removed duplicate trie in RAM, other norm fixes
also includes code to validate incoming utf8 moved normalization from claimTrie; all in cache now also fixed a few post-merge issues added handling for support normalization fixed failure to handle unnormalized items reinserted on rollback fixing ICU deps for Travis build get more info on Travis build failure Travis experiment 2: ICU fPIC add independent tests to check string normalization only move comment to proper location, and note what excpetion is thrown add RPC call checknormalization so user can see what normalization does made expiration at norm time smarter also rearranged unit test code to avoid some spurious errors made ICU compile statically also fixed early exit in reproducible_build script changed to keep original name removed ability to return just-added supports it was impossible to get the normalized names correct there apparently the -s is no longer appreciated moved normalization code to separate file also fixed bug on effective amount fixed performance problem on trie upgrade fixed issue with valid height on rollback fixed issue with post-normalization name q data fixed failure to remove normalized claims on rollback post-merge fixes post-merge fixes
This commit is contained in:
parent
223b6047cd
commit
fd6e26608d
20 changed files with 1407 additions and 1226 deletions
|
@ -31,8 +31,8 @@ before_install:
|
|||
install: true
|
||||
script:
|
||||
- mkdir -p "dist/${TRAVIS_BRANCH}"
|
||||
- if [[ "${TARGET}" == "osx" ]]; then ./reproducible_build.sh -t -o -c; fi
|
||||
- if [[ "${TARGET}" == "linux" ]]; then ./reproducible_build.sh -t -o -c -f; fi
|
||||
- if [[ "${TARGET}" == "osx" ]]; then ./reproducible_build.sh -t -o -r; fi
|
||||
- if [[ "${TARGET}" == "linux" ]]; then ./reproducible_build.sh -t -o; fi
|
||||
- if [[ "${TARGET}" == "windows" ]]; then ./packaging/build_windows.sh; fi
|
||||
- if [[ "${TARGET}" == "osx" ]]; then zip -j "dist/${TRAVIS_BRANCH}/lbrycrd-${TARGET}.zip" src/lbrycrdd src/lbrycrd-cli src/lbrycrd-tx; fi
|
||||
- if [[ "${TARGET}" == "linux" ]]; then zip -j "dist/${TRAVIS_BRANCH}/lbrycrd-${TARGET}.zip" src/lbrycrdd src/lbrycrd-cli src/lbrycrd-tx; fi
|
||||
|
|
26
configure.ac
26
configure.ac
|
@ -749,22 +749,19 @@ if test x$use_pkgconfig = xyes; then
|
|||
AC_MSG_ERROR(pkg-config not found.)
|
||||
fi
|
||||
|
||||
if test "${ICU_PREFIX}" != "auto"; then
|
||||
PKG_CONFIG_PATH="${ICU_PREFIX}/lib/pkgconfig:$PKG_CONFIG_PATH"
|
||||
export PKG_CONFIG_PATH
|
||||
fi
|
||||
|
||||
: #NOP
|
||||
m4_ifdef(
|
||||
[PKG_CHECK_MODULES],
|
||||
[
|
||||
ICU_CPPFLAGS="-I$ICU_PREFIX/include"
|
||||
CPPFLAGS="$ICU_CPPFLAGS $CPPFLAGS"
|
||||
ICU_LIBS="-L$ICU_PREFIX/lib -licui18n -licuuc -licudata -dl"
|
||||
AC_MSG_WARN([Using ICU_CPPFLAGS $ICU_CPPFLAGS])
|
||||
AC_MSG_WARN([Using CPPFLAGS $CPPFLAGS])
|
||||
|
||||
AC_CHECK_HEADER([unicode/errorcode.h],,AC_MSG_ERROR(libicu headers missing))
|
||||
AC_CHECK_LIB([icudata], [main], ICU_LIBS="-L$ICU_PREFIX/lib -licui18n -licuuc -licudata -dl",
|
||||
AC_CHECK_LIB([icu18n], [main],ICU_LIBS=$ICU_LIBS, ICU_LIBS="-L$ICU_PREFIX/lib -lsicudt -lsicuin -lsicuio -lsicule -lsiculx -lsicutest -lsicutu -lsicuuc"))
|
||||
|
||||
PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)])
|
||||
PKG_CHECK_MODULES([CRYPTO], [libcrypto],,[AC_MSG_ERROR(libcrypto not found.)])
|
||||
PKG_CHECK_MODULES([ICU], [icu-i18n],, [AC_MSG_ERROR(icu-i18n not found.)])
|
||||
AC_CHECK_HEADER([unicode/errorcode.h],, AC_MSG_ERROR(libicu headers missing))
|
||||
PKG_CHECK_MODULES([SSL], [libssl],, [AC_MSG_ERROR(openssl not found.)])
|
||||
PKG_CHECK_MODULES([CRYPTO], [libcrypto],, [AC_MSG_ERROR(libcrypto not found.)])
|
||||
|
||||
BITCOIN_QT_CHECK([PKG_CHECK_MODULES([PROTOBUF], [protobuf], [have_protobuf=yes], [BITCOIN_QT_FAIL(libprotobuf not found)])])
|
||||
if test x$use_qr != xno; then
|
||||
|
@ -876,8 +873,8 @@ AC_SUBST(UNIVALUE_LIBS)
|
|||
|
||||
CXXFLAGS_TEMP="$CXXFLAGS"
|
||||
LIBS_TEMP="$LIBS"
|
||||
CXXFLAGS="$CXXFLAGS $CPPFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS $ICU_PREFIX/include"
|
||||
LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS"
|
||||
CXXFLAGS="$CXXFLAGS $CPPFLAGS $SSL_CFLAGS $CRYPTO_CFLAGS"
|
||||
LIBS="$LIBS $SSL_LIBS $CRYPTO_LIBS $ICU_LIBS"
|
||||
#AC_CHECK_HEADER([openssl/ec.h],, AC_MSG_ERROR(OpenSSL ec header missing),)
|
||||
CXXFLAGS="$CXXFLAGS_TEMP"
|
||||
LIBS="$LIBS_TEMP"
|
||||
|
@ -1069,7 +1066,6 @@ AC_SUBST(LIBTOOL_APP_LDFLAGS)
|
|||
AC_SUBST(USE_UPNP)
|
||||
AC_SUBST(USE_QRCODE)
|
||||
AC_SUBST(BOOST_LIBS)
|
||||
AC_SUBST(ICU_PREFIX)
|
||||
AC_SUBST(ICU_CPPFLAGS)
|
||||
AC_SUBST(ICU_LIBS)
|
||||
AC_SUBST(TESTDEFS)
|
||||
|
|
|
@ -6,7 +6,7 @@ sudo apt-get update
|
|||
sudo apt-get install -y --no-install-recommends \
|
||||
g++-mingw-w64-i686 mingw-w64-i686-dev g++-mingw-w64-x86-64 \
|
||||
mingw-w64-x86-64-dev build-essential libtool autotools-dev automake pkg-config \
|
||||
libssl-dev libevent-dev bsdmainutils curl ca-certificates libicu-dev
|
||||
libssl-dev libevent-dev bsdmainutils curl ca-certificates
|
||||
|
||||
#################################################################
|
||||
# Build ICU for Linux first so that we can cross compile it below
|
||||
|
@ -15,8 +15,8 @@ staging_dir=/tmp/icu_staging
|
|||
icu_linux_dir=$staging_dir/build_icu_linux
|
||||
mkdir -p $staging_dir
|
||||
pushd $staging_dir
|
||||
wget http://download.icu-project.org/files/icu4c/55.1/icu4c-55_1-src.tgz
|
||||
tar -xvzf icu4c-55_1-src.tgz
|
||||
wget -c http://download.icu-project.org/files/icu4c/57.1/icu4c-57_1-src.tgz
|
||||
tar -xvzf icu4c-57_1-src.tgz
|
||||
pushd icu/source
|
||||
./runConfigureICU Linux --prefix=$icu_linux_dir --enable-extras=no --enable-strict=no -enable-static --enable-shared=no --enable-tests=no --enable-samples=no --enable-dyload=no
|
||||
make
|
||||
|
|
|
@ -15,7 +15,6 @@ function HELP {
|
|||
echo
|
||||
echo "Optional arguments:"
|
||||
echo
|
||||
echo "-c: don't clone a fresh copy of the repo"
|
||||
echo "-f: check formatting of committed code relative to master"
|
||||
echo "-r: remove intermediate files."
|
||||
echo "-l: build only lbrycrd"
|
||||
|
@ -26,8 +25,7 @@ function HELP {
|
|||
exit 1
|
||||
}
|
||||
|
||||
CLONE=false
|
||||
CLEAN=true
|
||||
CLEAN=false
|
||||
CHECK_CODE_FORMAT=false
|
||||
BUILD_DEPENDENCIES=true
|
||||
BUILD_LBRYCRD=true
|
||||
|
@ -39,15 +37,12 @@ OUTPUT_LOG=true
|
|||
|
||||
while getopts :crfldoth:w:d: FLAG; do
|
||||
case $FLAG in
|
||||
c)
|
||||
CLONE=false
|
||||
;;
|
||||
r)
|
||||
CLEAN=true
|
||||
;;
|
||||
f)
|
||||
CHECK_CODE_FORMAT=true
|
||||
;;
|
||||
f)
|
||||
CHECK_CODE_FORMAT=true
|
||||
;;
|
||||
l)
|
||||
BUILD_DEPENDENCIES=false
|
||||
;;
|
||||
|
@ -81,13 +76,11 @@ if (( EUID != 0 )); then
|
|||
SUDO='sudo'
|
||||
fi
|
||||
|
||||
if [ "${CLONE}" = false ]; then
|
||||
if [ "$(basename "$PWD")" != "lbrycrd" ]; then
|
||||
echo "Not currently in the lbrycrd directory. Cowardly refusing to go forward"
|
||||
exit 1
|
||||
fi
|
||||
SOURCE_DIR=$PWD
|
||||
if [ "$(basename "$PWD")" != "lbrycrd" ]; then
|
||||
echo "Not currently in the lbrycrd directory. Cowardly refusing to go forward"
|
||||
exit 1
|
||||
fi
|
||||
SOURCE_DIR=$PWD
|
||||
|
||||
if [ -z "${TRAVIS_OS_NAME+x}" ]; then
|
||||
if [ "$(uname -s)" = "Darwin" ]; then
|
||||
|
@ -133,44 +126,40 @@ function exit_at_60() {
|
|||
# - echo message
|
||||
function wait_and_echo() {
|
||||
PID=$1
|
||||
(set -o | grep xtrace | grep -q on)
|
||||
TRACE_STATUS=$?
|
||||
# disable xtrace or else this will get verbose, which is what
|
||||
# I'm trying to avoid by going through all of this nonsense anyway
|
||||
set +o xtrace
|
||||
TIME=0
|
||||
SLEEP=5
|
||||
SLEEP=3
|
||||
# loop until the process is no longer running
|
||||
# check every $SLEEP seconds, echoing a message every minute
|
||||
while (ps -p "${PID}" > /dev/null); do
|
||||
exit_at_60 "$2"
|
||||
sleep "${SLEEP}"
|
||||
done
|
||||
# restore the xtrace setting
|
||||
if [ "${TRACE_STATUS}" -eq 0 ]; then
|
||||
set -o xtrace
|
||||
fi
|
||||
wait "$PID"
|
||||
return $?
|
||||
}
|
||||
|
||||
# run a command ($1) in the background
|
||||
# logging its stdout and stderr to $2
|
||||
# and wait until it completed
|
||||
function background() {
|
||||
$1 >> "$2" 2>&1 &
|
||||
eval $1 >> "$2" 2>&1 &
|
||||
BACKGROUND_PID=$!
|
||||
wait_and_echo $BACKGROUND_PID "$3"
|
||||
(
|
||||
set +xe # do not echo each sleep call in trace mode
|
||||
wait_and_echo $BACKGROUND_PID "$3"
|
||||
)
|
||||
wait $BACKGROUND_PID
|
||||
}
|
||||
|
||||
function cleanup() {
|
||||
rv=$?
|
||||
if [ $rv -eq 0 ]; then
|
||||
return $rv
|
||||
fi
|
||||
# cat the log file if it exists
|
||||
if [ -f "$2" ] && [ "${OUTPUT_LOG}" = true ]; then
|
||||
echo
|
||||
echo "Output of log file $2"
|
||||
echo
|
||||
tail -n 1000 "$2"
|
||||
tail -n 200 "$2"
|
||||
echo
|
||||
fi
|
||||
# delete the build directory
|
||||
|
@ -209,7 +198,7 @@ function install_brew_packages() {
|
|||
brew_if_not_installed automake
|
||||
# something weird happened where glibtoolize was failing to find
|
||||
# sed, and reinstalling fixes it.
|
||||
brew reinstall -s libtool
|
||||
brew reinstall libtool
|
||||
brew_if_not_installed pkg-config
|
||||
brew_if_not_installed protobuf
|
||||
brew_if_not_installed gmp
|
||||
|
@ -220,6 +209,10 @@ function install_brew_packages() {
|
|||
}
|
||||
|
||||
function install_apt_packages() {
|
||||
if [ -d "${OUTPUT_DIR}" ]; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [ -z "${TRAVIS+x}" ]; then
|
||||
# if not on travis, its nice to see progress
|
||||
QUIET=""
|
||||
|
@ -265,7 +258,7 @@ function build_dependencies() {
|
|||
build_dependency "${BDB_PREFIX}" "${LOG_DIR}/bdb_build.log" build_bdb
|
||||
|
||||
set +u
|
||||
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${OPENSSL_PREFIX}/lib/pkgconfig/"
|
||||
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${OPENSSL_PREFIX}/lib/pkgconfig"
|
||||
set -u
|
||||
|
||||
build_dependency "${BOOST_PREFIX}" "${LOG_DIR}/boost_build.log" build_boost
|
||||
|
@ -275,6 +268,7 @@ function build_dependencies() {
|
|||
function build_bdb() {
|
||||
BDB_LOG="$1"
|
||||
if [ "${OS_NAME}" = "osx" ]; then
|
||||
# TODO: make this handle already patched files
|
||||
patch db-4.8.30.NC/dbinc/atomic.h < atomic.patch
|
||||
fi
|
||||
cd db-4.8.30.NC/build_unix
|
||||
|
@ -309,29 +303,31 @@ function build_boost() {
|
|||
echo "int main() { return 0; }" > libs/regex/build/has_icu_test.cpp
|
||||
echo "int main() { return 0; }" > libs/locale/build/has_icu_test.cpp
|
||||
|
||||
export BOOST_ICU_LIBS="$(pkg-config icu-i18n --libs) -dl"
|
||||
export BOOST_LDFLAGS="${BOOST_PREFIX}/lib ${ICU_PREFIX}/lib ${BOOST_ICU_LIBS}"
|
||||
export BOOST_ICU_LIBS="-L${ICU_PREFIX}/lib -licui18n -licuuc -licudata -dl"
|
||||
export BOOST_LDFLAGS="-L${BOOST_PREFIX}/lib ${BOOST_ICU_LIBS}"
|
||||
|
||||
echo "BOOST_ICU_LIBS: $BOOST_ICU_LIBS"
|
||||
echo "BOOST_LDFLAGS: $BOOST_ICU_LIBS"
|
||||
echo "BOOST_LDFLAGS: $BOOST_LDFLAGS"
|
||||
|
||||
echo "Building Boost. tail -f ${BOOST_LOG} to see the details and monitor progress"
|
||||
./bootstrap.sh --prefix="${BOOST_PREFIX}" "--with-icu=${ICU_PREFIX}" > "${BOOST_LOG}" 2>&1
|
||||
b2cmd="./b2 link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH=${ICU_PREFIX} -sICU_LINK=${BOOST_ICU_LIBS}"
|
||||
./bootstrap.sh --prefix="${BOOST_PREFIX}" --with-icu="${ICU_PREFIX}" > "${BOOST_LOG}" 2>&1
|
||||
b2cmd="./b2 --reconfigure ${PARALLEL} link=static cxxflags=-fPIC install boost.locale.iconv=off boost.locale.posix=off -sICU_PATH=\"${ICU_PREFIX}\" -sICU_LINK=\"${BOOST_ICU_LIBS}\""
|
||||
background "${b2cmd}" "${BOOST_LOG}" "Waiting for boost to finish building"
|
||||
if grep -q "icu[[:space:]]*:[[:space:]]*no$" "${BOOST_LOG}"; then
|
||||
echo "Failed to find ICU dependencies. Exiting..."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function build_icu() {
|
||||
ICU_LOG="$1"
|
||||
mkdir -p "${ICU_PREFIX}/icu"
|
||||
wget http://download.icu-project.org/files/icu4c/55.1/icu4c-55_1-src.tgz
|
||||
tar -xf icu4c-55_1-src.tgz
|
||||
rm -f icu4c-55_1-src.tgz
|
||||
wget -c http://download.icu-project.org/files/icu4c/57.1/icu4c-57_1-src.tgz
|
||||
tar -xf icu4c-57_1-src.tgz
|
||||
pushd icu/source > /dev/null
|
||||
echo "Building icu. tail -f $ICU_LOG to see the details and monitor progress"
|
||||
./configure --prefix="${ICU_PREFIX}" --enable-draft --enable-tools \
|
||||
--enable-shared --disable-extras --disable-icuio \
|
||||
--disable-layout --disable-layoutex --disable-tests --disable-samples
|
||||
--disable-shared --enable-static --disable-extras --disable-icuio --disable-dyload \
|
||||
--disable-layout --disable-layoutex --disable-tests --disable-samples CFLAGS=-fPIC CPPFLAGS=-fPIC > "${ICU_LOG}"
|
||||
if [ ! -z ${TARGET+x} ]; then
|
||||
TMP_TARGET="${TARGET}"
|
||||
unset TARGET
|
||||
|
@ -355,7 +351,7 @@ function build_libevent() {
|
|||
echo "Building libevent. tail -f ${LIBEVENT_LOG} to see the details and monitor progress"
|
||||
./autogen.sh > "${LIBEVENT_LOG}" 2>&1
|
||||
./configure --prefix="${LIBEVENT_PREFIX}" --enable-static --disable-shared --with-pic \
|
||||
LDFLAGS="-L${OPENSSL_PREFIX}/lib/" \
|
||||
LDFLAGS="-L${OPENSSL_PREFIX}/lib" \
|
||||
CPPFLAGS="-I${OPENSSL_PREFIX}/include" >> "${LIBEVENT_LOG}" 2>&1
|
||||
background "make ${PARALLEL}" "${LIBEVENT_LOG}" "Waiting for libevent to finish building"
|
||||
make install >> "${LIBEVENT_LOG}"
|
||||
|
@ -378,39 +374,22 @@ function build_dependency() {
|
|||
}
|
||||
|
||||
function build_lbrycrd() {
|
||||
if [ "$CLONE" == true ]; then
|
||||
cd "${LBRYCRD_DEPENDENCIES}"
|
||||
git clone https://github.com/lbryio/lbrycrd
|
||||
cd lbrycrd
|
||||
else
|
||||
cd "${SOURCE_DIR}"
|
||||
fi
|
||||
cd "${SOURCE_DIR}"
|
||||
./autogen.sh > "${LBRYCRD_LOG}" 2>&1
|
||||
LDFLAGS="-L${OPENSSL_PREFIX}/lib/ -L${BDB_PREFIX}/lib/ -L${LIBEVENT_PREFIX}/lib/ -L${ICU_PREFIX}/lib/ -static-libstdc++"
|
||||
LDFLAGS="-L${OPENSSL_PREFIX}/lib -L${BDB_PREFIX}/lib -L${LIBEVENT_PREFIX}/lib -L${ICU_PREFIX}/lib -static-libstdc++ -licui18n -licuuc -licudata -dl"
|
||||
OPTIONS="--enable-cxx --enable-static --disable-shared --with-pic"
|
||||
if [ "${OS_NAME}" = "osx" ]; then
|
||||
OPTIONS="--enable-cxx --enable-static --disable-shared --with-pic"
|
||||
CPPFLAGS="-I${OPENSSL_PREFIX}/include -I${BDB_PREFIX}/include -I${LIBEVENT_PREFIX}/include/ -I${ICU_PREFIX}/include"
|
||||
CPPFLAGS="-I${OPENSSL_PREFIX}/include -I${BDB_PREFIX}/include -I${LIBEVENT_PREFIX}/include -I${ICU_PREFIX}/include"
|
||||
else
|
||||
OPTIONS=""
|
||||
CPPFLAGS="-I${OPENSSL_PREFIX}/include -I${BDB_PREFIX}/include -I${LIBEVENT_PREFIX}/include/ -I${ICU_PREFIX}/include -Wno-unused-local-typedefs"
|
||||
CPPFLAGS="-I${OPENSSL_PREFIX}/include -I${BDB_PREFIX}/include -I${LIBEVENT_PREFIX}/include -I${ICU_PREFIX}/include -Wno-unused-local-typedefs -Wno-deprecated -Wno-implicit-fallthrough"
|
||||
fi
|
||||
|
||||
CPPFLAGS="${CPPFLAGS}" LDFLAGS="${LDFLAGS}" \
|
||||
./configure --without-gui ${OPTIONS} \
|
||||
--with-boost="${BOOST_PREFIX}" \
|
||||
--with-icu="${ICU_PREFIX}" >> "${LBRYCRD_LOG}" 2>&1
|
||||
|
||||
|
||||
background "make ${PARALLEL}" "${LBRYCRD_LOG}" "Waiting for lbrycrd to finish building"
|
||||
if [ "${OS_NAME}" = "linux" ]; then
|
||||
LD_LIBRARY_PATH="${ICU_PREFIX}/lib" src/test/test_lbrycrd
|
||||
else
|
||||
DYLD_LIBRARY_PATH="${ICU_PREFIX}/lib" src/test/test_lbrycrd
|
||||
fi
|
||||
strip src/lbrycrdd
|
||||
strip src/lbrycrd-cli
|
||||
strip src/lbrycrd-tx
|
||||
strip src/test/test_lbrycrd
|
||||
}
|
||||
|
||||
function clang_format_diff(){
|
||||
|
@ -443,7 +422,7 @@ if [ "${CHECK_CODE_FORMAT}" = true ]; then
|
|||
fi
|
||||
|
||||
set +u
|
||||
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${OPENSSL_PREFIX}/lib/pkgconfig/:${LIBEVENT_PREFIX}/lib/pkgconfig/"
|
||||
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:${OPENSSL_PREFIX}/lib/pkgconfig:${LIBEVENT_PREFIX}/lib/pkgconfig:${ICU_PREFIX}/lib/pkgconfig"
|
||||
set -u
|
||||
|
||||
if [ "${BUILD_LBRYCRD}" = true ]; then
|
||||
|
@ -452,4 +431,12 @@ if [ "${BUILD_LBRYCRD}" = true ]; then
|
|||
trap 'cat_and_exit "${LBRYCRD_LOG}"' INT TERM EXIT
|
||||
build_lbrycrd
|
||||
trap - INT TERM EXIT
|
||||
|
||||
./src/test/test_lbrycrd
|
||||
set +u
|
||||
if [[ ! $CXXFLAGS =~ -g ]]; then
|
||||
strip src/lbrycrdd
|
||||
strip src/lbrycrd-cli
|
||||
strip src/lbrycrd-tx
|
||||
fi
|
||||
fi
|
||||
|
|
|
@ -191,6 +191,7 @@ libbitcoin_server_a_SOURCES = \
|
|||
merkleblock.cpp \
|
||||
miner.cpp \
|
||||
claimtrie.cpp \
|
||||
claimtrieForks.cpp \
|
||||
net.cpp \
|
||||
noui.cpp \
|
||||
policy/fees.cpp \
|
||||
|
@ -354,7 +355,7 @@ nodist_libbitcoin_util_a_SOURCES = $(srcdir)/obj/build.h
|
|||
lbrycrdd_SOURCES = bitcoind.cpp
|
||||
lbrycrdd_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES)
|
||||
lbrycrdd_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
lbrycrdd_LDFLAGS = -L$(ICU_PREFIX)/lib $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
lbrycrdd_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
||||
if TARGET_WINDOWS
|
||||
lbrycrdd_SOURCES += bitcoin-cli-res.rc
|
||||
|
|
|
@ -9,7 +9,7 @@ bench_bench_bitcoin_SOURCES = \
|
|||
bench/bench.h \
|
||||
bench/Examples.cpp
|
||||
|
||||
bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) -I$(builddir)/bench/
|
||||
bench_bench_bitcoin_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(EVENT_CLFAGS) $(EVENT_PTHREADS_CFLAGS) $(ICU_CPPFLAGS) $(BOOST_CPPFLAGS) -I$(builddir)/bench/
|
||||
bench_bench_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
bench_bench_bitcoin_LDADD = \
|
||||
$(LIBBITCOIN_SERVER) \
|
||||
|
@ -30,8 +30,8 @@ if ENABLE_WALLET
|
|||
bench_bench_bitcoin_LDADD += $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
|
||||
bench_bench_bitcoin_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
bench_bench_bitcoin_LDFLAGS = -L$(ICU_PREFIX)/lib $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
bench_bench_bitcoin_LDADD += $(ICU_LIBS) $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
bench_bench_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
||||
CLEAN_BITCOIN_BENCH = bench/*.gcda bench/*.gcno
|
||||
|
||||
|
|
|
@ -382,7 +382,7 @@ endif
|
|||
qt_lbrycrd_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||
$(BOOST_LIBS) $(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)
|
||||
qt_lbrycrd_qt_LDFLAGS = -L$(ICU_PREFIX)/lib $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
qt_lbrycrd_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
qt_lbrycrd_qt_LIBTOOLFLAGS = --tag CXX
|
||||
|
||||
#locale/foo.ts -> locale/foo.qm
|
||||
|
|
|
@ -37,7 +37,7 @@ qt_test_test_lbrycrd_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBIT
|
|||
$(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
|
||||
$(QR_LIBS) $(PROTOBUF_LIBS) $(ICU_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
|
||||
$(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
|
||||
qt_test_test_lbrycrd_qt_LDFLAGS = -L$(ICU_PREFIX)/lib $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
qt_test_test_lbrycrd_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
qt_test_test_lbrycrd_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)
|
||||
|
||||
CLEAN_BITCOIN_QT_TEST = $(TEST_QT_MOC_CPP) qt/test/*.gcda qt/test/*.gcno
|
||||
|
|
|
@ -100,16 +100,16 @@ BITCOIN_TESTS += \
|
|||
endif
|
||||
|
||||
test_test_lbrycrd_SOURCES = $(BITCOIN_TESTS) $(JSON_TEST_FILES) $(RAW_TEST_FILES)
|
||||
test_test_lbrycrd_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) -I$(builddir)/test/ $(TESTDEFS)
|
||||
test_test_lbrycrd_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(ICU_CPPFLAGS) $(BOOST_CPPFLAGS) -I$(builddir)/test/ $(TESTDEFS)
|
||||
test_test_lbrycrd_LDADD = $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBMEMENV) \
|
||||
$(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1)
|
||||
$(ICU_LIBS) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1)
|
||||
test_test_lbrycrd_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)
|
||||
if ENABLE_WALLET
|
||||
test_test_lbrycrd_LDADD += $(LIBBITCOIN_WALLET)
|
||||
endif
|
||||
|
||||
test_test_lbrycrd_LDADD += $(LIBBITCOIN_CONSENSUS) $(ICU_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
|
||||
test_test_lbrycrd_LDFLAGS = -L$(ICU_PREFIX)/lib $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static
|
||||
test_test_lbrycrd_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
|
||||
test_test_lbrycrd_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
|
||||
|
||||
if ENABLE_ZMQ
|
||||
test_test_lbrycrd_LDADD += $(ZMQ_LIBS)
|
||||
|
|
|
@ -305,7 +305,7 @@ public:
|
|||
consensus.nExtendedClaimExpirationForkHeight = 800;
|
||||
consensus.fPowAllowMinDifficultyBlocks = false;
|
||||
consensus.fPowNoRetargeting = false;
|
||||
consensus.nNormalizedNameForkHeight = 2000; // FIXME: pick a real fork height
|
||||
consensus.nNormalizedNameForkHeight = 2000;
|
||||
consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
|
||||
consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
|
||||
consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
|
||||
|
|
1093
src/claimtrie.cpp
1093
src/claimtrie.cpp
File diff suppressed because it is too large
Load diff
321
src/claimtrie.h
321
src/claimtrie.h
|
@ -13,11 +13,6 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/locale/conversion.hpp>
|
||||
#include <boost/locale/localization_backend.hpp>
|
||||
#include <boost/locale.hpp>
|
||||
|
||||
// leveldb keys
|
||||
#define HASH_BLOCK 'h'
|
||||
#define CURRENT_HEIGHT 't'
|
||||
|
@ -33,34 +28,6 @@
|
|||
|
||||
uint256 getValueHash(COutPoint outPoint, int nHeightOfLastTakeover);
|
||||
|
||||
// lower-case and normalize any input string name
|
||||
// see: https://unicode.org/reports/tr15/#Norm_Forms
|
||||
inline std::string normalizeClaimName(const std::string& name)
|
||||
{
|
||||
static std::locale utf8;
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
static boost::locale::localization_backend_manager manager =
|
||||
boost::locale::localization_backend_manager::global();
|
||||
manager.select("icu");
|
||||
|
||||
static boost::locale::generator curLocale(manager);
|
||||
utf8 = curLocale("en_US.UTF8");
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
std::string normalized = boost::locale::normalize(name, boost::locale::norm_nfd, utf8);
|
||||
// Non-locale aware lowercase
|
||||
boost::algorithm::to_lower(normalized);
|
||||
|
||||
// Locale aware lowercase
|
||||
/* normalized = boost::locale::to_lower(normalized, utf8); */
|
||||
|
||||
LogPrintf("%s: Normalized \"%s\" (%lu, %lu) to \"%s\" (%lu, %lu)\n", __func__, name, name.size(), sizeof(name), normalized, normalized.size(), sizeof(normalized));
|
||||
// code points can be lost if we're not careful to make sure the string isn't shrinking here
|
||||
return (normalized.size() >= name.size()) ? normalized : name;
|
||||
}
|
||||
|
||||
class CClaimValue
|
||||
{
|
||||
public:
|
||||
|
@ -191,63 +158,6 @@ public:
|
|||
READWRITE(nHeightOfLastTakeover);
|
||||
}
|
||||
|
||||
CClaimTrieNode& cloneState(const CClaimTrieNode& other)
|
||||
{
|
||||
hash = other.hash;
|
||||
nHeightOfLastTakeover = other.nHeightOfLastTakeover;
|
||||
if (!claims.empty()) {
|
||||
claims.reserve(other.claims.size());
|
||||
std::copy(other.claims.begin(), other.claims.end(), claims.begin());
|
||||
}
|
||||
|
||||
std::string sPos;
|
||||
for (nodeMapType::const_iterator it = other.children.begin(); it != other.children.end(); ++it) {
|
||||
std::stringstream ss;
|
||||
ss << it->first;
|
||||
sPos = ss.str();
|
||||
|
||||
CClaimTrieNode* newNode = new CClaimTrieNode();
|
||||
newNode->cloneState(*it->second);
|
||||
if (!it->second->claims.empty()) {
|
||||
newNode->claims.reserve(it->second->claims.size());
|
||||
for (std::vector<CClaimValue>::const_iterator cit = it->second->claims.begin(); cit != it->second->claims.end(); ++cit)
|
||||
newNode->claims.push_back(*cit);
|
||||
}
|
||||
children[sPos[sPos.size() - 1]] = newNode;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
// NOTE: While normalization is hardcoded into this method, it's
|
||||
// *only* used while enabling the normalization fork in order to
|
||||
// flatten the namespace.
|
||||
CClaimTrieNode& normalizeClone(const CClaimTrieNode& other)
|
||||
{
|
||||
hash = uint256S("0000000000000000000000000000000000000000000000000000000000000001");
|
||||
nHeightOfLastTakeover = other.nHeightOfLastTakeover;
|
||||
if (!claims.empty()) {
|
||||
claims.reserve(other.claims.size());
|
||||
std::copy(other.claims.begin(), other.claims.end(), claims.begin());
|
||||
}
|
||||
|
||||
std::string sPos;
|
||||
for (nodeMapType::const_iterator it = other.children.begin(); it != other.children.end(); ++it) {
|
||||
std::stringstream ss;
|
||||
ss << it->first;
|
||||
sPos = normalizeClaimName(ss.str());
|
||||
|
||||
CClaimTrieNode* newNode = new CClaimTrieNode();
|
||||
newNode->normalizeClone(*it->second);
|
||||
if (!it->second->claims.empty()) {
|
||||
newNode->claims.reserve(it->second->claims.size());
|
||||
for (std::vector<CClaimValue>::const_iterator cit = it->second->claims.begin(); cit != it->second->claims.end(); ++cit)
|
||||
newNode->claims.push_back(*cit);
|
||||
}
|
||||
children[sPos[sPos.size() - 1]] = newNode;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const CClaimTrieNode& other) const
|
||||
{
|
||||
return hash == other.hash && claims == other.claims;
|
||||
|
@ -375,33 +285,34 @@ typedef std::vector<CClaimIndexElement> claimIndexElementListType;
|
|||
|
||||
struct claimsForNameType
|
||||
{
|
||||
std::vector<CClaimValue> claims;
|
||||
std::vector<CSupportValue> supports;
|
||||
int nLastTakeoverHeight;
|
||||
const std::vector<CClaimValue> claims;
|
||||
const std::vector<CSupportValue> supports;
|
||||
const int nLastTakeoverHeight;
|
||||
const std::string name;
|
||||
|
||||
claimsForNameType(std::vector<CClaimValue> claims, std::vector<CSupportValue> supports, int nLastTakeoverHeight)
|
||||
: claims(claims), supports(supports), nLastTakeoverHeight(nLastTakeoverHeight) {}
|
||||
claimsForNameType(std::vector<CClaimValue> claims, std::vector<CSupportValue> supports,
|
||||
int nLastTakeoverHeight, const std::string& name)
|
||||
: claims(claims), supports(supports), nLastTakeoverHeight(nLastTakeoverHeight), name(name) {}
|
||||
};
|
||||
|
||||
class CClaimTrieCache;
|
||||
class CClaimTrieCacheBase;
|
||||
class CClaimTrieCacheExpirationFork;
|
||||
|
||||
class CClaimTrie
|
||||
{
|
||||
public:
|
||||
CClaimTrie(bool fMemory = false, bool fWipe = false, bool fNormalize = false, int nProportionalDelayFactor = 32)
|
||||
: db(GetDataDir() / "claimtrie", 100, fMemory, fWipe, false), nCurrentHeight(0), nExpirationTime(Params().GetConsensus().nOriginalClaimExpirationTime), nProportionalDelayFactor(nProportionalDelayFactor), root(uint256S("0000000000000000000000000000000000000000000000000000000000000001")), fNormalize(fNormalize)
|
||||
CClaimTrie(bool fMemory = false, bool fWipe = false, int nProportionalDelayFactor = 32)
|
||||
: db(GetDataDir() / "claimtrie", 100, fMemory, fWipe, false), nCurrentHeight(0),
|
||||
nExpirationTime(Params().GetConsensus().nOriginalClaimExpirationTime),
|
||||
nProportionalDelayFactor(nProportionalDelayFactor),
|
||||
root(uint256S("0000000000000000000000000000000000000000000000000000000000000001"))
|
||||
{}
|
||||
|
||||
// Does not change the current trie, but returns a normalized equivalent trie
|
||||
CClaimTrie* enableNormalizationFork(bool enable, int nHeight, CClaimTrieCache& trieCache);
|
||||
|
||||
uint256 getMerkleHash();
|
||||
|
||||
bool empty() const;
|
||||
void clear();
|
||||
|
||||
bool shouldNormalize();
|
||||
|
||||
bool checkConsistency() const;
|
||||
|
||||
bool WriteToDisk();
|
||||
|
@ -410,16 +321,12 @@ public:
|
|||
bool getInfoForName(const std::string& name, CClaimValue& claim) const;
|
||||
bool getLastTakeoverForName(const std::string& name, int& lastTakeoverHeight) const;
|
||||
|
||||
claimsForNameType getClaimsForName(const std::string& name) const;
|
||||
|
||||
CAmount getEffectiveAmountForClaim(const std::string& name, const uint160& claimId, std::vector<CSupportValue>* supports = NULL) const;
|
||||
CAmount getEffectiveAmountForClaim(const claimsForNameType& claims, const uint160& claimId, std::vector<CSupportValue>* supports = NULL) const;
|
||||
std::vector<CClaimValue> getClaimsForName(const std::string& name) const;
|
||||
|
||||
bool queueEmpty() const;
|
||||
bool supportEmpty() const;
|
||||
bool supportQueueEmpty() const;
|
||||
bool expirationQueueEmpty() const;
|
||||
bool supportExpirationQueueEmpty() const;
|
||||
|
||||
void setExpirationTime(int t);
|
||||
|
||||
|
@ -427,14 +334,6 @@ public:
|
|||
void removeFromClaimIndex(const CClaimValue& claim);
|
||||
|
||||
bool getClaimById(const uint160 claimId, std::string& name, CClaimValue& claim) const;
|
||||
bool getQueueRow(int nHeight, claimQueueRowType& row) const;
|
||||
bool getQueueNameRow(const std::string& name, queueNameRowType& row) const;
|
||||
bool getExpirationQueueRow(int nHeight, expirationQueueRowType& row) const;
|
||||
bool getSupportNode(std::string name, supportMapEntryType& node) const;
|
||||
bool getSupportQueueRow(int nHeight, supportQueueRowType& row) const;
|
||||
bool getSupportQueueNameRow(const std::string& name, queueNameRowType& row) const;
|
||||
bool getSupportExpirationQueueRow(int nHeight, expirationQueueRowType& row) const;
|
||||
|
||||
|
||||
bool haveClaim(const std::string& name, const COutPoint& outPoint) const;
|
||||
bool haveClaimInQueue(const std::string& name, const COutPoint& outPoint,
|
||||
|
@ -448,7 +347,8 @@ public:
|
|||
unsigned int getTotalClaimsInTrie() const;
|
||||
CAmount getTotalValueOfClaimsInTrie(bool fControllingOnly) const;
|
||||
|
||||
friend class CClaimTrieCache;
|
||||
friend class CClaimTrieCacheBase;
|
||||
friend class CClaimTrieCacheExpirationFork;
|
||||
|
||||
CDBWrapper db;
|
||||
int nCurrentHeight;
|
||||
|
@ -470,7 +370,6 @@ private:
|
|||
expirationQueueType& supportExpirationQueueCache);
|
||||
bool updateName(const std::string& name, CClaimTrieNode* updatedNode);
|
||||
bool updateHash(const std::string& name, uint256& hash);
|
||||
bool updateHashNormalized(const std::string& name, uint256& hash);
|
||||
bool updateTakeoverHeight(const std::string& name, int nTakeoverHeight);
|
||||
bool recursiveNullify(CClaimTrieNode* node, const std::string& name);
|
||||
|
||||
|
@ -483,6 +382,14 @@ private:
|
|||
CAmount getTotalValueOfClaimsRecursive(const CClaimTrieNode* current,
|
||||
bool fControllingOnly) const;
|
||||
|
||||
bool getQueueRow(int nHeight, claimQueueRowType& row) const;
|
||||
bool getQueueNameRow(const std::string& name, queueNameRowType& row) const;
|
||||
bool getExpirationQueueRow(int nHeight, expirationQueueRowType& row) const;
|
||||
bool getSupportNode(std::string name, supportMapEntryType& node) const;
|
||||
bool getSupportQueueRow(int nHeight, supportQueueRowType& row) const;
|
||||
bool getSupportQueueNameRow(const std::string& name, queueNameRowType& row) const;
|
||||
bool getSupportExpirationQueueRow(int nHeight, expirationQueueRowType& row) const;
|
||||
|
||||
void markNodeDirty(const std::string& name, CClaimTrieNode* node);
|
||||
void updateQueueRow(int nHeight, claimQueueRowType& row);
|
||||
void updateQueueNameRow(const std::string& name,
|
||||
|
@ -496,8 +403,6 @@ private:
|
|||
|
||||
void BatchWriteNode(CDBBatch& batch, const std::string& name,
|
||||
const CClaimTrieNode* pNode) const;
|
||||
void BatchEraseNode(CDBBatch& batch, const std::string& nome) const;
|
||||
void BatchWriteClaimIndex(CDBBatch& batch) const;
|
||||
void BatchWriteQueueRows(CDBBatch& batch);
|
||||
void BatchWriteQueueNameRows(CDBBatch& batch);
|
||||
void BatchWriteExpirationQueueRows(CDBBatch& batch);
|
||||
|
@ -507,9 +412,6 @@ private:
|
|||
void BatchWriteSupportExpirationQueueRows(CDBBatch& batch);
|
||||
template<typename K> bool keyTypeEmpty(char key, K& dummy) const;
|
||||
|
||||
void cloneState(const CClaimTrie&);
|
||||
void copyAndNormalizeQueues(const CClaimTrie&);
|
||||
|
||||
CClaimTrieNode root;
|
||||
uint256 hashBlock;
|
||||
|
||||
|
@ -523,8 +425,6 @@ private:
|
|||
|
||||
nodeCacheType dirtyNodes;
|
||||
supportMapType dirtySupportNodes;
|
||||
|
||||
bool fNormalize;
|
||||
};
|
||||
|
||||
class CClaimTrieProofNode
|
||||
|
@ -572,10 +472,10 @@ struct CNodeCallback {
|
|||
virtual void visit(const std::string& name, const CClaimTrieNode* node) = 0;
|
||||
};
|
||||
|
||||
class CClaimTrieCache
|
||||
class CClaimTrieCacheBase
|
||||
{
|
||||
public:
|
||||
CClaimTrieCache(CClaimTrie* base, bool fRequireTakeoverHeights = true)
|
||||
CClaimTrieCacheBase(CClaimTrie* base, bool fRequireTakeoverHeights = true)
|
||||
: base(base),
|
||||
fRequireTakeoverHeights(fRequireTakeoverHeights)
|
||||
{
|
||||
|
@ -597,8 +497,8 @@ public:
|
|||
|
||||
bool addClaim(const std::string& name, const COutPoint& outPoint,
|
||||
uint160 claimId, CAmount nAmount, int nHeight) const;
|
||||
bool undoAddClaim(const std::string& name, const COutPoint& outPoint) const;
|
||||
bool spendClaim(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight) const;
|
||||
bool undoAddClaim(const std::string& name, const COutPoint& outPoint, int nHeight) const;
|
||||
bool spendClaim(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight) const;
|
||||
bool undoSpendClaim(const std::string& name, const COutPoint& outPoint,
|
||||
uint160 claimId, CAmount nAmount, int nHeight,
|
||||
int nValidAtHeight) const;
|
||||
|
@ -617,38 +517,27 @@ public:
|
|||
uint256 getBestBlock();
|
||||
void setBestBlock(const uint256& hashBlock);
|
||||
|
||||
bool incrementBlock(insertUndoType& insertUndo,
|
||||
virtual bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const;
|
||||
bool decrementBlock(insertUndoType& insertUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo);
|
||||
virtual bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const;
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo);
|
||||
|
||||
~CClaimTrieCache() { clear(); }
|
||||
~CClaimTrieCacheBase() { clear(); }
|
||||
|
||||
bool insertClaimIntoTrie(const std::string& name, CClaimValue claim,
|
||||
bool fCheckTakeover = false) const;
|
||||
bool removeClaimFromTrie(const std::string& name, const COutPoint& outPoint,
|
||||
CClaimValue& claim,
|
||||
bool fCheckTakeover = false) const;
|
||||
|
||||
bool getProofForName(const std::string& name, CClaimTrieProof& proof) const;
|
||||
bool getInfoForName(const std::string& name, CClaimValue& claim) const;
|
||||
virtual bool getProofForName(const std::string& name, CClaimTrieProof& proof) const;
|
||||
virtual bool getInfoForName(const std::string& name, CClaimValue& claim) const;
|
||||
|
||||
bool finalizeDecrement() const;
|
||||
|
||||
void removeAndAddSupportToExpirationQueue(expirationQueueRowType &row, int height, bool increment) const;
|
||||
void removeAndAddToExpirationQueue(expirationQueueRowType &row, int height, bool increment) const;
|
||||
|
||||
bool forkForExpirationChange(bool increment) const;
|
||||
|
||||
bool iterateTrie(CNodeCallback& callback) const;
|
||||
|
||||
claimsForNameType getClaimsForName(const std::string& name) const;
|
||||
virtual claimsForNameType getClaimsForName(const std::string& name) const;
|
||||
|
||||
CAmount getEffectiveAmountForClaim(const std::string& name, const uint160& claimId, std::vector<CSupportValue>* supports = NULL) const;
|
||||
CAmount getEffectiveAmountForClaim(const claimsForNameType& claims, const uint160& claimId, std::vector<CSupportValue>* supports = NULL) const;
|
||||
|
@ -660,11 +549,48 @@ protected:
|
|||
const std::string& sPos,
|
||||
bool forceCompute = false) const;
|
||||
bool recursivePruneName(CClaimTrieNode* tnCurrent, unsigned int nPos, const std::string& sName, bool* pfNullified = NULL) const;
|
||||
void checkNamesForTakeover(insertUndoType& insertUndo, insertUndoType& insertSupportUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const;
|
||||
|
||||
virtual bool insertClaimIntoTrie(const std::string& name, CClaimValue claim,
|
||||
bool fCheckTakeover = false) const;
|
||||
virtual bool removeClaimFromTrie(const std::string& name, const COutPoint& outPoint,
|
||||
CClaimValue& claim,
|
||||
bool fCheckTakeover = false) const;
|
||||
|
||||
virtual bool insertSupportIntoMap(const std::string& name,
|
||||
CSupportValue support,
|
||||
bool fCheckTakeover) const;
|
||||
virtual bool removeSupportFromMap(const std::string& name, const COutPoint& outPoint,
|
||||
CSupportValue& support,
|
||||
bool fCheckTakeover) const;
|
||||
|
||||
virtual void addClaimToQueues(const std::string& name, CClaimValue& claim) const;
|
||||
virtual bool addSupportToQueues(const std::string& name, CSupportValue& support) const;
|
||||
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
||||
|
||||
void addToExpirationQueue(int nExpirationHeight, nameOutPointType& entry) const;
|
||||
void removeFromExpirationQueue(const std::string& name, const COutPoint& outPoint,
|
||||
int nHeight) const;
|
||||
|
||||
void addSupportToExpirationQueue(int nExpirationHeight,
|
||||
nameOutPointType& entry) const;
|
||||
void removeSupportFromExpirationQueue(const std::string& name,
|
||||
const COutPoint& outPoint,
|
||||
int nHeight) const;
|
||||
|
||||
bool getSupportsForName(const std::string& name,
|
||||
supportMapEntryType& supports) const;
|
||||
|
||||
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
|
||||
|
||||
mutable nodeCacheType cache;
|
||||
|
||||
private:
|
||||
CClaimTrie* base;
|
||||
mutable int nCurrentHeight; // Height of the block that is being worked on, which is
|
||||
// one greater than the height of the chain's tip
|
||||
|
||||
private:
|
||||
|
||||
bool fRequireTakeoverHeights;
|
||||
|
||||
|
@ -680,26 +606,19 @@ private:
|
|||
mutable expirationQueueType supportExpirationQueueCache;
|
||||
mutable std::set<std::string> namesToCheckForTakeover;
|
||||
mutable std::map<std::string, int> cacheTakeoverHeights;
|
||||
mutable int nCurrentHeight; // Height of the block that is being worked on, which is
|
||||
// one greater than the height of the chain's tip
|
||||
mutable claimIndexElementListType claimsToAdd;
|
||||
mutable claimIndexClaimListType claimsToDelete;
|
||||
|
||||
uint256 hashBlock;
|
||||
|
||||
uint256 computeHash() const;
|
||||
|
||||
bool reorderTrieNode(const std::string& name, bool fCheckTakeover) const;
|
||||
|
||||
bool clear() const;
|
||||
|
||||
bool removeClaim(const std::string& name, const COutPoint& outPoint, int& nValidAtHeight, bool fCheckTakeover) const;
|
||||
bool addClaimToQueues(const std::string& name, CClaimValue& claim) const;
|
||||
// generally the opposite of addClaimToQueues, but they aren't perfectly symmetrical:
|
||||
bool removeClaim(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight, bool fCheckTakeover) const;
|
||||
bool removeClaimFromQueue(const std::string& name, const COutPoint& outPoint,
|
||||
CClaimValue& claim) const;
|
||||
void addToExpirationQueue(int nExpirationHeight, nameOutPointType& entry) const;
|
||||
void removeFromExpirationQueue(const std::string& name, const COutPoint& outPoint,
|
||||
int nHeight) const;
|
||||
|
||||
claimQueueType::iterator getQueueCacheRow(int nHeight,
|
||||
bool createIfNotExists) const;
|
||||
|
@ -711,13 +630,6 @@ private:
|
|||
bool removeSupport(const std::string& name, const COutPoint& outPoint,
|
||||
int nHeight, int& nValidAtHeight,
|
||||
bool fCheckTakeover) const;
|
||||
bool removeSupportFromMap(const std::string& name, const COutPoint& outPoint,
|
||||
CSupportValue& support,
|
||||
bool fCheckTakeover) const;
|
||||
|
||||
bool insertSupportIntoMap(const std::string& name,
|
||||
CSupportValue support,
|
||||
bool fCheckTakeover) const;
|
||||
|
||||
supportQueueType::iterator getSupportQueueCacheRow(int nHeight,
|
||||
bool createIfNotExists) const;
|
||||
|
@ -726,25 +638,14 @@ private:
|
|||
expirationQueueType::iterator getSupportExpirationQueueCacheRow(int nHeight,
|
||||
bool createIfNotExists) const;
|
||||
|
||||
bool addSupportToQueues(const std::string& name, CSupportValue& support) const;
|
||||
bool removeSupportFromQueue(const std::string& name, const COutPoint& outPoint,
|
||||
CSupportValue& support) const;
|
||||
|
||||
void addSupportToExpirationQueue(int nExpirationHeight,
|
||||
nameOutPointType& entry) const;
|
||||
void removeSupportFromExpirationQueue(const std::string& name,
|
||||
const COutPoint& outPoint,
|
||||
int nHeight) const;
|
||||
|
||||
bool getSupportsForName(const std::string& name,
|
||||
supportMapEntryType& node) const;
|
||||
|
||||
bool getLastTakeoverForName(const std::string& name, int& lastTakeoverHeight) const;
|
||||
|
||||
int getDelayForName(const std::string& name) const;
|
||||
|
||||
uint256 getLeafHashForProof(const std::string& currentPosition, unsigned char nodeChar,
|
||||
const CClaimTrieNode* currentNode) const;
|
||||
uint256 getLeafHashForProof(const std::string& currentPosition, const CClaimTrieNode* currentNode) const;
|
||||
|
||||
bool getOriginalInfoForName(const std::string& name, CClaimValue& claim) const;
|
||||
|
||||
|
@ -755,4 +656,70 @@ private:
|
|||
const CClaimTrieNode* getNodeForName(const std::string& name) const;
|
||||
};
|
||||
|
||||
|
||||
class CClaimTrieCacheExpirationFork: public CClaimTrieCacheBase {
|
||||
public:
|
||||
CClaimTrieCacheExpirationFork(CClaimTrie* base, bool fRequireTakeoverHeights = true)
|
||||
: CClaimTrieCacheBase(base, fRequireTakeoverHeights) {}
|
||||
|
||||
bool forkForExpirationChange(bool increment) const;
|
||||
|
||||
// TODO: move the expiration fork code from main.cpp to overrides of increment/decrement block
|
||||
|
||||
private:
|
||||
void removeAndAddSupportToExpirationQueue(expirationQueueRowType &row, int height, bool increment) const;
|
||||
void removeAndAddToExpirationQueue(expirationQueueRowType &row, int height, bool increment) const;
|
||||
};
|
||||
|
||||
class CClaimTrieCacheNormalizationFork: public CClaimTrieCacheExpirationFork {
|
||||
public:
|
||||
CClaimTrieCacheNormalizationFork(CClaimTrie* base, bool fRequireTakeoverHeights = true)
|
||||
: CClaimTrieCacheExpirationFork(base, fRequireTakeoverHeights),
|
||||
overrideInsertNormalization(false), overrideRemoveNormalization(false) {}
|
||||
|
||||
bool shouldNormalize() const;
|
||||
|
||||
// lower-case and normalize any input string name
|
||||
// see: https://unicode.org/reports/tr15/#Norm_Forms
|
||||
std::string normalizeClaimName(const std::string& name, bool force = false) const; // public only for validating name field on update op
|
||||
|
||||
virtual bool incrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo);
|
||||
virtual bool decrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo);
|
||||
|
||||
virtual bool getProofForName(const std::string& name, CClaimTrieProof& proof) const;
|
||||
virtual bool getInfoForName(const std::string& name, CClaimValue& claim) const;
|
||||
virtual claimsForNameType getClaimsForName(const std::string& name) const;
|
||||
|
||||
protected:
|
||||
virtual bool insertClaimIntoTrie(const std::string& name, CClaimValue claim, bool fCheckTakeover = false) const;
|
||||
virtual bool removeClaimFromTrie(const std::string& name, const COutPoint& outPoint,
|
||||
CClaimValue& claim, bool fCheckTakeover = false) const;
|
||||
|
||||
virtual bool insertSupportIntoMap(const std::string& name, CSupportValue support, bool fCheckTakeover) const;
|
||||
virtual bool removeSupportFromMap(const std::string& name, const COutPoint& outPoint,
|
||||
CSupportValue& support, bool fCheckTakeover) const;
|
||||
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
|
||||
|
||||
virtual void addClaimToQueues(const std::string& name, CClaimValue& claim) const;
|
||||
virtual bool addSupportToQueues(const std::string& name, CSupportValue& support) const;
|
||||
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
|
||||
|
||||
private:
|
||||
bool overrideInsertNormalization, overrideRemoveNormalization;
|
||||
bool normalizeAllNamesInTrieIfNecessary(insertUndoType& insertUndo, claimQueueRowType& removeUndo,
|
||||
insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const;
|
||||
};
|
||||
|
||||
typedef CClaimTrieCacheNormalizationFork CClaimTrieCache;
|
||||
|
||||
|
||||
#endif // BITCOIN_CLAIMTRIE_H
|
||||
|
|
300
src/claimtrieForks.cpp
Normal file
300
src/claimtrieForks.cpp
Normal file
|
@ -0,0 +1,300 @@
|
|||
#include "claimtrie.h"
|
||||
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/locale/conversion.hpp>
|
||||
#include <boost/locale/localization_backend.hpp>
|
||||
#include <boost/locale.hpp>
|
||||
#include <boost/scope_exit.hpp>
|
||||
|
||||
void CClaimTrieCacheExpirationFork::removeAndAddToExpirationQueue(expirationQueueRowType &row, int height, bool increment) const
|
||||
{
|
||||
for (expirationQueueRowType::iterator e = row.begin(); e != row.end(); ++e)
|
||||
{
|
||||
// remove and insert with new expiration time
|
||||
removeFromExpirationQueue(e->name, e->outPoint, height);
|
||||
int extend_expiration = Params().GetConsensus().nExtendedClaimExpirationTime - Params().GetConsensus().nOriginalClaimExpirationTime;
|
||||
int new_expiration_height = increment ? height + extend_expiration : height - extend_expiration;
|
||||
nameOutPointType entry(e->name, e->outPoint);
|
||||
addToExpirationQueue(new_expiration_height, entry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CClaimTrieCacheExpirationFork::removeAndAddSupportToExpirationQueue(expirationQueueRowType &row, int height, bool increment) const
|
||||
{
|
||||
for (expirationQueueRowType::iterator e = row.begin(); e != row.end(); ++e)
|
||||
{
|
||||
// remove and insert with new expiration time
|
||||
removeSupportFromExpirationQueue(e->name, e->outPoint, height);
|
||||
int extend_expiration = Params().GetConsensus().nExtendedClaimExpirationTime - Params().GetConsensus().nOriginalClaimExpirationTime;
|
||||
int new_expiration_height = increment ? height + extend_expiration : height - extend_expiration;
|
||||
nameOutPointType entry(e->name, e->outPoint);
|
||||
addSupportToExpirationQueue(new_expiration_height, entry);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheExpirationFork::forkForExpirationChange(bool increment) const
|
||||
{
|
||||
/*
|
||||
If increment is True, we have forked to extend the expiration time, thus items in the expiration queue
|
||||
will have their expiration extended by "new expiration time - original expiration time"
|
||||
|
||||
If increment is False, we are decremented a block to reverse the fork. Thus items in the expiration queue
|
||||
will have their expiration extension removed.
|
||||
*/
|
||||
|
||||
// look through dirty expiration queues
|
||||
std::set<int> dirtyHeights;
|
||||
for (expirationQueueType::const_iterator i = base->dirtyExpirationQueueRows.begin(); i != base->dirtyExpirationQueueRows.end(); ++i)
|
||||
{
|
||||
int height = i->first;
|
||||
dirtyHeights.insert(height);
|
||||
expirationQueueRowType row = i->second;
|
||||
removeAndAddToExpirationQueue(row, height, increment);
|
||||
}
|
||||
|
||||
std::set<int> dirtySupportHeights;
|
||||
for (expirationQueueType::const_iterator i = base->dirtySupportExpirationQueueRows.begin(); i != base->dirtySupportExpirationQueueRows.end(); ++i)
|
||||
{
|
||||
int height = i->first;
|
||||
dirtySupportHeights.insert(height);
|
||||
expirationQueueRowType row = i->second;
|
||||
removeAndAddSupportToExpirationQueue(row, height, increment);
|
||||
}
|
||||
|
||||
|
||||
//look through db for expiration queues, if we haven't already found it in dirty expiration queue
|
||||
boost::scoped_ptr<CDBIterator> pcursor(const_cast<CDBWrapper*>(&base->db)->NewIterator());
|
||||
pcursor->SeekToFirst();
|
||||
while (pcursor->Valid())
|
||||
{
|
||||
std::pair<char, int> key;
|
||||
if (pcursor->GetKey(key))
|
||||
{
|
||||
int height = key.second;
|
||||
// if we've looked through this in dirtyExprirationQueueRows, don't use it
|
||||
// because its stale
|
||||
if ((key.first == EXP_QUEUE_ROW) & (dirtyHeights.count(height) == 0))
|
||||
{
|
||||
expirationQueueRowType row;
|
||||
if (pcursor->GetValue(row))
|
||||
{
|
||||
removeAndAddToExpirationQueue(row, height, increment);
|
||||
}
|
||||
else
|
||||
{
|
||||
return error("%s(): error reading expiration queue rows from disk", __func__);
|
||||
}
|
||||
}
|
||||
else if ((key.first == SUPPORT_EXP_QUEUE_ROW) & (dirtySupportHeights.count(height) == 0))
|
||||
{
|
||||
expirationQueueRowType row;
|
||||
if (pcursor->GetValue(row))
|
||||
{
|
||||
removeAndAddSupportToExpirationQueue(row, height, increment);
|
||||
}
|
||||
else
|
||||
{
|
||||
return error("%s(): error reading support expiration queue rows from disk", __func__);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
pcursor->Next();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::shouldNormalize() const {
|
||||
return nCurrentHeight > Params().GetConsensus().nNormalizedNameForkHeight;
|
||||
}
|
||||
|
||||
std::string CClaimTrieCacheNormalizationFork::normalizeClaimName(const std::string& name, bool force) const {
|
||||
if (!force && !shouldNormalize())
|
||||
return name;
|
||||
|
||||
static std::locale utf8;
|
||||
static bool initialized = false;
|
||||
if (!initialized) {
|
||||
static boost::locale::localization_backend_manager manager =
|
||||
boost::locale::localization_backend_manager::global();
|
||||
manager.select("icu");
|
||||
|
||||
static boost::locale::generator curLocale(manager);
|
||||
utf8 = curLocale("en_US.UTF8");
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
std::string normalized;
|
||||
try {
|
||||
|
||||
// Check if it is a valid utf-8 string. If not, it will throw a
|
||||
// boost::locale::conv::conversion_error exception which we catch later
|
||||
normalized = boost::locale::conv::to_utf<char>(name, "UTF-8", boost::locale::conv::stop);
|
||||
if (normalized.empty())
|
||||
return name;
|
||||
|
||||
normalized = boost::locale::normalize(normalized, boost::locale::norm_nfd, utf8);
|
||||
|
||||
// Locale aware lowercase (the non-locale-aware version seemed to struggle with some international chars):
|
||||
normalized = boost::locale::to_lower(normalized, utf8);
|
||||
}
|
||||
catch (const boost::locale::conv::conversion_error& e){
|
||||
return name;
|
||||
}
|
||||
catch (const std::bad_cast& e) {
|
||||
LogPrintf("%s() is invalid or dependencies are missing: %s\n", __func__, e.what());
|
||||
throw;
|
||||
}
|
||||
catch (const std::exception& e) { // TODO: change to use ... with current_exception() in c++11
|
||||
LogPrintf("%s() had an unexpected exception: %s\n", __func__, e.what());
|
||||
return name;
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::insertClaimIntoTrie(const std::string& name, CClaimValue claim,
|
||||
bool fCheckTakeover) const {
|
||||
return CClaimTrieCacheExpirationFork::insertClaimIntoTrie(normalizeClaimName(name, overrideInsertNormalization), claim, fCheckTakeover);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::removeClaimFromTrie(const std::string& name, const COutPoint& outPoint,
|
||||
CClaimValue& claim, bool fCheckTakeover) const {
|
||||
return CClaimTrieCacheExpirationFork::removeClaimFromTrie(normalizeClaimName(name, overrideRemoveNormalization), outPoint, claim, fCheckTakeover);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::insertSupportIntoMap(const std::string& name, CSupportValue support,
|
||||
bool fCheckTakeover) const {
|
||||
return CClaimTrieCacheExpirationFork::insertSupportIntoMap(normalizeClaimName(name, overrideInsertNormalization), support, fCheckTakeover);
|
||||
}
|
||||
bool CClaimTrieCacheNormalizationFork::removeSupportFromMap(const std::string& name, const COutPoint& outPoint,
|
||||
CSupportValue& support, bool fCheckTakeover) const {
|
||||
return CClaimTrieCacheExpirationFork::removeSupportFromMap(normalizeClaimName(name, overrideRemoveNormalization), outPoint, support, fCheckTakeover);
|
||||
}
|
||||
|
||||
struct claimsForNormalization: public claimsForNameType {
|
||||
const std::string normalized;
|
||||
claimsForNormalization(std::vector<CClaimValue> claims, std::vector<CSupportValue> supports,
|
||||
int nLastTakeoverHeight, const std::string& name, const std::string& normalized)
|
||||
: claimsForNameType(claims, supports, nLastTakeoverHeight, name), normalized(normalized) {}
|
||||
};
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary(insertUndoType& insertUndo, claimQueueRowType& removeUndo,
|
||||
insertUndoType& insertSupportUndo, supportQueueRowType& expireSupportUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo) const {
|
||||
|
||||
struct CNameChangeDetector: public CNodeCallback {
|
||||
std::vector<claimsForNormalization> hits;
|
||||
const CClaimTrieCacheNormalizationFork* owner;
|
||||
CNameChangeDetector(const CClaimTrieCacheNormalizationFork* owner): owner(owner) {}
|
||||
void visit(const std::string& name, const CClaimTrieNode* node) {
|
||||
if (node->claims.empty()) return;
|
||||
const std::string normalized = owner->normalizeClaimName(name, true);
|
||||
if (normalized == name) return;
|
||||
|
||||
supportMapEntryType supports;
|
||||
owner->getSupportsForName(name, supports);
|
||||
hits.push_back(claimsForNormalization(node->claims, supports, node->nHeightOfLastTakeover, name, normalized));
|
||||
}
|
||||
};
|
||||
|
||||
if (nCurrentHeight == Params().GetConsensus().nNormalizedNameForkHeight) {
|
||||
|
||||
// run the one-time upgrade of all names that need to change
|
||||
// it modifies the (cache) trie as it goes, so we need to grab everything to be modified first
|
||||
|
||||
CNameChangeDetector detector(this);
|
||||
iterateTrie(detector);
|
||||
|
||||
for (std::vector<claimsForNormalization>::iterator it = detector.hits.begin(); it != detector.hits.end(); ++it) {
|
||||
BOOST_FOREACH(CSupportValue support, it->supports) {
|
||||
// if it's already going to expire just skip it
|
||||
if (support.nHeight + base->nExpirationTime <= nCurrentHeight)
|
||||
continue;
|
||||
|
||||
bool success = removeSupportFromMap(it->name, support.outPoint, support, false);
|
||||
assert(success);
|
||||
expireSupportUndo.push_back(std::make_pair(it->name, support));
|
||||
success = insertSupportIntoMap(it->normalized, support, false);
|
||||
assert(success);
|
||||
insertSupportUndo.push_back(nameOutPointHeightType(it->name, support.outPoint, -1));
|
||||
}
|
||||
|
||||
BOOST_FOREACH(CClaimValue claim, it->claims) {
|
||||
if (claim.nHeight + base->nExpirationTime <= nCurrentHeight)
|
||||
continue;
|
||||
|
||||
bool success = removeClaimFromTrie(it->name, claim.outPoint, claim, false);
|
||||
assert(success);
|
||||
removeUndo.push_back(std::make_pair(it->name, claim));
|
||||
|
||||
success = insertClaimIntoTrie(it->normalized, claim, true);
|
||||
assert(success);
|
||||
insertUndo.push_back(nameOutPointHeightType(it->name, claim.outPoint, -1));
|
||||
}
|
||||
|
||||
takeoverHeightUndo.push_back(std::make_pair(it->name, it->nLastTakeoverHeight));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::incrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo) {
|
||||
overrideInsertNormalization = normalizeAllNamesInTrieIfNecessary(insertUndo, expireUndo, insertSupportUndo,
|
||||
expireSupportUndo, takeoverHeightUndo);
|
||||
BOOST_SCOPE_EXIT(&overrideInsertNormalization) { overrideInsertNormalization = false; } BOOST_SCOPE_EXIT_END
|
||||
return CClaimTrieCacheExpirationFork::incrementBlock(insertUndo, expireUndo, insertSupportUndo,
|
||||
expireSupportUndo, takeoverHeightUndo);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::decrementBlock(insertUndoType& insertUndo,
|
||||
claimQueueRowType& expireUndo,
|
||||
insertUndoType& insertSupportUndo,
|
||||
supportQueueRowType& expireSupportUndo,
|
||||
std::vector<std::pair<std::string, int> >& takeoverHeightUndo) {
|
||||
|
||||
overrideRemoveNormalization = shouldNormalize();
|
||||
BOOST_SCOPE_EXIT(&overrideRemoveNormalization) { overrideRemoveNormalization = false; } BOOST_SCOPE_EXIT_END
|
||||
return CClaimTrieCacheExpirationFork::decrementBlock(insertUndo, expireUndo, insertSupportUndo,
|
||||
expireSupportUndo, takeoverHeightUndo);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::getProofForName(const std::string& name, CClaimTrieProof& proof) const {
|
||||
return CClaimTrieCacheExpirationFork::getProofForName(normalizeClaimName(name), proof);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::getInfoForName(const std::string& name, CClaimValue& claim) const {
|
||||
return CClaimTrieCacheExpirationFork::getInfoForName(normalizeClaimName(name), claim);
|
||||
}
|
||||
|
||||
claimsForNameType CClaimTrieCacheNormalizationFork::getClaimsForName(const std::string& name) const {
|
||||
return CClaimTrieCacheExpirationFork::getClaimsForName(normalizeClaimName(name));
|
||||
}
|
||||
|
||||
int CClaimTrieCacheNormalizationFork::getDelayForName(const std::string& name, const uint160& claimId) const {
|
||||
return CClaimTrieCacheExpirationFork::getDelayForName(normalizeClaimName(name), claimId);
|
||||
}
|
||||
|
||||
void CClaimTrieCacheNormalizationFork::addClaimToQueues(const std::string& name, CClaimValue& claim) const {
|
||||
return CClaimTrieCacheExpirationFork::addClaimToQueues(normalizeClaimName(name,
|
||||
claim.nValidAtHeight > Params().GetConsensus().nNormalizedNameForkHeight), claim);
|
||||
}
|
||||
|
||||
bool CClaimTrieCacheNormalizationFork::addSupportToQueues(const std::string& name, CSupportValue& support) const {
|
||||
return CClaimTrieCacheExpirationFork::addSupportToQueues(normalizeClaimName(name,
|
||||
support.nValidAtHeight > Params().GetConsensus().nNormalizedNameForkHeight), support);
|
||||
}
|
||||
|
||||
std::string CClaimTrieCacheNormalizationFork::adjustNameForValidHeight(const std::string& name, int validHeight) const {
|
||||
return normalizeClaimName(name, validHeight > Params().GetConsensus().nNormalizedNameForkHeight);
|
||||
}
|
19
src/init.cpp
19
src/init.cpp
|
@ -1425,27 +1425,10 @@ bool AppInit2(boost::thread_group& threadGroup, CScheduler& scheduler)
|
|||
RandAddSeedPerfmon();
|
||||
|
||||
pclaimTrie->setExpirationTime(consensusParams.GetExpirationTime(chainActive.Height()));
|
||||
// Possible enhancement TODO: Instead of forcing a re-init, store
|
||||
// fork status on disk and just load at start-up (on initial
|
||||
// load).
|
||||
if ((chainActive.Height() >= (Params().GetConsensus().nNormalizedNameForkHeight - 1)) &&
|
||||
!pclaimTrie->shouldNormalize()) {
|
||||
LogPrintf("Reloading ClaimTrie with normalization enabled\n");
|
||||
|
||||
delete pclaimTrie;
|
||||
pclaimTrie = new CClaimTrie(false, fReindex, true);
|
||||
assert(pclaimTrie->shouldNormalize());
|
||||
|
||||
if (!pclaimTrie->ReadFromDisk(true)) {
|
||||
LogPrintf("Error re-loading the claim trie from disk");
|
||||
return false;
|
||||
}
|
||||
LogPrintf("Finished reloading ClaimTrie with normalization enabled\n");
|
||||
}
|
||||
|
||||
//// debug print
|
||||
LogPrintf("mapBlockIndex.size() = %u\n", mapBlockIndex.size());
|
||||
LogPrintf("nBestHeight = %d\n", chainActive.Height());
|
||||
LogPrintf("nBestHeight = %d\n", chainActive.Height());
|
||||
#ifdef ENABLE_WALLET
|
||||
LogPrintf("setKeyPool.size() = %u\n", pwalletMain ? pwalletMain->setKeyPool.size() : 0);
|
||||
LogPrintf("mapWallet.size() = %u\n", pwalletMain ? pwalletMain->mapWallet.size() : 0);
|
||||
|
|
44
src/main.cpp
44
src/main.cpp
|
@ -2067,7 +2067,6 @@ static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, CClaimTr
|
|||
std::vector<std::vector<unsigned char> > vvchParams;
|
||||
if (undo.fIsClaim && DecodeClaimScript(undo.txout.scriptPubKey, op, vvchParams))
|
||||
{
|
||||
const bool shouldNormalize = pclaimTrie->shouldNormalize();
|
||||
if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM)
|
||||
{
|
||||
uint160 claimId;
|
||||
|
@ -2086,7 +2085,7 @@ static bool ApplyTxInUndo(const CTxInUndo& undo, CCoinsViewCache& view, CClaimTr
|
|||
if (nValidHeight > 0 && nValidHeight >= coins->nHeight)
|
||||
{
|
||||
LogPrintf("%s: (txid: %s, nOut: %d) Restoring %s to the claim trie due to a block being disconnected (normalize claim active: %s)\n",
|
||||
__func__, out.hash.ToString(), out.n, name.c_str(), (shouldNormalize ? "true" : "false"));
|
||||
__func__, out.hash.ToString(), out.n, name.c_str(), (trieCache.shouldNormalize() ? "true" : "false"));
|
||||
if (!trieCache.undoSpendClaim(name, COutPoint(out.hash, out.n), claimId, undo.txout.nValue, coins->nHeight, nValidHeight))
|
||||
LogPrintf("%s: Something went wrong inserting the claim\n", __func__);
|
||||
}
|
||||
|
@ -2141,13 +2140,6 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
|||
|
||||
assert(trieCache.decrementBlock(blockUndo.insertUndo, blockUndo.expireUndo, blockUndo.insertSupportUndo, blockUndo.expireSupportUndo, blockUndo.takeoverHeightUndo));
|
||||
|
||||
if (pindex->nHeight == Params().GetConsensus().nNormalizedNameForkHeight) {
|
||||
LogPrintf("Decremented past the normalization hard fork height\n");
|
||||
const uint256 prevHash = trieCache.getBestBlock();
|
||||
pclaimTrie = pclaimTrie->enableNormalizationFork(false, pindex->nHeight, trieCache);
|
||||
trieCache.setBestBlock(prevHash);
|
||||
}
|
||||
|
||||
// undo transactions in reverse order
|
||||
for (int i = block.vtx.size() - 1; i >= 0; i--) {
|
||||
const CTransaction &tx = block.vtx[i];
|
||||
|
@ -2177,7 +2169,6 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
|||
std::vector<std::vector<unsigned char> > vvchParams;
|
||||
if (DecodeClaimScript(txout.scriptPubKey, op, vvchParams))
|
||||
{
|
||||
bool shouldNormalize = pclaimTrie->shouldNormalize();
|
||||
if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM)
|
||||
{
|
||||
uint160 claimId;
|
||||
|
@ -2203,7 +2194,7 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
|||
}
|
||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||
LogPrintf("%s: (txid: %s, nOut: %d) Trying to remove %s from the claim trie due to its block being disconnected\n", __func__, hash.ToString(), i, name.c_str());
|
||||
if (!trieCache.undoAddClaim(name, COutPoint(hash, i))) {
|
||||
if (!trieCache.undoAddClaim(name, COutPoint(hash, i), pindex->nHeight)) {
|
||||
LogPrintf("%s: Could not find the claim in the trie or the cache\n", __func__);
|
||||
}
|
||||
}
|
||||
|
@ -2215,7 +2206,7 @@ bool DisconnectBlock(const CBlock& block, CValidationState& state, const CBlockI
|
|||
LogPrintf("--- %s[%lu]: OP_SUPPORT_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||
__func__, pindex->nHeight, name, supportedClaimId.GetHex(), hash.ToString(), i);
|
||||
LogPrintf("%s: (txid: %s, nOut: %d) Removing support for claim id %s on %s due to its block being disconnected (normalize fork active: %s)\n",
|
||||
__func__, hash.ToString(), i, supportedClaimId.ToString(), name.c_str(), (shouldNormalize ? "true" : "false"));
|
||||
__func__, hash.ToString(), i, supportedClaimId.ToString(), name.c_str(), (trieCache.shouldNormalize() ? "true" : "false"));
|
||||
if (!trieCache.undoAddSupport(name, COutPoint(hash, i), pindex->nHeight))
|
||||
LogPrintf("%s: Something went wrong removing support for name %s in hash %s\n", __func__, name.c_str(), hash.ToString());
|
||||
}
|
||||
|
@ -2612,13 +2603,12 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
std::vector<std::vector<unsigned char> > vvchParams;
|
||||
if (DecodeClaimScript(coins->vout[txin.prevout.n].scriptPubKey, op, vvchParams))
|
||||
{
|
||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||
if (op == OP_CLAIM_NAME || op == OP_UPDATE_CLAIM)
|
||||
{
|
||||
uint160 claimId;
|
||||
if (op == OP_CLAIM_NAME)
|
||||
{
|
||||
assert(vvchParams.size() == 2);
|
||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||
std::string value(vvchParams[1].begin(), vvchParams[1].end());
|
||||
claimId = ClaimIdHash(txin.prevout.hash, txin.prevout.n);
|
||||
LogPrintf("+++ %s[%lu]: OP_CLAIM_NAME \"%s\" = \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||
|
@ -2627,18 +2617,15 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
}
|
||||
else if (op == OP_UPDATE_CLAIM)
|
||||
{
|
||||
assert(vvchParams.size() == 3);
|
||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||
std::string value(vvchParams[1].begin(), vvchParams[1].end());
|
||||
claimId = uint160(vvchParams[1]);
|
||||
std::string value(vvchParams[2].begin(), vvchParams[2].end());
|
||||
LogPrintf("+++ %s[%lu]: OP_UPDATE_CLAIM \"%s\" = \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||
__func__, pindex->nHeight, name, SanitizeString(value),
|
||||
claimId.GetHex(), txin.prevout.hash.GetHex(), txin.prevout.n);
|
||||
}
|
||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||
int nValidAtHeight;
|
||||
LogPrintf("%s: Removing %s from the claim trie. Tx: %s, nOut: %d\n", __func__, name, txin.prevout.hash.GetHex(), txin.prevout.n);
|
||||
if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), nValidAtHeight)) {
|
||||
if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), coins->nHeight, nValidAtHeight)) {
|
||||
mClaimUndoHeights[i] = nValidAtHeight;
|
||||
std::pair<std::string, uint160> entry(name, claimId);
|
||||
spentClaims.push_back(entry);
|
||||
|
@ -2648,8 +2635,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
}
|
||||
else if (op == OP_SUPPORT_CLAIM)
|
||||
{
|
||||
assert(vvchParams.size() == 2);
|
||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||
uint160 supportedClaimId(vvchParams[1]);
|
||||
LogPrintf("+++ %s[%lu]: OP_SUPPORT_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n",
|
||||
__func__, pindex->nHeight, name,
|
||||
|
@ -2695,13 +2680,9 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
spentClaimsType::iterator itSpent;
|
||||
for (itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent)
|
||||
{
|
||||
if (pclaimTrie->shouldNormalize()) {
|
||||
const std::string normalizedName1 = normalizeClaimName(name);
|
||||
const std::string normalizedName2 = normalizeClaimName(itSpent->first);
|
||||
if (normalizedName1 == normalizedName2 && itSpent->second == claimId)
|
||||
if (itSpent->second == claimId) {
|
||||
if (trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->first))
|
||||
break;
|
||||
} else if (itSpent->first == name && itSpent->second == claimId) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (itSpent != spentClaims.end())
|
||||
|
@ -2757,15 +2738,6 @@ bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockIndex* pin
|
|||
pos.nTxOffset += ::GetSerializeSize(tx, SER_DISK, CLIENT_VERSION);
|
||||
}
|
||||
|
||||
if (pindex->nHeight == Params().GetConsensus().nNormalizedNameForkHeight) {
|
||||
LogPrintf("Incremented past the normalization hard fork height\n");
|
||||
pclaimTrie = pclaimTrie->enableNormalizationFork(true, pindex->nHeight, trieCache);
|
||||
CClaimTrieCache tmpTrieCache(pclaimTrie);
|
||||
tmpTrieCache.setBestBlock(trieCache.getBestBlock());
|
||||
trieCache = tmpTrieCache;
|
||||
trieCache.getMerkleHash(true);
|
||||
}
|
||||
|
||||
assert(trieCache.incrementBlock(blockUndo.insertUndo, blockUndo.expireUndo, blockUndo.insertSupportUndo, blockUndo.expireSupportUndo, blockUndo.takeoverHeightUndo));
|
||||
|
||||
if (trieCache.getMerkleHash() != block.hashClaimTrie) {
|
||||
|
|
|
@ -294,7 +294,7 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s
|
|||
}
|
||||
std::string name(vvchParams[0].begin(), vvchParams[0].end());
|
||||
int throwaway;
|
||||
if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), throwaway)) {
|
||||
if (trieCache.spendClaim(name, COutPoint(txin.prevout.hash, txin.prevout.n), nTxinHeight, throwaway)) {
|
||||
std::pair<std::string, uint160> entry(name, claimId);
|
||||
spentClaims.push_back(entry);
|
||||
}
|
||||
|
@ -341,12 +341,10 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s
|
|||
spentClaimsType::iterator itSpent;
|
||||
for (itSpent = spentClaims.begin(); itSpent != spentClaims.end(); ++itSpent)
|
||||
{
|
||||
if (pclaimTrie->shouldNormalize() &&
|
||||
(normalizeClaimName(name) == normalizeClaimName(itSpent->first)) &&
|
||||
itSpent->second == claimId)
|
||||
break;
|
||||
else if (itSpent->first == name && itSpent->second == claimId)
|
||||
break;
|
||||
if (itSpent->second == claimId) {
|
||||
if (trieCache.normalizeClaimName(name) == trieCache.normalizeClaimName(itSpent->first))
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (itSpent != spentClaims.end())
|
||||
{
|
||||
|
@ -445,31 +443,14 @@ CBlockTemplate* CreateNewBlock(const CChainParams& chainparams, const CScript& s
|
|||
supportQueueRowType dummyExpireSupportUndo;
|
||||
std::vector<std::pair<std::string, int> > dummyTakeoverHeightUndo;
|
||||
|
||||
if (nHeight == Params().GetConsensus().nNormalizedNameForkHeight) {
|
||||
trieCache.setBestBlock(pindexPrev->GetBlockHash());
|
||||
pclaimTrie = pclaimTrie->enableNormalizationFork(true, nHeight, trieCache);
|
||||
CClaimTrieCache tmpTrieCache(pclaimTrie);
|
||||
tmpTrieCache.setBestBlock(trieCache.getBestBlock());
|
||||
trieCache = tmpTrieCache;
|
||||
trieCache.getMerkleHash(true);
|
||||
}
|
||||
|
||||
trieCache.incrementBlock(dummyInsertUndo, dummyExpireUndo, dummyInsertSupportUndo, dummyExpireSupportUndo, dummyTakeoverHeightUndo);
|
||||
|
||||
pblock->hashClaimTrie = trieCache.getMerkleHash();
|
||||
|
||||
// disable the fork enabled above
|
||||
if (nHeight == Params().GetConsensus().nNormalizedNameForkHeight)
|
||||
pclaimTrie = pclaimTrie->enableNormalizationFork(false, nHeight, trieCache);
|
||||
|
||||
CValidationState state;
|
||||
if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) {
|
||||
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state)));
|
||||
}
|
||||
|
||||
// disable the fork enabled in TestBlockValidity
|
||||
if (nHeight == Params().GetConsensus().nNormalizedNameForkHeight)
|
||||
pclaimTrie = pclaimTrie->enableNormalizationFork(false, nHeight, trieCache);
|
||||
}
|
||||
return pblocktemplate.release();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include "boost/scope_exit.hpp"
|
||||
#include "consensus/validation.h"
|
||||
#include "init.h"
|
||||
#include "main.h"
|
||||
|
@ -88,15 +87,16 @@ UniValue getclaimsintrie(const UniValue& params, bool fHelp)
|
|||
"Result: \n"
|
||||
"[\n"
|
||||
" {\n"
|
||||
" \"name\" (string) the name claimed\n"
|
||||
" \"claims\": [ (array of object) the claims for this name\n"
|
||||
" \"normalized_name\" (string) the name of these claims (after normalization)\n"
|
||||
" \"claims\": [ (array of object) the claims for this name\n"
|
||||
" {\n"
|
||||
" \"claimId\" (string) the claimId of the claim\n"
|
||||
" \"txid\" (string) the txid of the claim\n"
|
||||
" \"n\" (numeric) the vout value of the claim\n"
|
||||
" \"amount\" (numeric) txout amount\n"
|
||||
" \"height\" (numeric) the height of the block in which this transaction is located\n"
|
||||
" \"value\" (string) the value of this claim\n"
|
||||
" \"claimId\" (string) the claimId of the claim\n"
|
||||
" \"txid\" (string) the txid of the claim\n"
|
||||
" \"n\" (numeric) the vout value of the claim\n"
|
||||
" \"amount\" (numeric) txout amount\n"
|
||||
" \"height\" (numeric) the height of the block in which this transaction is located\n"
|
||||
" \"value\" (string) the value of this claim\n"
|
||||
" \"name\" (string) the original name of this claim (before normalization)\n"
|
||||
" }\n"
|
||||
" ]\n"
|
||||
" }\n"
|
||||
|
@ -154,11 +154,15 @@ UniValue getclaimsintrie(const UniValue& params, bool fHelp)
|
|||
std::string sValue(vvchParams[1].begin(), vvchParams[1].end());
|
||||
claim.push_back(Pair("value", sValue));
|
||||
}
|
||||
std::string targetName;
|
||||
CClaimValue targetClaim;
|
||||
if (pclaimTrie->getClaimById(itClaims->claimId, targetName, targetClaim))
|
||||
claim.push_back(Pair("name", targetName));
|
||||
claims.push_back(claim);
|
||||
}
|
||||
|
||||
UniValue nodeObj(UniValue::VOBJ);
|
||||
nodeObj.push_back(Pair("name", name));
|
||||
nodeObj.push_back(Pair("normalized_name", name));
|
||||
nodeObj.push_back(Pair("claims", claims));
|
||||
nodes.push_back(nodeObj);
|
||||
}
|
||||
|
@ -286,7 +290,7 @@ UniValue getvalueforname(const UniValue& params, bool fHelp)
|
|||
if (fHelp || params.size() > 2)
|
||||
throw std::runtime_error(
|
||||
"getvalueforname \"name\"\n"
|
||||
"Return the value associated with a name, if one exists\n"
|
||||
"Return the winning value associated with a name, if one exists\n"
|
||||
"Arguments:\n"
|
||||
"1. \"name\" (string) the name to look up\n"
|
||||
"2. \"blockhash\" (string, optional) get the value\n"
|
||||
|
@ -303,7 +307,8 @@ UniValue getvalueforname(const UniValue& params, bool fHelp)
|
|||
"\"n\" (numeric) vout value\n"
|
||||
"\"amount\" (numeric) txout amount\n"
|
||||
"\"effective amount\" (numeric) txout amount plus amount from all supports associated with the claim\n"
|
||||
"\"height\" (numeric) the height of the block in which this transaction is located\n");
|
||||
"\"height\" (numeric) the height of the block in which this transaction is located\n"
|
||||
"\"name\" (string) the original name of this claim (before normalization)\n");
|
||||
|
||||
LOCK(cs_main);
|
||||
|
||||
|
@ -334,6 +339,12 @@ UniValue getvalueforname(const UniValue& params, bool fHelp)
|
|||
ret.push_back(Pair("amount", claim.nAmount));
|
||||
ret.push_back(Pair("effective amount", nEffectiveAmount));
|
||||
ret.push_back(Pair("height", claim.nHeight));
|
||||
|
||||
std::string targetName;
|
||||
CClaimValue targetClaim;
|
||||
if (pclaimTrie->getClaimById(claim.claimId, targetName, targetClaim))
|
||||
ret.push_back(Pair("name", targetName));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -371,6 +382,12 @@ UniValue claimAndSupportsToJSON(const CCoinsViewCache& coinsCache, CAmount nEffe
|
|||
ret.push_back(Pair("value", sValue));
|
||||
ret.push_back(Pair("nEffectiveAmount", nEffectiveAmount));
|
||||
ret.push_back(Pair("supports", supportObjs));
|
||||
|
||||
std::string targetName;
|
||||
CClaimValue targetClaim;
|
||||
if (pclaimTrie->getClaimById(claim.claimId, targetName, targetClaim))
|
||||
ret.push_back(Pair("name", targetName));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -391,6 +408,7 @@ UniValue getclaimsforname(const UniValue& params, bool fHelp)
|
|||
"Result:\n"
|
||||
"{\n"
|
||||
" \"nLastTakeoverHeight\" (numeric) the last height at which ownership of the name changed\n"
|
||||
" \"normalized_name\" (string) the name of these claims after normalization\n"
|
||||
" \"claims\": [ (array of object) claims for this name\n"
|
||||
" {\n"
|
||||
" \"claimId\" (string) the claimId of this claim\n"
|
||||
|
@ -408,6 +426,7 @@ UniValue getclaimsforname(const UniValue& params, bool fHelp)
|
|||
" \"nValidAtHeight\" (numeric) the height at which the support became/becomes valid\n"
|
||||
" \"nAmount\" (numeric) the amount of the support\n"
|
||||
" ]\n"
|
||||
" \"name\" (string) the original name of this claim before normalization\n"
|
||||
" }\n"
|
||||
" ],\n"
|
||||
" \"supports without claims\": [ (array of object) supports that did not match a claim for this name\n"
|
||||
|
@ -454,6 +473,7 @@ UniValue getclaimsforname(const UniValue& params, bool fHelp)
|
|||
|
||||
UniValue ret(UniValue::VOBJ);
|
||||
ret.push_back(Pair("nLastTakeoverHeight", claimsForName.nLastTakeoverHeight));
|
||||
ret.push_back(Pair("normalized_name", claimsForName.name));
|
||||
|
||||
for (claimSupportMapType::const_iterator itClaimsAndSupports = claimSupportMap.begin(); itClaimsAndSupports != claimSupportMap.end(); ++itClaimsAndSupports) {
|
||||
CAmount nEffectiveAmount = trieCache.getEffectiveAmountForClaim(claimsForName, itClaimsAndSupports->first);
|
||||
|
@ -476,7 +496,8 @@ UniValue getclaimbyid(const UniValue& params, bool fHelp)
|
|||
"1. \"claimId\" (string) the claimId of this claim\n"
|
||||
"Result:\n"
|
||||
"{\n"
|
||||
" \"name\" (string) the name of the claim\n"
|
||||
" \"name\" (string) the original name of the claim (before normalization)\n"
|
||||
" \"normalized_name\" (string) the name of this claim (after normalization)\n"
|
||||
" \"value\" (string) claim metadata\n"
|
||||
" \"claimId\" (string) the claimId of this claim\n"
|
||||
" \"txid\" (string) the hash of the transaction which has successfully claimed this name\n"
|
||||
|
@ -503,13 +524,15 @@ UniValue getclaimbyid(const UniValue& params, bool fHelp)
|
|||
pclaimTrie->getClaimById(claimId, name, claimValue);
|
||||
if (claimValue.claimId == claimId)
|
||||
{
|
||||
CClaimTrieCache cache(pclaimTrie);
|
||||
std::vector<CSupportValue> supports;
|
||||
CAmount effectiveAmount = pclaimTrie->getEffectiveAmountForClaim(name, claimValue.claimId, &supports);
|
||||
CAmount effectiveAmount = cache.getEffectiveAmountForClaim(name, claimValue.claimId, &supports);
|
||||
|
||||
std::string sValue;
|
||||
CCoinsViewCache coins(pcoinsTip);
|
||||
getValueForClaim(coins, claimValue.outPoint, sValue);
|
||||
claim.push_back(Pair("name", name));
|
||||
claim.push_back(Pair("normalized_name", cache.normalizeClaimName(name, true)));
|
||||
claim.push_back(Pair("value", sValue));
|
||||
claim.push_back(Pair("claimId", claimValue.claimId.GetHex()));
|
||||
claim.push_back(Pair("txid", claimValue.outPoint.hash.GetHex()));
|
||||
|
@ -866,6 +889,30 @@ UniValue getnameproof(const UniValue& params, bool fHelp)
|
|||
return proofToJSON(proof);
|
||||
}
|
||||
|
||||
UniValue checknormalization(const UniValue& params, bool fHelp)
|
||||
{
|
||||
if (fHelp || params.size() != 1)
|
||||
throw std::runtime_error(
|
||||
"checknormalization\n"
|
||||
"Given an unnormalized name of a claim, return normalized version of it\n"
|
||||
"Arguments:\n"
|
||||
"1. \"name\" (string) the name to normalize\n"
|
||||
"Result: \n"
|
||||
"\"normalized\" (string) fully normalized name\n"
|
||||
);
|
||||
|
||||
|
||||
std::string name = params[0].get_str();
|
||||
|
||||
CClaimTrieCache triecache(pclaimTrie);
|
||||
bool force = true;
|
||||
std::string out = triecache.normalizeClaimName(name, force);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static const CRPCCommand commands[] =
|
||||
{ // category name actor (function) okSafeMode
|
||||
// --------------------- ------------------------ ----------------------- ----------
|
||||
|
@ -879,6 +926,7 @@ static const CRPCCommand commands[] =
|
|||
{ "Claimtrie", "getclaimsfortx", &getclaimsfortx, true },
|
||||
{ "Claimtrie", "getnameproof", &getnameproof, true },
|
||||
{ "Claimtrie", "getclaimbyid", &getclaimbyid, true },
|
||||
{ "Claimtrie", "checknormalization", &checknormalization, true },
|
||||
};
|
||||
|
||||
void RegisterClaimTrieRPCCommands(CRPCTable &tableRPC)
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
using namespace std;
|
||||
|
||||
|
||||
BOOST_FIXTURE_TEST_SUITE(claimtriebranching_tests, RegTestingSetup)
|
||||
|
||||
//is a claim in queue
|
||||
|
@ -63,7 +62,8 @@ boost::test_tools::predicate_result
|
|||
best_claim_effective_amount_equals(std::string name, CAmount amount)
|
||||
{
|
||||
CClaimValue val;
|
||||
bool have_info = pclaimTrie->getInfoForName(name, val);
|
||||
CClaimTrieCache cache(pclaimTrie);
|
||||
bool have_info = cache.getInfoForName(name, val);
|
||||
if (!have_info)
|
||||
{
|
||||
boost::test_tools::predicate_result res(false);
|
||||
|
@ -72,7 +72,7 @@ best_claim_effective_amount_equals(std::string name, CAmount amount)
|
|||
}
|
||||
else
|
||||
{
|
||||
CAmount effective_amount = pclaimTrie->getEffectiveAmountForClaim(name, val.claimId);
|
||||
CAmount effective_amount = cache.getEffectiveAmountForClaim(name, val.claimId);
|
||||
if (effective_amount != amount)
|
||||
{
|
||||
boost::test_tools::predicate_result res(false);
|
||||
|
@ -117,20 +117,20 @@ struct ClaimTrieChainFixture{
|
|||
std::vector<CTransaction> coinbase_txs;
|
||||
std::vector<int> marks;
|
||||
int coinbase_txs_used;
|
||||
int unique_block_counter;
|
||||
unsigned int num_txs;
|
||||
unsigned int num_txs_for_next_block;
|
||||
|
||||
// these will take on regtest parameters
|
||||
const int normalizationForkHeight;
|
||||
const int expirationForkHeight;
|
||||
const int originalExpiration;
|
||||
const int extendedExpiration;
|
||||
int unique_block_counter;
|
||||
int normalization_original;
|
||||
|
||||
ClaimTrieChainFixture() : normalizationForkHeight(Params(CBaseChainParams::REGTEST).GetConsensus().nNormalizedNameForkHeight),
|
||||
expirationForkHeight(Params(CBaseChainParams::REGTEST).GetConsensus().nExtendedClaimExpirationForkHeight),
|
||||
ClaimTrieChainFixture() : expirationForkHeight(Params(CBaseChainParams::REGTEST).GetConsensus().nExtendedClaimExpirationForkHeight),
|
||||
originalExpiration(Params(CBaseChainParams::REGTEST).GetConsensus().nOriginalClaimExpirationTime),
|
||||
extendedExpiration(Params(CBaseChainParams::REGTEST).GetConsensus().nExtendedClaimExpirationTime)
|
||||
extendedExpiration(Params(CBaseChainParams::REGTEST).GetConsensus().nExtendedClaimExpirationTime),
|
||||
unique_block_counter(0), normalization_original(-1)
|
||||
{
|
||||
fRequireStandard = false;
|
||||
ENTER_CRITICAL_SECTION(cs_main);
|
||||
|
@ -139,7 +139,6 @@ struct ClaimTrieChainFixture{
|
|||
num_txs_for_next_block = 0;
|
||||
num_txs = 0;
|
||||
coinbase_txs_used = 0;
|
||||
unique_block_counter = 0;
|
||||
// generate coinbases to spend
|
||||
CreateCoinbases(40, coinbase_txs);
|
||||
}
|
||||
|
@ -147,14 +146,26 @@ struct ClaimTrieChainFixture{
|
|||
~ClaimTrieChainFixture()
|
||||
{
|
||||
DecrementBlocks(chainActive.Height());
|
||||
if (normalization_original >= 0) {
|
||||
const Consensus::Params& consensus = Params().GetConsensus();
|
||||
const_cast<Consensus::Params&>(consensus).nNormalizedNameForkHeight = normalization_original;
|
||||
}
|
||||
pclaimTrie->setExpirationTime(originalExpiration); // in case it was changed during the test
|
||||
LEAVE_CRITICAL_SECTION(cs_main);
|
||||
}
|
||||
|
||||
void setNormalizationForkHeight(int targetMinusCurrent) {
|
||||
int target = chainActive.Height() + targetMinusCurrent;
|
||||
const Consensus::Params& consensus = Params().GetConsensus();
|
||||
normalization_original = consensus.nNormalizedNameForkHeight;
|
||||
const_cast<Consensus::Params&>(consensus).nNormalizedNameForkHeight = target;
|
||||
}
|
||||
|
||||
bool CreateBlock(CBlockTemplate* pblocktemplate)
|
||||
{
|
||||
CBlock* pblock = &pblocktemplate->block;
|
||||
pblock->nVersion = 1;
|
||||
pblock->nTime = chainActive.Tip()->GetBlockTime() + Params().GetConsensus().nPowTargetSpacing;
|
||||
pblock->nTime = chainActive.Tip()->GetBlockTime()+Params().GetConsensus().nPowTargetSpacing;
|
||||
CMutableTransaction txCoinbase(pblock->vtx[0]);
|
||||
txCoinbase.vin[0].scriptSig = CScript() << CScriptNum(unique_block_counter++) << CScriptNum(chainActive.Height());
|
||||
txCoinbase.vout[0].nValue = GetBlockSubsidy(chainActive.Height() + 1, Params().GetConsensus());
|
||||
|
@ -162,7 +173,8 @@ struct ClaimTrieChainFixture{
|
|||
pblock->hashMerkleRoot = BlockMerkleRoot(*pblock);
|
||||
for (uint32_t i = 0;; ++i) {
|
||||
pblock->nNonce = i;
|
||||
if (CheckProofOfWork(pblock->GetPoWHash(), pblock->nBits, Params().GetConsensus())) {
|
||||
if (CheckProofOfWork(pblock->GetPoWHash(), pblock->nBits, Params().GetConsensus()))
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -170,16 +182,18 @@ struct ClaimTrieChainFixture{
|
|||
bool success = (ProcessNewBlock(state, Params(), NULL, pblock, true, NULL) && state.IsValid() && pblock->GetHash() == chainActive.Tip()->GetBlockHash());
|
||||
pblock->hashPrevBlock = pblock->GetHash();
|
||||
return success;
|
||||
|
||||
}
|
||||
|
||||
bool CreateCoinbases(unsigned int num_coinbases, std::vector<CTransaction>& coinbases)
|
||||
{
|
||||
CBlockTemplate* pblocktemplate;
|
||||
CBlockTemplate *pblocktemplate;
|
||||
coinbases.clear();
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(Params(), CScript() << OP_TRUE));
|
||||
BOOST_CHECK(pblocktemplate = CreateNewBlock(Params(), CScript()<<OP_TRUE ));
|
||||
BOOST_CHECK(pblocktemplate->block.vtx.size() == 1);
|
||||
pblocktemplate->block.hashPrevBlock = chainActive.Tip()->GetBlockHash();
|
||||
for (unsigned int i = 0; i < 100 + num_coinbases; ++i) {
|
||||
for (unsigned int i = 0; i < 100 + num_coinbases; ++i)
|
||||
{
|
||||
BOOST_CHECK(CreateBlock(pblocktemplate));
|
||||
if (coinbases.size() < num_coinbases)
|
||||
coinbases.push_back(CTransaction(pblocktemplate->block.vtx[0]));
|
||||
|
@ -188,6 +202,7 @@ struct ClaimTrieChainFixture{
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void CommitTx(CMutableTransaction &tx){
|
||||
num_txs_for_next_block++;
|
||||
num_txs++;
|
||||
|
@ -263,8 +278,7 @@ struct ClaimTrieChainFixture{
|
|||
|
||||
CMutableTransaction GetCoinbase()
|
||||
{
|
||||
CMutableTransaction tx = coinbase_txs[coinbase_txs_used];
|
||||
coinbase_txs_used++;
|
||||
CMutableTransaction tx = coinbase_txs.at(coinbase_txs_used++);
|
||||
return tx;
|
||||
}
|
||||
|
||||
|
@ -295,10 +309,10 @@ struct ClaimTrieChainFixture{
|
|||
for (int i = 0; i < num_blocks; i++) {
|
||||
CValidationState state;
|
||||
CBlockIndex* pblockindex = chainActive.Tip();
|
||||
InvalidateBlock(state, Params().GetConsensus(), pblockindex);
|
||||
BOOST_CHECK(InvalidateBlock(state, Params().GetConsensus(), pblockindex));
|
||||
if (state.IsValid())
|
||||
{
|
||||
ActivateBestChain(state, Params());
|
||||
BOOST_CHECK(ActivateBestChain(state, Params()));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -357,12 +371,12 @@ BOOST_AUTO_TEST_CASE(claim_test)
|
|||
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("test",tx3));
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size());
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").size());
|
||||
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(!is_best_claim("test",tx2));
|
||||
BOOST_CHECK(!is_best_claim("test",tx3));
|
||||
BOOST_CHECK_EQUAL(0U, pclaimTrie->getClaimsForName("test").claims.size());
|
||||
BOOST_CHECK_EQUAL(0U, pclaimTrie->getClaimsForName("test").size());
|
||||
|
||||
// make two claims , one older
|
||||
CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",1);
|
||||
|
@ -374,7 +388,7 @@ BOOST_AUTO_TEST_CASE(claim_test)
|
|||
BOOST_CHECK(is_best_claim("test", tx4));
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("test",tx4));
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size());
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").size());
|
||||
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("test", tx4));
|
||||
|
@ -394,7 +408,7 @@ BOOST_AUTO_TEST_CASE(claim_test)
|
|||
BOOST_CHECK(is_best_claim("test", tx6));
|
||||
fixture.IncrementBlocks(10);
|
||||
BOOST_CHECK(is_best_claim("test",tx7));
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size());
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").size());
|
||||
|
||||
fixture.DecrementBlocks(10);
|
||||
BOOST_CHECK(is_claim_in_queue("test",tx7));
|
||||
|
@ -596,7 +610,7 @@ BOOST_AUTO_TEST_CASE(support_spend_test)
|
|||
CMutableTransaction s2 = fixture.MakeSupport(fixture.GetCoinbase(),tx5,"test",2);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("test",tx5));
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size());
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").size());
|
||||
|
||||
// build the spend where s2 is sppent on txin[1] and tx3 is spent on txin[0]
|
||||
uint32_t prevout = 0;
|
||||
|
@ -661,7 +675,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test)
|
|||
CMutableTransaction u3 = fixture.MakeUpdate(tx3, "test", "one", ClaimIdHash(tx3.GetHash(), 0), 2);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("test",u3));
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size());
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").size());
|
||||
fixture.DecrementBlocks(11);
|
||||
|
||||
// losing update on winning claim happens without delay
|
||||
|
@ -669,7 +683,7 @@ BOOST_AUTO_TEST_CASE(claimtrie_update_test)
|
|||
CMutableTransaction tx6 = fixture.MakeClaim(fixture.GetCoinbase(),"test","one",2);
|
||||
fixture.IncrementBlocks(10);
|
||||
BOOST_CHECK(is_best_claim("test", tx5));
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").claims.size());
|
||||
BOOST_CHECK_EQUAL(2U, pclaimTrie->getClaimsForName("test").size());
|
||||
CMutableTransaction u4 = fixture.MakeUpdate(tx5, "test", "one", ClaimIdHash(tx5.GetHash(), 0), 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("test",tx6));
|
||||
|
@ -788,38 +802,38 @@ BOOST_AUTO_TEST_CASE(claimtriebranching_get_effective_amount_for_claim)
|
|||
uint160 claimId = ClaimIdHash(claimtx.GetHash(), 0);
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("test", claimId) == 2);
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("inexistent", claimId) == 0); //not found returns 0
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("test", claimId) == 2);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("inexistent", claimId) == 0); //not found returns 0
|
||||
|
||||
// one claim, one support
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), claimtx, "test", 40);
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("test", claimId) == 42);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("test", claimId) == 42);
|
||||
|
||||
// Two claims, first one with supports
|
||||
CMutableTransaction claimtx2 = fixture.MakeClaim(fixture.GetCoinbase(), "test", "two", 1);
|
||||
uint160 claimId2 = ClaimIdHash(claimtx2.GetHash(), 0);
|
||||
fixture.IncrementBlocks(10);
|
||||
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("test", claimId) == 42);
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("test", claimId2) == 1);
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("inexistent", claimId) == 0);
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("inexistent", claimId2) == 0);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("test", claimId) == 42);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("test", claimId2) == 1);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("inexistent", claimId) == 0);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("inexistent", claimId2) == 0);
|
||||
|
||||
// Two claims, both with supports, second claim effective amount being less than first claim
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), claimtx2, "test", 6);
|
||||
fixture.IncrementBlocks(13); //delay
|
||||
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("test", claimId) == 42);
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("test", claimId2) == 7);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("test", claimId) == 42);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("test", claimId2) == 7);
|
||||
|
||||
// Two claims, both with supports, second one taking over
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), claimtx2, "test", 1330);
|
||||
fixture.IncrementBlocks(26); //delay
|
||||
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("test", claimId) == 42);
|
||||
BOOST_CHECK(pclaimTrie->getEffectiveAmountForClaim("test", claimId2) == 1337);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("test", claimId) == 42);
|
||||
BOOST_CHECK(CClaimTrieCache(pclaimTrie).getEffectiveAmountForClaim("test", claimId2) == 1337);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1077,6 +1091,51 @@ BOOST_AUTO_TEST_CASE(supports_fall_through)
|
|||
BOOST_CHECK(is_best_claim("A", tx2)); //tx2 support should be active now
|
||||
}
|
||||
|
||||
/*
|
||||
normalization
|
||||
test normalization function indpendent from rest of the code
|
||||
|
||||
*/
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalization_only)
|
||||
{
|
||||
CClaimTrieCache ccache(pclaimTrie);
|
||||
|
||||
// basic ASCII casing tests
|
||||
BOOST_CHECK_EQUAL("test", ccache.normalizeClaimName("TESt", true));
|
||||
BOOST_CHECK_EQUAL("test", ccache.normalizeClaimName("tesT", true));
|
||||
BOOST_CHECK_EQUAL("test", ccache.normalizeClaimName("TesT", true));
|
||||
BOOST_CHECK_EQUAL("test", ccache.normalizeClaimName("test", true));
|
||||
BOOST_CHECK_EQUAL("test this", ccache.normalizeClaimName("Test This", true));
|
||||
|
||||
// test invalid utf8 bytes are returned as is
|
||||
BOOST_CHECK_EQUAL("\xFF", ccache.normalizeClaimName("\xFF", true));
|
||||
BOOST_CHECK_EQUAL("\xC3\x28", ccache.normalizeClaimName("\xC3\x28", true));
|
||||
|
||||
// ohm sign unicode code point \x2126 should be transformed to equivalent
|
||||
// unicode code point \x03C9 , greek small letter omega
|
||||
BOOST_CHECK_EQUAL("\xCF\x89", ccache.normalizeClaimName("\xE2\x84\xA6", true));
|
||||
|
||||
// cyrillic capital ef code point \x0424 should be transformed to lower case
|
||||
// \x0444
|
||||
BOOST_CHECK_EQUAL("\xD1\x84", ccache.normalizeClaimName("\xD0\xA4", true));
|
||||
|
||||
// armenian capital ben code point \x0532 should be transformed to lower case
|
||||
// \x0562
|
||||
BOOST_CHECK_EQUAL("\xD5\xA2", ccache.normalizeClaimName("\xD4\xB2", true));
|
||||
|
||||
// japanese pbu code point \x3076 should be transformed by NFD decomposition
|
||||
// into \x3075 and \x3099
|
||||
BOOST_CHECK_EQUAL("\xE3\x81\xB5\xE3\x82\x99",
|
||||
ccache.normalizeClaimName("\xE3\x81\xB6", true));
|
||||
|
||||
// hangul ggwalg unicode code point \xAF51 should be transformed by NFD
|
||||
// decomposition into unicode code points \x1101 \x116A \x11B0
|
||||
// source: http://unicode.org/L2/L2009/09052-tr47.html
|
||||
BOOST_CHECK_EQUAL("\xE1\x84\x81\xE1\x85\xAA\xE1\x86\xB0",
|
||||
ccache.normalizeClaimName("\xEA\xBD\x91", true));
|
||||
}
|
||||
|
||||
/*
|
||||
normalization
|
||||
check claim name normalization before the fork
|
||||
|
@ -1085,64 +1144,65 @@ BOOST_AUTO_TEST_CASE(supports_fall_through)
|
|||
BOOST_AUTO_TEST_CASE(claimtriebranching_normalization)
|
||||
{
|
||||
ClaimTrieChainFixture fixture;
|
||||
BOOST_CHECK(!pclaimTrie->shouldNormalize());
|
||||
|
||||
// Disable reg-test expiration during this test
|
||||
pclaimTrie->setExpirationTime(5000);
|
||||
|
||||
// check claim names are not normalized
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "normalizeTest", "one", 3);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("normalizeTest", tx1));
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(pclaimTrie->getTotalNamesInTrie() == 0);
|
||||
fixture.CommitTx(tx1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("normalizeTest", tx1));
|
||||
|
||||
CMutableTransaction tx2a = fixture.MakeClaim(fixture.GetCoinbase(), "Normalizetest", "one_a", 2);
|
||||
CMutableTransaction tx2 = fixture.MakeUpdate(tx2a, "Normalizetest", "one", ClaimIdHash(tx2a.GetHash(), 0), 2);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("normalizeTest", tx1));
|
||||
BOOST_CHECK(is_best_claim("Normalizetest", tx2));
|
||||
|
||||
// Activate the fork (which rebuilds the existing claimtrie and
|
||||
// cache), flattening all previously existing name clashes due to
|
||||
// the normalization
|
||||
fixture.IncrementBlocks(fixture.normalizationForkHeight - chainActive.Height());
|
||||
BOOST_CHECK(pclaimTrie->shouldNormalize());
|
||||
fixture.setNormalizationForkHeight(2);
|
||||
|
||||
// Disable reg-test expiration during this test
|
||||
pclaimTrie->setExpirationTime(5000);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("normalizeTest", tx1));
|
||||
BOOST_CHECK(is_best_claim("Normalizetest", tx2));
|
||||
|
||||
fixture.IncrementBlocks(1, true);
|
||||
|
||||
// Post-fork, tx1 (the previous winning claim) assumes all name
|
||||
// variants of what it originally was ...
|
||||
BOOST_CHECK(is_best_claim("normalizeTest", tx1)); // effective amount is 3
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("normalizeTest", 3));
|
||||
BOOST_CHECK(is_best_claim("normalizetest", tx1));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("normalizetest", 3));
|
||||
|
||||
CClaimValue val;
|
||||
pclaimTrie->getInfoForName("normalizeTest", val);
|
||||
BOOST_CHECK(!pclaimTrie->getInfoForName("normalizeTest", val));
|
||||
|
||||
// Check equivalence of normalized claim names
|
||||
BOOST_CHECK(is_best_claim("NORMALIZETEST", tx1));
|
||||
BOOST_CHECK(is_best_claim("NormalizeTeST", tx1));
|
||||
BOOST_CHECK(is_best_claim("NormaLizeTeST", tx1));
|
||||
BOOST_CHECK(is_best_claim("Normalizetest", tx1)); // collapsed tx2
|
||||
BOOST_CHECK(is_best_claim("normalizetest", tx1)); // collapsed tx2
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "NORMALIZETEST", "one", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(!is_best_claim("NORMALIZETEST", tx3));
|
||||
BOOST_CHECK(!is_best_claim("normalizetest", tx3));
|
||||
|
||||
CMutableTransaction s1 = fixture.MakeSupport(fixture.GetCoinbase(), tx1, "NoRmAlIzEtEsT", 2);
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
// Ensure that supports work for normalized claim names
|
||||
BOOST_CHECK(is_best_claim("normalizeTest", tx1)); // effective amount is 5
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("normalizeTEST", 5));
|
||||
BOOST_CHECK(is_best_claim("normalizetest", tx1)); // effective amount is 5
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("normalizetest", 5));
|
||||
|
||||
CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(), "foo", "bar", 1);
|
||||
CMutableTransaction s2 = fixture.MakeSupport(fixture.GetCoinbase(), tx4, "Foo", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("FOO", tx4));
|
||||
BOOST_CHECK(is_best_claim("foo", tx4));
|
||||
|
||||
CMutableTransaction u1 = fixture.MakeUpdate(tx4, "foo", "baz", ClaimIdHash(tx4.GetHash(), 0), 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("fOO", u1));
|
||||
BOOST_CHECK(is_best_claim("foo", u1));
|
||||
|
||||
CMutableTransaction u2 = fixture.MakeUpdate(tx1, "nOrmalIzEtEst", "two", ClaimIdHash(tx1.GetHash(), 0), 3);
|
||||
fixture.IncrementBlocks(1);
|
||||
|
@ -1155,60 +1215,364 @@ BOOST_AUTO_TEST_CASE(claimtriebranching_normalization)
|
|||
CClaimValue nval1;
|
||||
pclaimTrie->getInfoForName("amélie", nval1);
|
||||
BOOST_CHECK(nval1.claimId == ClaimIdHash(tx5.GetHash(), 0));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("Ame\u0301lie", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("amélie", 2));
|
||||
|
||||
// Check equivalence of normalized claim names
|
||||
BOOST_CHECK(is_best_claim("Ame\u0301lie", tx5));
|
||||
BOOST_CHECK(is_best_claim("Amélie", tx5));
|
||||
BOOST_CHECK(is_best_claim("amélie", tx5));
|
||||
BOOST_CHECK(is_best_claim("améLIE", tx5));
|
||||
|
||||
CMutableTransaction tx7 = fixture.MakeClaim(fixture.GetCoinbase(), "あてはまる", "jn1", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("あてはまる", tx7));
|
||||
|
||||
CMutableTransaction tx8 = fixture.MakeClaim(fixture.GetCoinbase(), "añejo", "es1", 1);
|
||||
CMutableTransaction tx8 = fixture.MakeClaim(fixture.GetCoinbase(), "AÑEJO", "es1", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("añejo", tx8));
|
||||
BOOST_CHECK(is_best_claim("Añejo", tx8));
|
||||
BOOST_CHECK(is_best_claim("AñeJO", tx8));
|
||||
BOOST_CHECK(is_best_claim("AñEjO", tx8));
|
||||
|
||||
// Rewind to 1 block before the fork and be sure that the fork is
|
||||
// no longer active
|
||||
fixture.DecrementBlocks((chainActive.Height() - fixture.normalizationForkHeight) + 1);
|
||||
BOOST_CHECK(!pclaimTrie->shouldNormalize());
|
||||
// Rewind to 1 block before the fork and be sure that the fork is no longer active
|
||||
fixture.DecrementBlocks();
|
||||
|
||||
// Now check that our old (non-normalized) claims are 'alive' again
|
||||
BOOST_CHECK(is_best_claim("normalizeTest", tx1));
|
||||
BOOST_CHECK(!is_best_claim("NORMALIZETEST", tx1)); // no longer equivalent
|
||||
|
||||
BOOST_CHECK(!is_best_claim("Normalizetest", tx1)); // no longer equivalent
|
||||
BOOST_CHECK(is_best_claim("Normalizetest", tx2));
|
||||
|
||||
// Create new claim
|
||||
CMutableTransaction tx9 = fixture.MakeClaim(fixture.GetCoinbase(), "blah", "blah", 1);
|
||||
std::string invalidUtf8("\xFF\xFF");
|
||||
CMutableTransaction tx10 = fixture.MakeClaim(fixture.GetCoinbase(), invalidUtf8, "blah", 1); // invalid UTF8
|
||||
|
||||
// Roll forward to fork height again and check again that we're normalized
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(chainActive.Height() == fixture.normalizationForkHeight);
|
||||
BOOST_CHECK(is_best_claim("NORMALIZETEST", tx1));
|
||||
BOOST_CHECK(is_best_claim("NormalizeTeST", tx1));
|
||||
BOOST_CHECK(is_best_claim("NormaLizeTeST", tx1));
|
||||
BOOST_CHECK(is_best_claim("Normalizetest", tx1)); // collapsed tx2
|
||||
BOOST_CHECK(chainActive.Height() == Params().GetConsensus().nNormalizedNameForkHeight);
|
||||
BOOST_CHECK(is_best_claim("normalizetest", tx1)); // collapsed tx2
|
||||
BOOST_CHECK(is_best_claim(invalidUtf8, tx10));
|
||||
|
||||
// Rewind to 1 block before the fork and be sure that the fork is
|
||||
// no longer active
|
||||
fixture.DecrementBlocks((chainActive.Height() - fixture.normalizationForkHeight) + 1);
|
||||
BOOST_CHECK(!pclaimTrie->shouldNormalize());
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("Normalizetest", tx2));
|
||||
|
||||
// Roll forward to fork height again and check again that we're normalized
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(chainActive.Height() == fixture.normalizationForkHeight);
|
||||
BOOST_CHECK(is_best_claim("NORMALIZETEST", tx1));
|
||||
BOOST_CHECK(is_best_claim("NormalizeTeST", tx1));
|
||||
BOOST_CHECK(is_best_claim("NormaLizeTeST", tx1));
|
||||
BOOST_CHECK(is_best_claim("Normalizetest", tx1)); // collapsed tx2
|
||||
BOOST_CHECK(chainActive.Height() == Params().GetConsensus().nNormalizedNameForkHeight);
|
||||
BOOST_CHECK(is_best_claim("normalizetest", tx1)); // collapsed tx2
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
|
||||
{
|
||||
ClaimTrieChainFixture fixture;
|
||||
|
||||
std::string name = "Ame\u0301lie";
|
||||
|
||||
std::string name_upper = "Amélie";
|
||||
std::string name_normd = "amélie"; // this accented e is not actually the same as the one above; this has been "normalized"
|
||||
|
||||
BOOST_CHECK(name != name_upper);
|
||||
|
||||
// Add another set of unicode claims that will collapse after the fork
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), name, "amilie", 2);
|
||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), name_upper, "amelie", 2);
|
||||
fixture.MakeClaim(fixture.GetCoinbase(), "amelie1", "amelie", 2);
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
CClaimValue lookupClaim;
|
||||
std::string lookupName;
|
||||
BOOST_CHECK(pclaimTrie->getClaimById(ClaimIdHash(tx2.GetHash(), 0), lookupName, lookupClaim));
|
||||
CClaimValue nval1;
|
||||
BOOST_CHECK(pclaimTrie->getInfoForName("amelie1", nval1));
|
||||
// amélie is not found cause normalization still not appear
|
||||
BOOST_CHECK(!pclaimTrie->getInfoForName(name_normd, nval1));
|
||||
|
||||
// Activate the fork (which rebuilds the existing claimtrie and
|
||||
// cache), flattening all previously existing name clashes due to
|
||||
// the normalization
|
||||
fixture.setNormalizationForkHeight(1);
|
||||
int currentHeight = chainActive.Height();
|
||||
|
||||
fixture.IncrementBlocks(1);
|
||||
// Ok normalization fix the name problem
|
||||
BOOST_CHECK(pclaimTrie->getInfoForName(name_normd, nval1));
|
||||
BOOST_CHECK(nval1.nHeight == currentHeight);
|
||||
BOOST_CHECK(lookupClaim == nval1);
|
||||
|
||||
CCoinsViewCache coins(pcoinsTip);
|
||||
CClaimTrieCache trieCache(pclaimTrie);
|
||||
CBlockIndex* pindex = chainActive.Tip();
|
||||
CValidationState state;
|
||||
CBlock block;
|
||||
int amelieValidHeight;
|
||||
BOOST_CHECK(trieCache.shouldNormalize());
|
||||
BOOST_CHECK(ReadBlockFromDisk(block, pindex, Params().GetConsensus()));
|
||||
BOOST_CHECK(DisconnectBlock(block, state, pindex, coins, trieCache, NULL));
|
||||
BOOST_CHECK(state.IsValid());
|
||||
BOOST_CHECK(!trieCache.shouldNormalize());
|
||||
BOOST_CHECK(!trieCache.spendClaim(name_normd, COutPoint(tx2.GetHash(), 0), currentHeight, amelieValidHeight));
|
||||
BOOST_CHECK(trieCache.spendClaim(name_upper, COutPoint(tx2.GetHash(), 0), currentHeight, amelieValidHeight));
|
||||
|
||||
BOOST_CHECK(!pclaimTrie->getInfoForName(name, nval1));
|
||||
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
|
||||
BOOST_CHECK(trieCache.addClaim(name, COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), CAmount(2), currentHeight + 1));
|
||||
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
|
||||
insertUndoType insertUndo;
|
||||
claimQueueRowType expireUndo;
|
||||
insertUndoType insertSupportUndo;
|
||||
supportQueueRowType expireSupportUndo;
|
||||
std::vector<std::pair<std::string, int> > takeoverHeightUndo;
|
||||
BOOST_CHECK(trieCache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverHeightUndo));
|
||||
BOOST_CHECK(trieCache.shouldNormalize());
|
||||
// we cannot use getXXXForName cause they will normalized name
|
||||
|
||||
struct CNameVerifierCallback : public CNodeCallback {
|
||||
const std::string& cmp;
|
||||
CNameVerifierCallback(const std::string& cmp) : cmp(cmp) {}
|
||||
void visit(const std::string& nodeName, const CClaimTrieNode* node) {
|
||||
BOOST_CHECK(nodeName != cmp);
|
||||
}
|
||||
};
|
||||
|
||||
CNameVerifierCallback callback(name);
|
||||
trieCache.iterateTrie(callback);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(undo_normalization_does_not_kill_claim_order) {
|
||||
ClaimTrieChainFixture fixture;
|
||||
fixture.setNormalizationForkHeight(5);
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "1", 1);
|
||||
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "a", "3", 3);
|
||||
fixture.IncrementBlocks(1);
|
||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "2", 2);
|
||||
fixture.IncrementBlocks(2);
|
||||
BOOST_CHECK(is_best_claim("A", tx2));
|
||||
fixture.IncrementBlocks(3, true);
|
||||
BOOST_CHECK(is_best_claim("a", tx3));
|
||||
fixture.DecrementBlocks();
|
||||
BOOST_CHECK(is_best_claim("A", tx2));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalized_activations_fall_through) {
|
||||
ClaimTrieChainFixture fixture;
|
||||
fixture.setNormalizationForkHeight(5);
|
||||
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "AB", "1", 1);
|
||||
fixture.IncrementBlocks(3);
|
||||
BOOST_CHECK(pclaimTrie->nProportionalDelayFactor == 1);
|
||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "Ab", "2", 4);
|
||||
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "aB", "2", 3);
|
||||
CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(), "ab", "2", 2);
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
BOOST_CHECK(is_best_claim("AB", tx1));
|
||||
fixture.IncrementBlocks(3);
|
||||
BOOST_CHECK(is_best_claim("ab", tx2));
|
||||
BOOST_CHECK(pclaimTrie->getClaimsForName("ab").size() == 4U);
|
||||
fixture.DecrementBlocks(3);
|
||||
fixture.Spend(tx1);
|
||||
fixture.Spend(tx2);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("ab", tx3));
|
||||
BOOST_CHECK(pclaimTrie->getClaimsForName("ab").size() == 2U);
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("AB", tx1));
|
||||
fixture.Spend(tx1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("ab", tx2));
|
||||
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
fixture.IncrementBlocks(i, true); // well into normalized teritory
|
||||
CMutableTransaction tx5 = fixture.MakeClaim(fixture.GetCoinbase(), "CD", "a", 1 + i);
|
||||
fixture.IncrementBlocks(3);
|
||||
CMutableTransaction tx6 = fixture.MakeClaim(fixture.GetCoinbase(), "Cd", "b", 2 + i);
|
||||
CMutableTransaction tx7 = fixture.MakeClaim(fixture.GetCoinbase(), "cD", "c", 3 + i);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("cd", tx5));
|
||||
fixture.Spend(tx5);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("cd", tx7));
|
||||
fixture.DecrementBlocks();
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalization_removal_test)
|
||||
{
|
||||
ClaimTrieChainFixture fixture;
|
||||
fixture.setNormalizationForkHeight(2);
|
||||
fixture.IncrementBlocks(3);
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "AB", "1", 1);
|
||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "Ab", "2", 2);
|
||||
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "aB", "3", 3);
|
||||
CMutableTransaction sx1 = fixture.MakeSupport(fixture.GetCoinbase(), tx1, "AB", 1);
|
||||
CMutableTransaction sx2 = fixture.MakeSupport(fixture.GetCoinbase(), tx2, "Ab", 1);
|
||||
|
||||
CClaimTrieCache cache(pclaimTrie);
|
||||
cache.addClaim("AB", COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), 1, pclaimTrie->nCurrentHeight);
|
||||
cache.addClaim("Ab", COutPoint(tx2.GetHash(), 0), ClaimIdHash(tx2.GetHash(), 0), 2, pclaimTrie->nCurrentHeight);
|
||||
cache.addClaim("aB", COutPoint(tx3.GetHash(), 0), ClaimIdHash(tx3.GetHash(), 0), 3, pclaimTrie->nCurrentHeight);
|
||||
cache.addSupport("AB", COutPoint(sx1.GetHash(), 0), 1, ClaimIdHash(tx1.GetHash(), 0), pclaimTrie->nCurrentHeight);
|
||||
cache.addSupport("Ab", COutPoint(sx2.GetHash(), 0), 1, ClaimIdHash(tx2.GetHash(), 0), pclaimTrie->nCurrentHeight);
|
||||
insertUndoType insertUndo;
|
||||
claimQueueRowType expireUndo;
|
||||
insertUndoType insertSupportUndo;
|
||||
supportQueueRowType expireSupportUndo;
|
||||
std::vector<std::pair<std::string, int> > takeoverHeightUndo;
|
||||
BOOST_CHECK(cache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverHeightUndo));
|
||||
BOOST_CHECK(cache.getClaimsForName("ab").claims.size() == 3U);
|
||||
BOOST_CHECK(cache.getClaimsForName("ab").supports.size() == 2U);
|
||||
BOOST_CHECK(cache.decrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverHeightUndo));
|
||||
BOOST_CHECK(cache.undoAddSupport("AB", COutPoint(sx1.GetHash(), 0), pclaimTrie->nCurrentHeight));
|
||||
BOOST_CHECK(cache.undoAddSupport("Ab", COutPoint(sx2.GetHash(), 0), pclaimTrie->nCurrentHeight));
|
||||
BOOST_CHECK(cache.undoAddClaim("AB", COutPoint(tx1.GetHash(), 0), pclaimTrie->nCurrentHeight));
|
||||
BOOST_CHECK(cache.undoAddClaim("Ab", COutPoint(tx2.GetHash(), 0), pclaimTrie->nCurrentHeight));
|
||||
BOOST_CHECK(cache.undoAddClaim("aB", COutPoint(tx3.GetHash(), 0), pclaimTrie->nCurrentHeight));
|
||||
BOOST_CHECK(cache.getClaimsForName("ab").claims.size() == 0U);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalization_does_not_kill_supports) {
|
||||
ClaimTrieChainFixture fixture;
|
||||
fixture.setNormalizationForkHeight(3);
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "1", 1);
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), tx1, "A", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("A", 2));
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), tx1, "A", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("A", 3));
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), tx1, "A", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("a", 4));
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), tx1, "A", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("a", 5));
|
||||
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("a", 4));
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("A", 3));
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("A", 2));
|
||||
fixture.IncrementBlocks(5);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("a", 3));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalization_does_not_fail_on_spend) {
|
||||
ClaimTrieChainFixture fixture;
|
||||
fixture.setNormalizationForkHeight(2);
|
||||
|
||||
std::string sName1("testN");
|
||||
std::string sName2("testn");
|
||||
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, "1", 3);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim(sName1, tx1));
|
||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), sName1, "2", 2);
|
||||
CMutableTransaction tx1s = fixture.MakeSupport(fixture.GetCoinbase(), tx1, sName1, 2);
|
||||
fixture.IncrementBlocks(2, true);
|
||||
BOOST_CHECK(is_best_claim(sName2, tx1));
|
||||
|
||||
CMutableTransaction tx3 = fixture.Spend(tx1); // abandon the claim
|
||||
CMutableTransaction tx3s = fixture.Spend(tx1s);
|
||||
fixture.IncrementBlocks(2);
|
||||
BOOST_CHECK(is_best_claim(sName2, tx2));
|
||||
fixture.DecrementBlocks();
|
||||
BOOST_CHECK(is_best_claim(sName1, tx1));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalization_does_not_kill_sort_order) {
|
||||
ClaimTrieChainFixture fixture;
|
||||
fixture.setNormalizationForkHeight(2);
|
||||
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "1", 1);
|
||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "2", 2);
|
||||
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "a", "3", 3);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("A", tx2));
|
||||
BOOST_CHECK(is_best_claim("a", tx3));
|
||||
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(!is_best_claim("A", tx2));
|
||||
BOOST_CHECK(is_best_claim("a", tx3));
|
||||
BOOST_CHECK(pclaimTrie->getClaimsForName("a").size() == 3U);
|
||||
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(is_best_claim("A", tx2));
|
||||
BOOST_CHECK(is_best_claim("a", tx3));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(normalization_does_not_kill_expirations) {
|
||||
ClaimTrieChainFixture fixture;
|
||||
pclaimTrie->setExpirationTime(3);
|
||||
fixture.setNormalizationForkHeight(4);
|
||||
// need to see that claims expiring on the frame when we normalize aren't kept
|
||||
// need to see that supports expiring on the frame when we normalize aren't kept
|
||||
// need to see that claims & supports carried through the normalization fork do expire
|
||||
// and that they come back correctly when we roll backwards
|
||||
|
||||
CMutableTransaction tx1 = fixture.MakeClaim(fixture.GetCoinbase(), "A", "1", 1);
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), tx1, "A", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("A", 2));
|
||||
|
||||
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "B", "1", 1);
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), tx2, "B", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("A", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("B", 2));
|
||||
|
||||
CMutableTransaction tx3 = fixture.MakeClaim(fixture.GetCoinbase(), "C", "1", 1);
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), tx3, "C", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("A", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("B", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("C", 2));
|
||||
|
||||
CMutableTransaction tx4 = fixture.MakeClaim(fixture.GetCoinbase(), "D", "1", 1);
|
||||
fixture.MakeSupport(fixture.GetCoinbase(), tx4, "D", 1);
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("a", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("b", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("c", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("d", 2));
|
||||
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("a", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("b", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("c", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("d", 2));
|
||||
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("a", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("b", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("c", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("d", 2));
|
||||
|
||||
fixture.IncrementBlocks(1);
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("a", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("b", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("c", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("d", 2));
|
||||
|
||||
fixture.DecrementBlocks(2);
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("a", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("b", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("c", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("d", 2));
|
||||
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("a", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("b", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("c", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("d", 2));
|
||||
|
||||
fixture.DecrementBlocks(1);
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("A", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("B", 2));
|
||||
BOOST_CHECK(best_claim_effective_amount_equals("C", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("d", 2));
|
||||
|
||||
fixture.IncrementBlocks(3);
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("a", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("b", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("c", 2));
|
||||
BOOST_CHECK(!best_claim_effective_amount_equals("d", 2)); // (not re-added)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3368,14 +3732,14 @@ BOOST_AUTO_TEST_CASE(getclaimsintrie_test)
|
|||
|
||||
UniValue results = getclaimsintrie(params, false);
|
||||
BOOST_CHECK(results.size() == 2U);
|
||||
BOOST_CHECK(results[0]["name"].get_str() == sName1);
|
||||
BOOST_CHECK(results[1]["name"].get_str() == sName2);
|
||||
BOOST_CHECK(results[0]["normalized_name"].get_str() == sName1);
|
||||
BOOST_CHECK(results[1]["normalized_name"].get_str() == sName2);
|
||||
|
||||
params.push_back(blockHash.GetHex());
|
||||
|
||||
results = getclaimsintrie(params, false);
|
||||
BOOST_CHECK(results.size() == 1U);
|
||||
BOOST_CHECK(results[0]["name"].get_str() == sName1);
|
||||
BOOST_CHECK(results[0]["normalized_name"].get_str() == sName1);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(getclaimsintrie_test2)
|
||||
|
@ -3493,12 +3857,10 @@ BOOST_AUTO_TEST_CASE(getclaimsforname_test)
|
|||
|
||||
UniValue results = getclaimsforname(params, false);
|
||||
UniValue claims = results["claims"];
|
||||
BOOST_CHECK(claims.size() == 2U);
|
||||
BOOST_CHECK(claims.size() == 1U);
|
||||
BOOST_CHECK(results["nLastTakeoverHeight"].get_int() == height + 1);
|
||||
BOOST_CHECK(claims[0]["nEffectiveAmount"].get_int() == 0);
|
||||
BOOST_CHECK(claims[1]["nEffectiveAmount"].get_int() == 2);
|
||||
BOOST_CHECK(claims[0]["nEffectiveAmount"].get_int() == 2);
|
||||
BOOST_CHECK(claims[0]["supports"].size() == 0U);
|
||||
BOOST_CHECK(claims[1]["supports"].size() == 0U);
|
||||
|
||||
fixture.IncrementBlocks(1);
|
||||
|
||||
|
|
|
@ -39,6 +39,14 @@ public:
|
|||
return cache.find(key);
|
||||
}
|
||||
|
||||
bool insertClaimIntoTrie(const std::string& name, CClaimValue claim,
|
||||
bool fCheckTakeover = false) const {
|
||||
return CClaimTrieCache::insertClaimIntoTrie(name, claim, fCheckTakeover);
|
||||
}
|
||||
bool removeClaimFromTrie(const std::string& name, const COutPoint& outPoint,
|
||||
CClaimValue& claim, bool fCheckTakeover = false) const {
|
||||
return CClaimTrieCache::removeClaimFromTrie(name, outPoint, claim, fCheckTakeover);
|
||||
}
|
||||
};
|
||||
|
||||
CMutableTransaction BuildTransaction(const uint256& prevhash)
|
||||
|
@ -106,7 +114,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
|
|||
|
||||
BOOST_CHECK(pclaimTrie->empty());
|
||||
|
||||
CClaimTrieCache ntState(pclaimTrie, false);
|
||||
CClaimTrieCacheTest ntState(pclaimTrie);
|
||||
ntState.insertClaimIntoTrie(std::string("test"), CClaimValue(tx1OutPoint, hash160, 50, 100, 200));
|
||||
ntState.insertClaimIntoTrie(std::string("test2"), CClaimValue(tx2OutPoint, hash160, 50, 100, 200));
|
||||
|
||||
|
@ -127,7 +135,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
|
|||
BOOST_CHECK(pclaimTrie->getMerkleHash() == hash2);
|
||||
BOOST_CHECK(pclaimTrie->checkConsistency());
|
||||
|
||||
CClaimTrieCache ntState1(pclaimTrie, false);
|
||||
CClaimTrieCacheTest ntState1(pclaimTrie);
|
||||
ntState1.removeClaimFromTrie(std::string("test"), tx1OutPoint, unused);
|
||||
ntState1.removeClaimFromTrie(std::string("test2"), tx2OutPoint, unused);
|
||||
ntState1.removeClaimFromTrie(std::string("test"), tx3OutPoint, unused);
|
||||
|
@ -135,7 +143,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
|
|||
|
||||
BOOST_CHECK(ntState1.getMerkleHash() == hash0);
|
||||
|
||||
CClaimTrieCache ntState2(pclaimTrie, false);
|
||||
CClaimTrieCacheTest ntState2(pclaimTrie);
|
||||
ntState2.insertClaimIntoTrie(std::string("abab"), CClaimValue(tx6OutPoint, hash160, 50, 100, 200));
|
||||
ntState2.removeClaimFromTrie(std::string("test"), tx1OutPoint, unused);
|
||||
|
||||
|
@ -147,7 +155,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
|
|||
BOOST_CHECK(pclaimTrie->getMerkleHash() == hash3);
|
||||
BOOST_CHECK(pclaimTrie->checkConsistency());
|
||||
|
||||
CClaimTrieCache ntState3(pclaimTrie, false);
|
||||
CClaimTrieCacheTest ntState3(pclaimTrie);
|
||||
ntState3.insertClaimIntoTrie(std::string("test"), CClaimValue(tx1OutPoint, hash160, 50, 100, 200));
|
||||
BOOST_CHECK(ntState3.getMerkleHash() == hash4);
|
||||
ntState3.flush();
|
||||
|
@ -155,7 +163,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
|
|||
BOOST_CHECK(pclaimTrie->getMerkleHash() == hash4);
|
||||
BOOST_CHECK(pclaimTrie->checkConsistency());
|
||||
|
||||
CClaimTrieCache ntState4(pclaimTrie, false);
|
||||
CClaimTrieCacheTest ntState4(pclaimTrie);
|
||||
ntState4.removeClaimFromTrie(std::string("abab"), tx6OutPoint, unused);
|
||||
BOOST_CHECK(ntState4.getMerkleHash() == hash2);
|
||||
ntState4.flush();
|
||||
|
@ -163,7 +171,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
|
|||
BOOST_CHECK(pclaimTrie->getMerkleHash() == hash2);
|
||||
BOOST_CHECK(pclaimTrie->checkConsistency());
|
||||
|
||||
CClaimTrieCache ntState5(pclaimTrie, false);
|
||||
CClaimTrieCacheTest ntState5(pclaimTrie);
|
||||
ntState5.removeClaimFromTrie(std::string("test"), tx3OutPoint, unused);
|
||||
|
||||
BOOST_CHECK(ntState5.getMerkleHash() == hash2);
|
||||
|
@ -172,7 +180,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
|
|||
BOOST_CHECK(pclaimTrie->getMerkleHash() == hash2);
|
||||
BOOST_CHECK(pclaimTrie->checkConsistency());
|
||||
|
||||
CClaimTrieCache ntState6(pclaimTrie, false);
|
||||
CClaimTrieCacheTest ntState6(pclaimTrie);
|
||||
ntState6.insertClaimIntoTrie(std::string("test"), CClaimValue(tx3OutPoint, hash160, 50, 101, 201));
|
||||
|
||||
BOOST_CHECK(ntState6.getMerkleHash() == hash2);
|
||||
|
@ -181,7 +189,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
|
|||
BOOST_CHECK(pclaimTrie->getMerkleHash() == hash2);
|
||||
BOOST_CHECK(pclaimTrie->checkConsistency());
|
||||
|
||||
CClaimTrieCache ntState7(pclaimTrie, false);
|
||||
CClaimTrieCacheTest ntState7(pclaimTrie);
|
||||
ntState7.removeClaimFromTrie(std::string("test"), tx3OutPoint, unused);
|
||||
ntState7.removeClaimFromTrie(std::string("test"), tx1OutPoint, unused);
|
||||
ntState7.removeClaimFromTrie(std::string("tes"), tx4OutPoint, unused);
|
||||
|
@ -201,7 +209,6 @@ BOOST_AUTO_TEST_CASE(basic_insertion_info_test)
|
|||
CClaimTrieCacheTest ctc(pclaimTrie);
|
||||
|
||||
// create and insert claim
|
||||
CClaimValue unused;
|
||||
uint256 hash0(uint256S("0000000000000000000000000000000000000000000000000000000000000001"));
|
||||
CMutableTransaction tx1 = BuildTransaction(hash0);
|
||||
uint160 claimId = ClaimIdHash(tx1.GetHash(), 0);
|
||||
|
@ -270,8 +277,8 @@ BOOST_AUTO_TEST_CASE(recursive_prune_test)
|
|||
BOOST_CHECK_EQUAL(1, cc.cacheSize());
|
||||
nodeCacheType::iterator it = cc.getCache(std::string("t"));
|
||||
BOOST_CHECK_EQUAL(10, it->second->nHeightOfLastTakeover);
|
||||
BOOST_CHECK_EQUAL(1, it->second->claims.size());
|
||||
BOOST_CHECK_EQUAL(0, it->second->children.size());
|
||||
BOOST_CHECK_EQUAL(1U, it->second->claims.size());
|
||||
BOOST_CHECK_EQUAL(0U, it->second->children.size());
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(iteratetrie_test)
|
||||
|
|
|
@ -68,7 +68,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
|
|||
pblocktree = new CBlockTreeDB(1 << 20, true);
|
||||
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
|
||||
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
|
||||
pclaimTrie = new CClaimTrie(true, false, false, 1);
|
||||
pclaimTrie = new CClaimTrie(true, false, 1);
|
||||
InitBlockIndex(chainparams);
|
||||
#ifdef ENABLE_WALLET
|
||||
bool fFirstRun;
|
||||
|
|
Loading…
Add table
Reference in a new issue