diff --git a/.gitignore b/.gitignore index e54a14f63..eb9d0d55c 100755 --- a/.gitignore +++ b/.gitignore @@ -83,6 +83,7 @@ libconftest.dylib* Makefile axe-qt Axe-Qt.app +!/depends/Makefile # Unit-tests Makefile.test @@ -108,9 +109,9 @@ coverage_percent.txt linux-coverage-build linux-build win32-build -qa/pull-tester/tests_config.py -qa/pull-tester/tests_config.ini -qa/cache/* +test/functional/config.ini +test/util/buildenv.py +test/cache/* !src/leveldb*/Makefile diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 000000000..1ebfab7d6 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,144 @@ +image: "ubuntu:bionic" + +variables: + DOCKER_DRIVER: overlay2 + +cache: + # Cache by branch/tag and job name + # Gitlab can't use caches from parent pipelines when doing the first build in a PR, so we use artifacts to copy + # caches into PRs + key: ${CI_COMMIT_REF_SLUG}-${CI_JOB_NAME}${CI_EXTERNAL_PULL_REQUEST_IID} + paths: + - $CI_PROJECT_DIR/cache + +stages: + - build + +.build_template: &build_template + stage: build + before_script: + - export BUILD_TARGET="$CI_JOB_NAME" + - echo BUILD_TARGET=$BUILD_TARGET + - source ./ci/matrix.sh + + # The ubuntu base image has apt configured to delete caches after each invocation, which is something that is not desirable for us + - rm /etc/apt/apt.conf.d/docker-clean + - apt-get update + - apt-get install -y wget unzip + + # Init cache + - export CACHE_DIR=$CI_PROJECT_DIR/cache + - mkdir -p $CACHE_DIR + - | + if [ "$CI_COMMIT_REF_SLUG" != "development" -a "$CI_COMMIT_TAG" == "" ]; then + if [ ! -d $CACHE_DIR/ccache ]; then + echo "Downloading cache from development branch" + mkdir cache-artifact + cd cache-artifact + if wget --quiet -O cache-artifact.zip https://gitlab.com/$CI_PROJECT_NAMESPACE/$CI_PROJECT_NAME/-/jobs/artifacts/development/download?job=$CI_JOB_NAME; then + unzip -q cache-artifact.zip + rm cache-artifact.zip + mv cache-artifact/* $CACHE_DIR/ + else + echo "Failed to download cache" + fi + cd .. + rm -rf cache-artifact + else + echo "Not touching cache (was initialized from previous build)" + fi + else + echo "Not touching cache (building development branch or tag)" + fi + # Create missing cache dirs + - mkdir -p $CACHE_DIR/ccache && mkdir -p $CACHE_DIR/depends && mkdir -p $CACHE_DIR/sdk-sources && mkdir -p $CACHE_DIR/apt + # Keep this as it makes caching related debugging easier + - ls -lah $CACHE_DIR && ls -lah $CACHE_DIR/depends && ls -lah $CACHE_DIR/ccache && ls -lah $CACHE_DIR/apt + - mv $CACHE_DIR/apt/* /var/cache/apt/archives/ || true + + # Install base packages + - apt-get dist-upgrade -y + - apt-get install -y git g++ autotools-dev libtool m4 automake autoconf pkg-config zlib1g-dev libssl1.0-dev curl ccache bsdmainutils cmake + - apt-get install -y python3 python3-dev python3-pip + + # jinja2 is needed for combine_logs.py + - pip3 install jinja2 + + # Setup some environment variables + - if [ "$CI_EXTERNAL_PULL_REQUEST_IID" != "" ]; then export PULL_REQUEST="true"; else export PULL_REQUEST="false"; fi + - export COMMIT_RANGE="$CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA" + - export JOB_NUMBER="$CI_JOB_ID" + - export HOST_SRC_DIR=$CI_PROJECT_DIR + - echo PULL_REQUEST=$PULL_REQUEST COMMIT_RANGE=$COMMIT_RANGE HOST_SRC_DIR=$HOST_SRC_DIR CACHE_DIR=$CACHE_DIR + - echo "Commit log:" && git log --format=fuller -1 + + # Build axe_hash + - git clone https://github.com/axerunners/axe_hash + - cd axe_hash && python3 setup.py install + + # Install build target specific packages + - echo PACKAGES=$PACKAGES + - if [ -n "$DPKG_ADD_ARCH" ]; then dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi + - if [ -n "$PACKAGES" ]; then apt-get update && apt-get install -y --no-install-recommends --no-upgrade $PACKAGES; fi + + # Move apt packages into cache + - mv /var/cache/apt/archives/* $CACHE_DIR/apt/ || true + + # Make mingw use correct threading libraries + - update-alternatives --set i686-w64-mingw32-gcc /usr/bin/i686-w64-mingw32-gcc-posix || true + - update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix || true + - update-alternatives --set x86_64-w64-mingw32-gcc /usr/bin/x86_64-w64-mingw32-gcc-posix || true + - update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix || true + + script: + - export BUILD_TARGET="$CI_JOB_NAME" + - cd $CI_PROJECT_DIR + - ./ci/build_depends.sh + - ./ci/build_src.sh + - ./ci/test_unittests.sh + - ./ci/test_integrationtests.sh + + after_script: + # Copy all cache files into cache-artifact so that they get uploaded. We only do this for development so that artifacts + # stay minimal for PRs and branches (we never need them) + - mkdir -p $CI_PROJECT_DIR/cache-artifact + - mkdir -p $CI_PROJECT_DIR/testlogs + - | + if [ "$CI_COMMIT_REF_SLUG" = "development" ]; then + cp -ra $CI_PROJECT_DIR/cache/* $CI_PROJECT_DIR/cache-artifact/ + fi + + # We're actually only interested in the development branch creating the cache artifact, but there is no way to control this + # until https://gitlab.com/gitlab-org/gitlab-foss/issues/25478 gets implemented. Until then, we use an expiration time of + # 3 days and rely on daily builds to refresh the cache artifacts. We also keep non-development artifacts at minimum size + artifacts: + name: cache-artifact + when: always + paths: + - $CI_PROJECT_DIR/cache-artifact + - $CI_PROJECT_DIR/testlogs + expire_in: 3 days + +arm-linux: + <<: *build_template + +win32: + <<: *build_template + +win64: + <<: *build_template + +linux32: + <<: *build_template + +linux64: + <<: *build_template + +linux64_nowallet: + <<: *build_template + +linux64_release: + <<: *build_template + +mac: + <<: *build_template diff --git a/.travis.yml b/.travis.yml index 56163dff7..de8906694 100755 --- a/.travis.yml +++ b/.travis.yml @@ -6,21 +6,12 @@ sudo: required dist: trusty os: linux -language: generic - -addons: - apt: - packages: - # Use more recent docker version - - docker-ce - # Can be removed if Travis ever upgrades to Bionic - - realpath +language: minimal services: - docker cache: - apt: true ccache: true directories: - $HOME/cache @@ -31,26 +22,108 @@ env: - secure: "xdeQldckRR0Rp+GJr5BV0NRFaR0dGX4469LqAXP8Gn+01ZXtsVuwsereN177nbtRtGcCZYRukrVe9LWvksgWFoHfKuSv82J8TxFRIkXeXbAN1vLJpgQ+MI+iGOt940aiuy8P3eubbHAhqk9kCa9CuQMxtierG7DwgH2ri1zal5Q3x3wQtp0zvq8l36uAma0sGBK9Vz/N+Y+rYc/hAMKUMN8iZ0lt87Vili9hZmpnO7FJ2kkCcD3A24TrD9xnspWxbGO7F6rfWvc6RzbB9X6xQtuzoor7DHPlih93mNmBHjfv5KOwzc8oHY7ry2/54/yGXX9IvANgY3iW24YnyVBCVWaCpRfBG/cgBFbxjfcmaOK2nZHFuaPfpDYc346thQcwu3srPeDJjBaCXaYprrPZWnvaP0OpUcY4M+rxcNcAUY1BmDTa7Fdc1RwbBWJSsdc6qL2XxMR9cZreOYBNN+BWTcZDnnlZ+3zkGcR+P4WUYTvODdqNNj+mm+VwcYxoZzQvtOFyAtsgcEa+47UqFuhczMhU5CocX1fRMdjO0RWWG3A3CenPOMifvyPDSaHe+oPGTpxJTpXw3V5Ceu0gwkSTmMkAx1ZT1qhf7jxcfl9rieCNqF8iQHXOjkiI2mjpI2cK2Ld5IR6V3FNZ2/2MHTs1uGHwVYVoDMUbFCwP2Tcbbes=" - DOCKER_BUILD=false - matrix: - - BUILD_TARGET=arm-linux - - BUILD_TARGET=win32 - - BUILD_TARGET=win64 - - BUILD_TARGET=linux32 - - BUILD_TARGET=linux64 - - BUILD_TARGET=linux64_nowallet - - BUILD_TARGET=linux64_release DOCKER_BUILD=true - - BUILD_TARGET=mac +stages: + - build depends + - build src + - run tests + - build docker + +builddepends: &builddepends + stage: build depends + script: + - $DOCKER_RUN_IN_BUILDER ./ci/build_depends.sh + +buildsrc: &buildsrc + stage: build src + script: + - $DOCKER_RUN_IN_BUILDER ./ci/build_depends.sh + - $DOCKER_RUN_IN_BUILDER ./ci/build_src.sh + +runtests: &runtests + stage: run tests + script: + - $DOCKER_RUN_IN_BUILDER ./ci/build_depends.sh + - $DOCKER_RUN_IN_BUILDER ./ci/build_src.sh + - $DOCKER_RUN_IN_BUILDER ./ci/test_unittests.sh + - if [ "$TRAVIS_EVENT_TYPE" = "cron" ]; then extended="--extended --exclude pruning,dbcrash"; fi + - $DOCKER_RUN_IN_BUILDER ./ci/test_integrationtests.sh --jobs=3 ${extended} + +builddocker: &builddocker + stage: build docker + script: + # no need to run tests again here + - if [ "$DOCKER_BUILD" = "true" ]; then $DOCKER_RUN_IN_BUILDER ./ci/build_depends.sh && $DOCKER_RUN_IN_BUILDER ./ci/build_src.sh && BUILD_DIR=build-ci/axecore-$BUILD_TARGET ./docker/build-docker.sh; fi + +jobs: + include: + # build depends + - <<: *builddepends + env: BUILD_TARGET=arm-linux + - <<: *builddepends + env: BUILD_TARGET=win32 + - <<: *builddepends + env: BUILD_TARGET=win64 + - <<: *builddepends + env: BUILD_TARGET=linux32 + - <<: *builddepends + env: BUILD_TARGET=linux64 + - <<: *builddepends + env: BUILD_TARGET=linux64_nowallet + - <<: *builddepends + env: BUILD_TARGET=linux64_release DOCKER_BUILD=true + - <<: *builddepends + env: BUILD_TARGET=mac + # build source + - <<: *buildsrc + env: BUILD_TARGET=arm-linux + - <<: *buildsrc + env: BUILD_TARGET=win32 + - <<: *buildsrc + env: BUILD_TARGET=win64 + - <<: *buildsrc + env: BUILD_TARGET=linux32 + - <<: *buildsrc + env: BUILD_TARGET=linux64 + - <<: *buildsrc + env: BUILD_TARGET=linux64_nowallet + - <<: *buildsrc + env: BUILD_TARGET=linux64_release DOCKER_BUILD=true + - <<: *buildsrc + env: BUILD_TARGET=mac + # run tests (no tests for arm-linux and mac) + - <<: *runtests + env: BUILD_TARGET=win32 + - <<: *runtests + env: BUILD_TARGET=win64 + - <<: *runtests + env: BUILD_TARGET=linux32 + - <<: *runtests + env: BUILD_TARGET=linux64 + - <<: *runtests + env: BUILD_TARGET=linux64_nowallet + - <<: *runtests + env: BUILD_TARGET=linux64_release DOCKER_BUILD=true + # build docker + - <<: *builddocker + env: BUILD_TARGET=linux64_release DOCKER_BUILD=true before_cache: # Save builder image - docker save axe-builder-$BUILD_TARGET-$TRAVIS_JOB_NUMBER $(docker history -q axe-builder-$BUILD_TARGET-$TRAVIS_JOB_NUMBER | grep -v \) | gzip -2 > $HOME/cache/docker/axe-builder-$BUILD_TARGET.tar.gz +before_install: + - travis_retry travis_apt_get_update + - travis_retry sudo apt-get -yq --no-install-suggests --no-install-recommends install docker-ce realpath + install: # Our scripts try to be Travis agnostic - export PULL_REQUEST="$TRAVIS_PULL_REQUEST" + - export COMMIT_RANGE="$TRAVIS_COMMIT_RANGE" - export JOB_NUMBER="$TRAVIS_JOB_NUMBER" - export HOST_SRC_DIR=$TRAVIS_BUILD_DIR - export HOST_CACHE_DIR=$HOME/cache + - export TRAVIS_COMMIT_LOG=`git log --format=fuller -1` + - export PYTHON_DEBUG=1 - source ./ci/matrix.sh - mkdir -p $HOST_CACHE_DIR/docker && mkdir -p $HOST_CACHE_DIR/ccache && mkdir -p $HOST_CACHE_DIR/depends && mkdir -p $HOST_CACHE_DIR/sdk-sources # Keep this as it makes caching related debugging easier @@ -65,18 +138,6 @@ before_script: - python3 -c 'import os,sys,fcntl; flags = fcntl.fcntl(sys.stdout, fcntl.F_GETFL); fcntl.fcntl(sys.stdout, fcntl.F_SETFL, flags&~os.O_NONBLOCK);' # Build docker image only for development branch of the main repo - if [ "$TRAVIS_REPO_SLUG" != "axerunners/axe" -o "$TRAVIS_BRANCH" != "development" -o "$TRAVIS_PULL_REQUEST" != "false" ]; then export DOCKER_BUILD="false"; echo DOCKER_BUILD=$DOCKER_BUILD; fi -script: - - export TRAVIS_COMMIT_LOG=`git log --format=fuller -1` - # Our scripts try to be Travis agnostic - - $DOCKER_RUN_IN_BUILDER ./ci/build_depends.sh; - # Gracefully stop build without running into timeouts (which won't update caches) when building depends or source took too long - # Next build should fix this situation as it will start with a populated cache - - if [ $SECONDS -gt 1200 ]; then export TIMEOUT="true"; false; fi # The "false" here ensures that the build is marked as failed even though the whole script returns 0 - - test "$TIMEOUT" != "true" && $DOCKER_RUN_IN_BUILDER ./ci/build_src.sh - - test "$TIMEOUT" != "true" && $DOCKER_RUN_IN_BUILDER ./ci/test_unittests.sh - - if [ $SECONDS -gt 1800 -a "$RUN_INTEGRATIONTESTS" = "true" ]; then export TIMEOUT="true"; false; fi # The "false" here ensures that the build is marked as failed even though the whole script returns 0 - - test "$TIMEOUT" != "true" && $DOCKER_RUN_IN_BUILDER ./ci/test_integrationtests.sh --jobs=3 - - test "$TIMEOUT" != "true" && if [ "$DOCKER_BUILD" = "true" ]; then BUILD_DIR=build-ci/axecore-$BUILD_TARGET ./docker/build-docker.sh; fi after_script: - echo $TRAVIS_COMMIT_RANGE - echo $TRAVIS_COMMIT_LOG diff --git a/INSTALL.md b/INSTALL.md index d6e1a23bc..51176a998 100755 --- a/INSTALL.md +++ b/INSTALL.md @@ -2,4 +2,4 @@ Building AXE ============= See doc/build-*.md for instructions on building the various -elements of the AXE Core reference implementation of AXE. +elements of the Axe Core reference implementation of AXE. diff --git a/Makefile.am b/Makefile.am index 2620c7dee..95ab15388 100755 --- a/Makefile.am +++ b/Makefile.am @@ -61,7 +61,7 @@ OSX_PACKAGING = $(OSX_DEPLOY_SCRIPT) $(OSX_FANCY_PLIST) $(OSX_INSTALLER_ICONS) \ COVERAGE_INFO = baseline_filtered_combined.info baseline.info \ leveldb_baseline.info test_axe_filtered.info total_coverage.info \ - baseline_filtered.info rpc_test.info rpc_test_filtered.info \ + baseline_filtered.info functional_test.info functional_test_filtered.info \ leveldb_baseline_filtered.info test_axe_coverage.info test_axe.info dist-hook: @@ -82,7 +82,7 @@ $(OSX_APP)/Contents/PkgInfo: $(OSX_APP)/Contents/Resources/empty.lproj: $(MKDIR_P) $(@D) - @touch $@ + @touch $@ $(OSX_APP)/Contents/Info.plist: $(OSX_PLIST) $(MKDIR_P) $(@D) @@ -191,20 +191,20 @@ test_axe.info: baseline_filtered_combined.info test_axe_filtered.info: test_axe.info $(LCOV) -r $< "/usr/include/*" -o $@ -rpc_test.info: test_axe_filtered.info - -@TIMEOUT=15 python qa/pull-tester/rpc-tests.py $(EXTENDED_RPC_TESTS) - $(LCOV) -c -d $(abs_builddir)/src --t rpc-tests -o $@ +functional_test.info: test_axe_filtered.info + -@TIMEOUT=15 python test/functional/test_runner.py $(EXTENDED_FUNCTIONAL_TESTS) + $(LCOV) -c -d $(abs_builddir)/src --t functional-tests -o $@ $(LCOV) -z -d $(abs_builddir)/src $(LCOV) -z -d $(abs_builddir)/src/leveldb -rpc_test_filtered.info: rpc_test.info +functional_test_filtered.info: functional_test.info $(LCOV) -r $< "/usr/include/*" -o $@ test_axe_coverage.info: baseline_filtered_combined.info test_axe_filtered.info $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_axe_filtered.info -o $@ -total_coverage.info: baseline_filtered_combined.info test_axe_filtered.info rpc_test_filtered.info - $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_axe_filtered.info -a rpc_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt +total_coverage.info: baseline_filtered_combined.info test_axe_filtered.info functional_test_filtered.info + $(LCOV) -a baseline_filtered.info -a leveldb_baseline_filtered.info -a test_axe_filtered.info -a functional_test_filtered.info -o $@ | $(GREP) "\%" | $(AWK) '{ print substr($$3,2,50) "/" $$5 }' > coverage_percent.txt test_axe.coverage/.dirstamp: test_axe_coverage.info $(GENHTML) -s $< -o $(@D) @@ -220,14 +220,58 @@ endif dist_noinst_SCRIPTS = autogen.sh -EXTRA_DIST = $(top_srcdir)/share/genbuild.sh qa/pull-tester/rpc-tests.py qa/rpc-tests $(DIST_CONTRIB) $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) +EXTRA_DIST = $(top_srcdir)/share/genbuild.sh test/functional/test_runner.py test/functional $(DIST_CONTRIB) $(DIST_DOCS) $(WINDOWS_PACKAGING) $(OSX_PACKAGING) $(BIN_CHECKS) + +EXTRA_DIST += \ + test/util/bctest.py \ + test/util/bitcoin-util-test.py \ + test/util/data/bitcoin-util-test.json \ + test/util/data/blanktxv1.hex \ + test/util/data/blanktxv1.json \ + test/util/data/blanktxv2.hex \ + test/util/data/blanktxv2.json \ + test/util/data/tt-delin1-out.hex \ + test/util/data/tt-delin1-out.json \ + test/util/data/tt-delout1-out.hex \ + test/util/data/tt-delout1-out.json \ + test/util/data/tt-locktime317000-out.hex \ + test/util/data/tt-locktime317000-out.json \ + test/util/data/tx394b54bb.hex \ + test/util/data/txcreate1.hex \ + test/util/data/txcreate1.json \ + test/util/data/txcreate2.hex \ + test/util/data/txcreate2.json \ + test/util/data/txcreatedata1.hex \ + test/util/data/txcreatedata1.json \ + test/util/data/txcreatedata2.hex \ + test/util/data/txcreatedata2.json \ + test/util/data/txcreatedata_seq0.hex \ + test/util/data/txcreatedata_seq0.json \ + test/util/data/txcreatedata_seq1.hex \ + test/util/data/txcreatedata_seq1.json \ + test/util/data/txcreatemultisig1.hex \ + test/util/data/txcreatemultisig1.json \ + test/util/data/txcreatemultisig2.hex \ + test/util/data/txcreatemultisig2.json \ + test/util/data/txcreateoutpubkey1.hex \ + test/util/data/txcreateoutpubkey1.json \ + test/util/data/txcreatescript1.hex \ + test/util/data/txcreatescript1.json \ + test/util/data/txcreatescript2.hex \ + test/util/data/txcreatescript2.json \ + test/util/data/txcreatesignv1.hex \ + test/util/data/txcreatesignv1.json \ + test/util/data/txcreatesignv2.hex CLEANFILES = $(OSX_DMG) $(BITCOIN_WIN_INSTALLER) +# This file is problematic for out-of-tree builds if it exists. +DISTCLEANFILES = test/util/buildenv.pyc + .INTERMEDIATE: $(COVERAGE_INFO) DISTCHECK_CONFIGURE_FLAGS = --enable-man clean-local: - rm -rf coverage_percent.txt test_axe.coverage/ total.coverage/ qa/tmp/ cache/ $(OSX_APP) - rm -rf qa/pull-tester/__pycache__ + rm -rf coverage_percent.txt test_axe.coverage/ total.coverage/ test/tmp/ cache/ $(OSX_APP) + rm -rf test/functional/__pycache__ diff --git a/.github/README.md b/README.md similarity index 100% rename from .github/README.md rename to README.md diff --git a/build-aux/m4/bitcoin_qt.m4 b/build-aux/m4/bitcoin_qt.m4 index e5a781227..aeff28595 100755 --- a/build-aux/m4/bitcoin_qt.m4 +++ b/build-aux/m4/bitcoin_qt.m4 @@ -130,6 +130,8 @@ AC_DEFUN([BITCOIN_QT_CONFIGURE],[ if test "x$bitcoin_cv_need_acc_widget" = "xyes"; then _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(AccessibleFactory)], [-lqtaccessiblewidgets]) fi + _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin)],[-lqminimal]) + AC_DEFINE(QT_QPA_PLATFORM_MINIMAL, 1, [Define this symbol if the minimal qt platform exists]) if test x$TARGET_OS = xwindows; then _BITCOIN_QT_CHECK_STATIC_PLUGINS([Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin)],[-lqwindows]) AC_DEFINE(QT_QPA_PLATFORM_WINDOWS, 1, [Define this symbol if the qt platform is windows]) diff --git a/ci/Dockerfile.builder b/ci/Dockerfile.builder index 7b64c5e9f..bd7037fe0 100755 --- a/ci/Dockerfile.builder +++ b/ci/Dockerfile.builder @@ -14,6 +14,7 @@ RUN apt-get update && apt-get install -y python3-pip # Python stuff RUN pip3 install pyzmq # really needed? +RUN pip3 install jinja2 # axe_hash RUN git clone https://github.com/axerunners/axe_hash diff --git a/ci/build_src.sh b/ci/build_src.sh index 5380ef189..6b46c15c7 100755 --- a/ci/build_src.sh +++ b/ci/build_src.sh @@ -12,6 +12,8 @@ unset DISPLAY export CCACHE_COMPRESS=${CCACHE_COMPRESS:-1} export CCACHE_SIZE=${CCACHE_SIZE:-400M} +if [ "$PULL_REQUEST" != "false" ]; then contrib/devtools/commit-script-check.sh $COMMIT_RANGE; fi + #if [ "$CHECK_DOC" = 1 ]; then contrib/devtools/check-doc.py; fi TODO reenable after all Bitcoin PRs have been merged and docs fully fixed depends/$HOST/native/bin/ccache --max-size=$CCACHE_SIZE diff --git a/ci/matrix.sh b/ci/matrix.sh index 37ed7684a..a1133d0d6 100755 --- a/ci/matrix.sh +++ b/ci/matrix.sh @@ -20,14 +20,13 @@ export CACHE_DIR=${CACHE_DIR:-$HOST_CACHE_DIR} export CCACHE_DIR=$CACHE_DIR/ccache export DOCKER_RUN_VOLUME_ARGS="-v $HOST_SRC_DIR:$SRC_DIR -v $HOST_CACHE_DIR:$CACHE_DIR" -export DOCKER_RUN_ENV_ARGS="-e SRC_DIR=$SRC_DIR -e CACHE_DIR=$CACHE_DIR -e PULL_REQUEST=$PULL_REQUEST -e JOB_NUMBER=$JOB_NUMBER -e BUILD_TARGET=$BUILD_TARGET" +export DOCKER_RUN_ENV_ARGS="-e SRC_DIR=$SRC_DIR -e CACHE_DIR=$CACHE_DIR -e PULL_REQUEST=$PULL_REQUEST -e COMMIT_RANGE=$COMMIT_RANGE -e JOB_NUMBER=$JOB_NUMBER -e BUILD_TARGET=$BUILD_TARGET" export DOCKER_RUN_ARGS="$DOCKER_RUN_VOLUME_ARGS $DOCKER_RUN_ENV_ARGS" export DOCKER_RUN_IN_BUILDER="docker run -t --rm -w $SRC_DIR $DOCKER_RUN_ARGS $BUILDER_IMAGE_NAME" # Default values for targets export GOAL="install" export SDK_URL=${SDK_URL:-https://bitcoincore.org/depends-sources/sdks} -export PYTHON_DEBUG=1 export MAKEJOBS="-j4" export RUN_UNITTESTS=false @@ -71,7 +70,7 @@ elif [ "$BUILD_TARGET" = "linux64" ]; then export RUN_INTEGRATIONTESTS=true elif [ "$BUILD_TARGET" = "linux64_nowallet" ]; then export HOST=x86_64-unknown-linux-gnu - export PACKAGES="python3" + export PACKAGES="python3 xvfb" export DEP_OPTS="NO_WALLET=1" export BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports" export RUN_UNITTESTS=true diff --git a/ci/test_integrationtests.sh b/ci/test_integrationtests.sh index abdb8ec47..fd95bde0e 100755 --- a/ci/test_integrationtests.sh +++ b/ci/test_integrationtests.sh @@ -17,4 +17,4 @@ export LD_LIBRARY_PATH=$BUILD_DIR/depends/$HOST/lib cd build-ci/axecore-$BUILD_TARGET -#./qa/pull-tester/rpc-tests.py --coverage $PASS_ARGS +#./test/functional/test_runner.py --coverage $PASS_ARGS diff --git a/ci/test_unittests.sh b/ci/test_unittests.sh index fe1538b61..cb0b46f5b 100755 --- a/ci/test_unittests.sh +++ b/ci/test_unittests.sh @@ -19,6 +19,12 @@ export WINEDEBUG=fixme-all export BOOST_TEST_LOG_LEVEL=test_suite cd build-ci/axecore-$BUILD_TARGET + +if [ "$RUN_TESTS" = "true" -a "${DEP_OPTS#*NO_QT=1}" = "$DEP_OPTS" ]; then + export DISPLAY=:99.0; + /sbin/start-stop-daemon --start --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac; +fi + if [ "$DIRECT_WINE_EXEC_TESTS" = "true" ]; then # Inside Docker, binfmt isn't working so we can't trust in make invoking windows binaries correctly wine ./src/test/test_axe.exe diff --git a/configure.ac b/configure.ac index c1ebb2b1a..61dbdb69e 100755 --- a/configure.ac +++ b/configure.ac @@ -2,8 +2,8 @@ dnl require autoconf 2.60 (AS_ECHO/AS_ECHO_N) AC_PREREQ([2.60]) define(_CLIENT_VERSION_MAJOR, 1) define(_CLIENT_VERSION_MINOR, 4) -define(_CLIENT_VERSION_REVISION, 0) -define(_CLIENT_VERSION_BUILD, 2) +define(_CLIENT_VERSION_REVISION, 1) +define(_CLIENT_VERSION_BUILD, 0) define(_CLIENT_VERSION_IS_RELEASE, true) define(_COPYRIGHT_YEAR, 2019) define(_COPYRIGHT_HOLDERS,[The %s developers]) @@ -124,10 +124,10 @@ AC_ARG_ENABLE(bench, [use_bench=$enableval], [use_bench=yes]) -AC_ARG_ENABLE([extended-rpc-tests], - AS_HELP_STRING([--enable-extended-rpc-tests],[enable expensive RPC tests when using lcov (default no)]), - [use_extended_rpc_tests=$enableval], - [use_extended_rpc_tests=no]) +AC_ARG_ENABLE([extended-functional-tests], + AS_HELP_STRING([--enable-extended-functional-tests],[enable expensive functional tests when using lcov (default no)]), + [use_extended_functional_tests=$enableval], + [use_extended_functional_tests=no]) AC_ARG_WITH([qrencode], [AS_HELP_STRING([--with-qrencode], @@ -459,8 +459,8 @@ if test x$use_pkgconfig = xyes; then ]) fi -if test x$use_extended_rpc_tests != xno; then - AC_SUBST(EXTENDED_RPC_TESTS, -extended) +if test x$use_extended_functional_tests != xno; then + AC_SUBST(EXTENDED_FUNCTIONAL_TESTS, --extended) fi if test x$use_lcov = xyes; then @@ -603,6 +603,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT(no)] ) +dnl Check for MSG_DONTWAIT +AC_MSG_CHECKING(for MSG_DONTWAIT) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ int f = MSG_DONTWAIT; ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_DONTWAIT, 1,[Define this symbol if you have MSG_DONTWAIT]) ], + [ AC_MSG_RESULT(no)] +) + dnl Check for mallopt(M_ARENA_MAX) (to set glibc arenas) AC_MSG_CHECKING(for mallopt M_ARENA_MAX) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], @@ -611,6 +619,14 @@ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [ AC_MSG_RESULT(no)] ) +dnl Check for malloc_info (for memory statistics information in getmemoryinfo) +AC_MSG_CHECKING(for getmemoryinfo) +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], + [[ int f = malloc_info(0, NULL); ]])], + [ AC_MSG_RESULT(yes); AC_DEFINE(HAVE_MALLOC_INFO, 1,[Define this symbol if you have malloc_info]) ], + [ AC_MSG_RESULT(no)] +) + AC_MSG_CHECKING([for visibility attribute]) AC_LINK_IFELSE([AC_LANG_SOURCE([ int foo_def( void ) __attribute__((visibility("default"))); @@ -1184,10 +1200,12 @@ AC_SUBST(EVENT_PTHREADS_LIBS) AC_SUBST(ZMQ_LIBS) AC_SUBST(PROTOBUF_LIBS) AC_SUBST(QR_LIBS) -AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist src/test/buildenv.py]) -AC_CONFIG_FILES([qa/pull-tester/tests_config.ini],[chmod +x qa/pull-tester/tests_config.ini]) +AC_CONFIG_FILES([Makefile src/Makefile doc/man/Makefile share/setup.nsi share/qt/Info.plist test/functional/config.ini]) +AC_CONFIG_FILES([test/util/buildenv.py],[chmod +x test/util/buildenv.py]) AC_CONFIG_FILES([contrib/devtools/split-debug.sh],[chmod +x contrib/devtools/split-debug.sh]) -AC_CONFIG_LINKS([qa/pull-tester/rpc-tests.py:qa/pull-tester/rpc-tests.py]) +AC_CONFIG_LINKS([test/functional/test_runner.py:test/functional/test_runner.py]) +AC_CONFIG_LINKS([test/util/bitcoin-util-test.py:test/util/bitcoin-util-test.py]) +AC_CONFIG_LINKS([test/util/bctest.py:test/util/bctest.py]) dnl boost's m4 checks do something really nasty: they export these vars. As a dnl result, they leak into secp256k1's configure and crazy things happen. @@ -1235,8 +1253,8 @@ esac dnl Replace the BUILDDIR path with the correct Windows path if compiling on Native Windows case ${OS} in *Windows*) - sed 's/BUILDDIR="\/\([[a-z]]\)/BUILDDIR="\1:/' qa/pull-tester/tests_config.py > qa/pull-tester/tests_config-2.py - mv qa/pull-tester/tests_config-2.py qa/pull-tester/tests_config.py + sed 's/BUILDDIR="\/\([[a-z]]\)/BUILDDIR="\1:/' test/functional/config.ini > test/functional/config-2.ini + mv test/functional/config-2.ini test/functional/config.ini ;; esac diff --git a/contrib/devtools/commit-script-check.sh b/contrib/devtools/commit-script-check.sh new file mode 100755 index 000000000..1c9dbc7f6 --- /dev/null +++ b/contrib/devtools/commit-script-check.sh @@ -0,0 +1,46 @@ +#!/bin/sh +# Copyright (c) 2017 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. + +# This simple script checks for commits beginning with: scripted-diff: +# If found, looks for a script between the lines -BEGIN VERIFY SCRIPT- and +# -END VERIFY SCRIPT-. If no ending is found, it reads until the end of the +# commit message. + +# The resulting script should exactly transform the previous commit into the current +# one. Any remaining diff signals an error. + +if test "x$1" = "x"; then + echo "Usage: $0 ..." + exit 1 +fi + +RET=0 +PREV_BRANCH=`git name-rev --name-only HEAD` +PREV_HEAD=`git rev-parse HEAD` +for i in `git rev-list --reverse $1`; do + if git rev-list -n 1 --pretty="%s" $i | grep -q "^scripted-diff:"; then + git checkout --quiet $i^ || exit + SCRIPT="`git rev-list --format=%b -n1 $i | sed '/^-BEGIN VERIFY SCRIPT-$/,/^-END VERIFY SCRIPT-$/{//!b};d'`" + if test "x$SCRIPT" = "x"; then + echo "Error: missing script for: $i" + echo "Failed" + RET=1 + else + echo "Running script for: $i" + echo "$SCRIPT" + eval "$SCRIPT" + git --no-pager diff --exit-code $i && echo "OK" || (echo "Failed"; false) || RET=1 + fi + git reset --quiet --hard HEAD + else + if git rev-list "--format=%b" -n1 $i | grep -q '^-\(BEGIN\|END\)[ a-zA-Z]*-$'; then + echo "Error: script block marker but no scripted-diff in title" + echo "Failed" + RET=1 + fi + fi +done +git checkout --quiet $PREV_BRANCH 2>/dev/null || git checkout --quiet $PREV_HEAD +exit $RET diff --git a/contrib/devtools/copyright_header.py b/contrib/devtools/copyright_header.py index 440000084..d045d836d 100755 --- a/contrib/devtools/copyright_header.py +++ b/contrib/devtools/copyright_header.py @@ -34,7 +34,7 @@ 'src/tinyformat.h', 'src/leveldb/util/env_win.cc', 'src/crypto/ctaes/bench.c', - 'qa/rpc-tests/test_framework/bignum.py', + 'test/functional/test_framework/bignum.py', # python init: '*__init__.py', ] diff --git a/contrib/gitian-descriptors/gitian-win-signer.yml b/contrib/gitian-descriptors/gitian-win-signer.yml index 5e99c00f4..660ba519b 100644 --- a/contrib/gitian-descriptors/gitian-win-signer.yml +++ b/contrib/gitian-descriptors/gitian-win-signer.yml @@ -5,7 +5,8 @@ suites: architectures: - "amd64" packages: -- "libssl-dev" +# Once osslsigncode supports openssl 1.1, we can change this back to libssl-dev +- "libssl1.0-dev" - "autoconf" remotes: - "url": "https://github.com/axerunners/axe-detached-sigs.git" diff --git a/contrib/gitian-keys/sparkuss.pgp b/contrib/gitian-keys/sparkuss.pgp new file mode 100644 index 000000000..d4e3928e6 --- /dev/null +++ b/contrib/gitian-keys/sparkuss.pgp @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +mQINBF0ocVoBEAChDJXKXrj4xlF0yu9DuG/fL3JpZRTRbS1ixbmulPthK2ViFQeB +UmNXbrRVPM3BRkjJFrwstB0wmprMBTyhyPxF7h1toJ5fdCU+5ybTcxW+XKusOhzp +PxdGxg5EGgKxGlKBv2zgbHymRYY129Kdnh5iyc+ewp72iWIxdTjksWuieBRWGU7j +tHObeuhZs4frx+UXwLc3hrXMhY859IAIzgmUv4thq1YmTAX0naHTp5Tgxn5lyg7g +5XvKK5UFOXUa6kUc3DC/cMjYtX5khbTmiE8LWArc89M6ImnW1TG1rSdQlZfEn4i9 +OjM6MJx+wrYgdUD3ttpaW8K+FBnfxvxN5IIPA8lvBB/dAm2aN1dMOGTjbBlqIRy2 +MAKWN+5M/tN4QfWsLVbRfoIjKaJxLZluS+ngDQ1mu59aF+bx5A2uWPOcPEDP/1zu +B89mQT+RVjC1izugRr5AP+GjX8sMLIA5sdb6Dy4188s1rQKWMmBEMJ6sHuxRYnMu +a/2fpC6IhvER1+4U/z6XYNRe4AaNxfZpVPEPZ01Xm+i2tGUrgoTKZTMOlPII9JN5 +MjNZ7F9qYVw5aAG3ySY1pe2ZdJejQB+rS3fBdF/+g4sVvK+tiw59P1QGwLLFTS2y +SX6ZB/YeMGufp88JSbZa6fnURlf+UwUuqiMjs8n37PzWFm+mphfo1NrL7wARAQAB +tCBTcGFya3VzcyA8c3Bhcmt1c3NkZXZAZ21haWwuY29tPokCTgQTAQoAOBYhBABe +1QEhA4WfEnn4WJOoS55AM/bYBQJdKHFaAhsDBQsJCAcCBhUKCQgLAgQWAgMBAh4B +AheAAAoJEJOoS55AM/bY/XMP/2/E6PieaEvGb1jxyVD2LjiR1/kh7fAq6yHYYJKu +RSffxpF584GOZErGi4MxBb67fwqFP6pUcrb8ugKcZE3ODVM1XGetyfaFJ0JNTvG6 +8P9AufcJoWjj1C3HT4qFGq9oLg+QoQ8jlC2W1Jy+WsjAempeos51+Qboh56ASbYX +hcoFVr1QDFzk41Mknc+sZ5e/sW9ZyPDWsxRxHLENaJEOoWlMly1uiwBHyHQOEjFp +Q7JcYvBkJllR961Bc9qJsw728xH9AWKRyiw9836BB9A+Lz57TfF9ruAjO+dWRMhi +7RtBEVeS5j8lQhlP2AK55QUrUbHwtmUOWF5Y6KkMD7VnBceqpUzh6VtUfLtzCqbF +5W1rYb0+pnNLdZdWTW915I2Ob5g8AdkOM1x97upLdH3FMnbA8xrYzeiJxuYELhLY +thPuCUiOPnXM5ZIheXO1Vcs6t1egg5axNlU48tT7PC32tAvhqF7skJh+dUiI24Rq +q2h+9oTEtdj89/tiGKmL7tFIGPCc8U5YXhQypfmvmybOsD1w60EUMkP0iylWBDL+ +1f3Pzf29W9sHBLvG8BzGFNYGR7ngeMxGPzFcWGvM03sEptbQ3219GYtse8NmvOwW +5GMi6XIKLE2fee5VIrK4EbflMk6TH4vYeuJy2V+2WvHeiYZ1yKlXLeEF3Qs4yhSX +st3wuQINBF0ocVoBEACmJAV2duLRSwxjswQBN8cBbf2yRsVzUre7GakhEPeEIQoI +xeIqRKmlXFltxATaPeQPvrBEmuiHiFr1nrTV0GuYthP8O6jJLjGBQjJ/bilgZMDJ +nv2ZuEUAz2F4xGqbBV9SLheh1YHmzWQwje8+mW+wGSR+mcApmC6JQgrCsRcJKpN3 +308k8ZZ3WLiJPltfKMPPPPMIHvhYBvrg4SzbYspWXjcFWZQFMQ3n3vAUXAsp0JLx +WF1URe/P8VrHWODS8cEsXLsHs49F3G/+PKNX6wg4clPl7Z1CiOGJ/Hd67R22m3nX +fsEZISe1zBkHeLUMGy/rqxVOfpWvXPp4/jlIQFa5trY0RItk58ZQBfeozNNvdni6 +6QkxW4eMGfMSp9V+pLIYpAX7iiBPvPodvnWdBChtHRGz0WSBifoonga0LmFP7L0I +z0X+Dpf4VTXsj23BRCwqB5p5nrmtB9c5+0KK53bsWw2mUC8y7gciw1LrvfyQ4cwl +k3Bvp84RmfJMWaLjLABfuspc96t+zYODBiXj5v/fBixgBCF7pcGYusFAGKq41AMu +SWAqq0ZULqUpYW/ltdVfyrCquaa3ssK7YRJXbhiQ7X+qIvUB4Mgo0Nrx4QxKextm +JBCAS/BaFqWulYprSlb+37mN0iTVajdO+uAo+1Zh0ElNPmGoQLyiJJxlmYmyoQAR +AQABiQI2BBgBCgAgFiEEAF7VASEDhZ8SefhYk6hLnkAz9tgFAl0ocVoCGwwACgkQ +k6hLnkAz9th9Og//eRddMdE2AkhG+8ASBGtqnFiqQlIF7wXv2aZHLHVBomGzinoh +C4KPJ80PhX6ENr12HmTC9uibSndkDdBebAGvz7bzhRKe+BJW+lOnCbtujZ1TWFyg +0nuw0SqPJqN9OoIf7jF68Vy6mM7Kw0Un+IvhOpRFLQSgq7wWfP57y7VWE9rt9H92 +CGrbDEe+OTjlR+WaMqQExMp04FWiXizg6bW6BUCgyB80gaG2Lx4IIT/yl/WI+xD2 +YzoEk+REoXMWrIkiVRK+OvAI2FGSMQNSJYJ33N7KfTlC6Fcj9mitftjrwaV0ofGP +HqDPboLk42do6lhm33flxs+0msTEBgGdykVH6FPadZSTfrGQshy9EMxmFiYi8yrC +DBdfxYMCNrbMuj2IErJlnBMFcbCNGZRqP7VDtNjObX3MljxEqxtvjn+wlvPISkq7 +g4BJkCXbCbznBFYGW/DX2E1zX7gR+MwrrLME5+8v89kzubQTkzUEQlkTEXHproFo +dUlF9eNo+l1Zi+T15NcKS01jnUhdFKtE9GwqxVO/9G/b0m1DTY7sgXYEbyJE9cQk +PRwa30lsANNFVN1hVkHlx2yMbzhT2yLUK8xOhaXspACGgvMrDoqX88/PGRrYJhAL +uw91CabkmpZdM38vg/36BVoA95oQU3KjIMLtyqfcYMhvVXhKEK12HgtfWUU= +=3PLm +-----END PGP PUBLIC KEY BLOCK----- + diff --git a/contrib/gitian-keys/spazcadet.pgp b/contrib/gitian-keys/spazcadet.pgp index 7eb2f2a3c..21ced054a 100644 --- a/contrib/gitian-keys/spazcadet.pgp +++ b/contrib/gitian-keys/spazcadet.pgp @@ -1,41 +1,41 @@ -----BEGIN PGP PUBLIC KEY BLOCK----- -mQGNBFzabDUBDADAePxdQ/Kubb1tJTx5c55iLP5FbFvqxnPTBhmQCbuc7bWhMd0w -/u1OV5jx++BPB5RNu5dqP6fQphAwGaKevP3XtmkJ6zcompfH59tL0BUq3m51FXTM -xweS1laLeZu4hHVfNHwyl/YnEqICGdP9ecIpzEvW3YSY9NW3oHx204i0dj7yeSxb -UdjiKp71oyl3dmej2XCtj3DmpgImqd3q3vuE+Gvwf1fcFyVkBZXoakhkmTsQxhlM -2TXvTk2kykgsSGBayaQf5UH6R5CiXQATwcvHIF3Z/RY8s9LcaaQ93btSSUvycpfI -vX0D26FmKZZ101BIKyukzZBMNGi13aBjaOQ+B488S1sWZDFUo9UzNIDAVaVswUT/ -RinOwn54aLGZVCvfZJy0SOUHNNVCWapaHDsxxtQKwbx5ygLECE7C52z4mr4u0ort -mEur+/GCuooTUAQFhw0FaE2D5ESkTIry4XkAYW20UZOVF771b15g7ZfMJHpePrCu -lcgq19YeWRkjGwEAEQEAAbQqU3BhemNhZGV0IChheGUtZ2l0aWFuKSA8czk4Mjgw -NUBnbWFpbC5jb20+iQHUBBMBCgA+FiEEM+2v3DPPlh30Xz6W9PwQdFlT2QcFAlza -bDUCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQ9PwQdFlT2QcZ -WQwAjF0k0+gznuPYmPvNJ7dFC5yevhlYFGvOsnhRyBh5AFMZbeG6JbfisAu4+QJD -/L0ZncJ/uW9gACtdXVi6Cv/hVYFcGZI+fZTYi3HWcYuO+6A9J8FtpzvUpgxq1UCE -QJVnay1Y6ysTiRSAn4NLibt8sWKL/EQrqc2Z3PHr6oGKofg4sJUZiRkeqTTPWhp6 -SSQCKb9F8Uke5/eQaz5C8DbbuxhJ2NV+TRRohoYi169kzo+sR4J6/kSr/F1cx4IG -Z1fBoPgNd4IhEg6UIE/R5Fnlg9ie0NsOz8JWKClUzlKSSf7t59+q7e9yoCwBu/Yr -iDabM2sg9k4Oiw3Gvv8XN3DFFjILHx5GMXYWDW91oBzECvr+PcxUXB/rpJG7VQbW -dGr4DsMEUwnJnnZ8bfv8VpEe/HMJEjP3rSSYU/fRkAAdmm0KdC8/ccA6bTg49rnK -8g2N1YDIC064yms4FajfpycQD0pjRq57mlT6RlrDve/GDamE1+yNeOqyJAaJ0Hp2 -XlN7uQGNBFzabDUBDADm6eJgc255YG7QRy3eFIu9f1HhS4CdgVzcS0Ekbi4KLqfJ -C37gfRIxdVrXyP4aRdDN/jV6EKDyU98vPEnt6kc/vBZnCt1jdEdXNFvEJ8LzPbyG -R86BCKsZ6Xqj3cVgM4/AYNLqCbUAoYgdE5tFJepEZhICZo1S+BeNDfMNNHi2Uhqy -GrRRPkNn/BjGVfwCpbdzrp/D2GQS3P6+hH+8y7uH0V0ktIKsAVu+cVnD9fOkH3W6 -sTHJrz7RJZcJgayJyFG+vBNRlLMozBbRD/+k/SzpE6QnhgdRkxS5IpMv9AlWMyV8 -nKz6VIw96E2y92hq81RdZ5laINpSwNLvc3HK25dekLQKVcTUnDtspUSXKWAidBar -8fTOV78UTUTwTAgl0FCqyztW9QrjPPUMulugXAZKzn9RLzWINMq+4mIc5hlEMYlz -Yrg9uobJxH1DVtoF+KHD5HTrSunvbgWQ4Pry55J8EvNc0ApPqFt11IzanlyRBwI9 -f0jlkg0GTh2pwYN1J/sAEQEAAYkBtgQYAQoAIBYhBDPtr9wzz5Yd9F8+lvT8EHRZ -U9kHBQJc2mw1AhsMAAoJEPT8EHRZU9kHqGEL/iRyqFyr9wSRMaVD2WRPGYa0ENHk -efIDSSv2KxIK+QDKlob+ZCfdkXlAgD/7vCo7VH6FPM3Q6JHRsEYtxK+aXAb0Po6a -/0txaPF1FtZbdEGhxqnK9xf9roSCKT+QYM9qF4I4ZHYts6Hze72T0uuqMfMfz6vh -5gxa5varH0Ig8MgjNKCYCHoXhoDTBEhZhdVmMKCHEqZ7hBPIo0fo3eQZaTSwCJOD -KIi/CgNeDRM5PiLGNBM3ESK82saA3QRQ3tsrT1QxcoIqf8VLydI5/NEm+bGqLmNs -1NrDD14MciYqR3Y+Bd5xv8SrcpzGpD64uAKvJQNzpFPjUTg4BtrGYzvB+ayJRzvJ -89CmGx82orSbJxUQVXV//O/ZsAQ83Y/tYyYw7bvW9M51ZA1xHw/klmrEebhS4o0n -wEeo+rtziOpBGy61OcwdUFGnubPYLWpYTSgA+QDLdtXP3Xn7evjINfZ/2G9+oGgZ -/V6RasQngxhd56n8WDSLb7nCZPwHpjpRceXtXw== -=tYJf +mQGNBFzzhLsBDAD6ucFAAQ3B7PLCgXTs1ig7zAzbo0S4V6vY0AwYhxexuFMnGSqB +rqPDlAg+4ew//u4VYe/w77RZqmQwJonluuAzwbzCXuQBmARnY5jIGUHgD8THflYf +uzxNu9l1A0My5jJSPHo/xsbrc9MbQERlINCEeVeHq5HB3ax8VK9E7/pKMkoP7rl+ +7e+bMQchVVi2s+lKyfADQlT2tcNvoxePN/RlFYDcIGO4zkh5JVRTCr+mTfdTjIGy +zA4ifCAJ1i1GnfJ7jQ/PmVuP5FQtdNGXA1QRRyRgoS9SfmI8P2sHPQyEN2sO17bp +5wRJ3GLaSeKSLmew3NdXjSgwl/yUOzyhQGldlFXmrm35f9wdMRjQs+ROeQSyjIgg +BmeS4uUTw/3q572tImRmiPC4wblQqdUqV17F4PCWldcpsNwmlgwWeidjRXUV/T1M +vEOaQLZp6NpvcmNB+16XVOe1caeea8EF8GsPDdrEM1t9PoTmldYdjDCySEW9Mptv +JyjnyZeZYaMCovcAEQEAAbQqc3BhemNhZGV0IChheGUtZ2l0aWFuKSA8czk4Mjgw +NUBnbWFpbC5jb20+iQHUBBMBCgA+FiEEWY/GIClyDpxv5WQrIiq6JIduopQFAlzz +hLsCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQIiq6JIduopQQ +cgv+J9zK+O35EIqEpCuv+6xg1dlbUIOBIgJYZdYXkBh44YCOBtPssAk0tL6ism6C ++cvJjrLfkgZJXn0NBr/FzCZTyUVi+wVm/H6TCLKZfaqHbcv42X6bg7K/5mrh0DjT +IslEtF/eE81Z7M7F/9HmKd9+9S+vVkRDhFlRdfhGHkI0fQOloW61b3XE8KHYKSUF +qLLw2v+zCKc7sAVNKUo0lyXrzoFW81ZOM52hGj8TLVa8CPLixsvu/E8YDlmgLKye +EaW20fcBI4WuOAmKbMvTMeD2Cf55CDcS6KL3FfQcvmVbfgbBnGtiw5DPNyO5lK2G +Xw2R5Q2IYXcSOdAW8vrdirkyQYiRMYKwRQf5JJLlDXFLdLOb32TOOc3HMueESxZE +YeBf+R1RQbIm7s2+nDc8XpXefdbVTel4VnLg/sb7rsVvMCO5c/yKzzMEW145ybjq +Gitd8eKtKPD/nahp6J+JTQK/j+2pIXsEcUWgutYaIxBAdH/KkPJncGNA4SYYM67c +qjqOuQGNBFzzhLsBDACYu9VdqvEYJYlOoImOWnY20krqrSygiYFW9HZqZeqtZx9s +ptt8cVv+kY81ioVA1niaDzLRV9OGReSZzORbWxSHVLJ6oDcIK5iPUEUxTgmu18so +7lFxj+X8uvnIJeT2e3/GOE1176CwaARrWx5zKq55m8pK+TmpO8/aB1DtlQyOauWB +fASQMlZygc0mCmZsSAp6wfdQLbrq95gnr/bxbj0jhnUW4FHU0qinhv3xE9gaOJc1 +XU0NRaDQDyXUFMdyH1bmYl5g834+xhKYHhcxVm4zZ+iBjkP3Bc6u73U5E1KHjF9o +L1eyQPjcMuuJvjymvH8IkQ0b0J47I5y+BPs5Re4oFALVaxvUOjLugSsgpwdEV+PU +3gRfgl+ABCCNcDUC9BGrwoP5cM1Nwvpe1h7lo5WXhjrAgoz0hgrX9yASKSmmAGYk +K1eKw9CYYfJexIXyH++JFqABxuePOZ7IYJDwl9SvupGWEVBs8gls3kBtq1UB6ugT +CjoSfZ0xBsaeyB8jJAkAEQEAAYkBtgQYAQoAIBYhBFmPxiApcg6cb+VkKyIquiSH +bqKUBQJc84S7AhsMAAoJECIquiSHbqKU04oL/0eNK3+VPC+i7wKx838q6NJWyvG8 +Auimhv6deSWqzSp9UdP7ziHD9bstqwlBngZ5U7MsuT2tj4n+BsvBkOBDjJFlF7AQ +Ufnd/KzEygCuhzwGUXjt8/73V9jUHprsJj5MAxmrgzQGvjgwfrJyEjOFTZuzqMnK +78zfuAVxfq5Y8gkSWKyocKL1vR7dUiFiw7kS+jGEKdK2NiDy+I/RqMcLyFjooqdp +uqlRXP63GRsn/kIvD65Xzpc8nKLd76LKfF17SaAAqaB4E8lrzSw+UHDivB35k9B1 +WiLszHkXQDS6nFBFeU33oCh+U3Fw8BBMZ0yqvJmiafx3XX7HBsyfyxjcV0BDc6Jq +t3m5oEIqsI6zSQFXa7UpqwIVD4d2B4WH4/EoZBRfykC8Zry9PXLb2QAdlw99dLku +69MvL9xt9PmCDF67cg+BHHJsfVsdAda8CUZk8p8cvX5xS+WARQfIyToPbkhfBk7z +1t4MdpiNKnuqoBv4OZ9QCD3PYXgMd4ujp9reHg== +=eznw -----END PGP PUBLIC KEY BLOCK----- diff --git a/contrib/zmq/zmq_sub.py b/contrib/zmq/zmq_sub.py index 3086b26d5..a80c2daf0 100755 --- a/contrib/zmq/zmq_sub.py +++ b/contrib/zmq/zmq_sub.py @@ -8,8 +8,8 @@ Axe should be started with the command line arguments: axed-testnet -daemon \ - -zmqpubhashblock=tcp://127.0.0.1:28332 \ -zmqpubrawtx=tcp://127.0.0.1:28332 \ + -zmqpubrawblock=tcp://127.0.0.1:28332 \ -zmqpubhashtx=tcp://127.0.0.1:28332 \ -zmqpubhashblock=tcp://127.0.0.1:28332 @@ -38,7 +38,7 @@ class ZMQHandler(): def __init__(self): - self.loop = zmq.asyncio.install() + self.loop = asyncio.get_event_loop() self.zmqContext = zmq.asyncio.Context() self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) diff --git a/contrib/zmq/zmq_sub3.4.py b/contrib/zmq/zmq_sub3.4.py index ea738242d..75398cf02 100755 --- a/contrib/zmq/zmq_sub3.4.py +++ b/contrib/zmq/zmq_sub3.4.py @@ -8,8 +8,8 @@ Axe should be started with the command line arguments: axed -testnet -daemon \ - -zmqpubhashblock=tcp://127.0.0.1:28332 \ -zmqpubrawtx=tcp://127.0.0.1:28332 \ + -zmqpubrawblock=tcp://127.0.0.1:28332 \ -zmqpubhashtx=tcp://127.0.0.1:28332 \ -zmqpubhashblock=tcp://127.0.0.1:28332 @@ -42,7 +42,7 @@ class ZMQHandler(): def __init__(self): - self.loop = zmq.asyncio.install() + self.loop = asyncio.get_event_loop() self.zmqContext = zmq.asyncio.Context() self.zmqSubSocket = self.zmqContext.socket(zmq.SUB) diff --git a/depends/Makefile b/depends/Makefile index 71aa4ecb8..6d8bd8d21 100755 --- a/depends/Makefile +++ b/depends/Makefile @@ -14,7 +14,6 @@ PATCHES_PATH = $(BASEDIR)/patches BASEDIR = $(CURDIR) HASH_LENGTH:=11 DOWNLOAD_CONNECT_TIMEOUT:=10 -DOWNLOAD_RETRIES:=3 HOST_ID_SALT ?= salt BUILD_ID_SALT ?= salt diff --git a/depends/builders/darwin.mk b/depends/builders/darwin.mk index d15d6feea..adf75e6ff 100755 --- a/depends/builders/darwin.mk +++ b/depends/builders/darwin.mk @@ -7,7 +7,7 @@ build_darwin_OTOOL: = $(shell xcrun -f otool) build_darwin_NM: = $(shell xcrun -f nm) build_darwin_INSTALL_NAME_TOOL:=$(shell xcrun -f install_name_tool) build_darwin_SHA256SUM = shasum -a 256 -build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o +build_darwin_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) -o #darwin host on darwin builder. overrides darwin host preferences. darwin_CC=$(shell xcrun -f clang) -mmacosx-version-min=$(OSX_MIN_VERSION) diff --git a/depends/builders/linux.mk b/depends/builders/linux.mk index b03f42401..9af0d066a 100755 --- a/depends/builders/linux.mk +++ b/depends/builders/linux.mk @@ -1,2 +1,2 @@ build_linux_SHA256SUM = sha256sum -build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) --retry $(DOWNLOAD_RETRIES) -o +build_linux_DOWNLOAD = curl --location --fail --connect-timeout $(DOWNLOAD_CONNECT_TIMEOUT) -o diff --git a/depends/funcs.mk b/depends/funcs.mk index 15e404e42..5c05a4e7c 100755 --- a/depends/funcs.mk +++ b/depends/funcs.mk @@ -31,6 +31,8 @@ endef define fetch_file ( test -f $$($(1)_source_dir)/$(4) || \ ( $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5)) || \ + (sleep 5 && $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5))) || \ + (sleep 10 && $(call fetch_file_inner,$(1),$(2),$(3),$(4),$(5))) || \ $(call fetch_file_inner,$(1),$(FALLBACK_DOWNLOAD_PATH),$(3),$(4),$(5)))) endef diff --git a/doc/Doxyfile b/doc/Doxyfile index 426a4f6e8..0e5ae27af 100755 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -41,7 +41,7 @@ PROJECT_NAME = "Axe Core" # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = 1.4.0.2 +PROJECT_NUMBER = 1.4.1.0 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/doc/developer-notes.md b/doc/developer-notes.md index 89c6b8cbd..3567e9ed2 100755 --- a/doc/developer-notes.md +++ b/doc/developer-notes.md @@ -133,7 +133,7 @@ Run with the -testnet option to run with "play coins" on the test network, if yo are testing multi-machine code that needs to operate across the internet. If you are testing something that can run on one machine, run with the -regtest option. -In regression test mode, blocks can be created on-demand; see qa/rpc-tests/ for tests +In regression test mode, blocks can be created on-demand; see test/functional/ for tests that run in -regtest mode. **DEBUG_LOCKORDER** @@ -255,7 +255,7 @@ Wallet - *Rationale*: In RPC code that conditionally uses the wallet (such as `validateaddress`) it is easy to forget that global pointer `pwalletMain` - can be NULL. See `qa/rpc-tests/disablewallet.py` for functional tests + can be NULL. See `test/functional/disablewallet.py` for functional tests exercising the API with `-disablewallet` - Include `db_cxx.h` (BerkeleyDB header) only when `ENABLE_WALLET` is set diff --git a/doc/release-process.md b/doc/release-process.md index 3719a5b6c..82dc8830a 100755 --- a/doc/release-process.md +++ b/doc/release-process.md @@ -21,6 +21,7 @@ Before every major release: * Update hardcoded [seeds](/contrib/seeds/README.md). TODO: Give example PR for Axe * Update [`BLOCK_CHAIN_SIZE`](/src/qt/intro.cpp) to the current size plus some overhead. +* Update `src/chainparams.cpp` chainTxData with statistics about the transaction count and rate. ### First time / New builders diff --git a/qa/README.md b/qa/README.md deleted file mode 100755 index d9bf3fd5f..000000000 --- a/qa/README.md +++ /dev/null @@ -1,87 +0,0 @@ -The [pull-tester](/qa/pull-tester/) folder contains a script to call -multiple tests from the [rpc-tests](/qa/rpc-tests/) folder. - -Every pull request to the Axe Core repository is built and run through -the regression test suite. You can also run all or only individual -tests locally. - -Test dependencies -================= -Before running the tests, the following must be installed. - -Unix ----- -The python3-zmq library is required. On Ubuntu or Debian it can be installed via: -``` -sudo apt-get install python3-zmq -``` - -OS X ------- -``` -pip3 install pyzmq -``` - -Running tests -============= - -You can run any single test by calling - - qa/pull-tester/rpc-tests.py - -Or you can run any combination of tests by calling - - qa/pull-tester/rpc-tests.py ... - -Run the regression test suite with - - qa/pull-tester/rpc-tests.py - -Run all possible tests with - - qa/pull-tester/rpc-tests.py --extended - -By default, tests will be run in parallel. To specify how many jobs to run, -append `--jobs=n` (default n=4). - -If you want to create a basic coverage report for the RPC test suite, append `--coverage`. - -Possible options, which apply to each individual test run: - -``` - -h, --help show this help message and exit - --nocleanup Leave axeds and test.* datadir on exit or error - --noshutdown Don't stop axeds after the test execution - --srcdir=SRCDIR Source directory containing axed/axe-cli - (default: ../../src) - --tmpdir=TMPDIR Root directory for datadirs - --tracerpc Print out all RPC calls as they are made - --coveragedir=COVERAGEDIR - Write tested RPC commands into this directory -``` - -If you set the environment variable `PYTHON_DEBUG=1` you will get some debug -output (example: `PYTHON_DEBUG=1 qa/pull-tester/rpc-tests.py wallet`). - -A 200-block -regtest blockchain and wallets for four nodes -is created the first time a regression test is run and -is stored in the cache/ directory. Each node has 25 mature -blocks (25*500=12500 AXE) in its wallet. - -After the first run, the cache/ blockchain and wallets are -copied into a temporary directory and used as the initial -test state. - -If you get into a bad state, you should be able -to recover with: - -```bash -rm -rf cache -killall axed -``` - -Writing tests -============= -You are encouraged to write tests for new or existing features. -Further information about the test framework and individual RPC -tests is found in [qa/rpc-tests](/qa/rpc-tests). diff --git a/share/qt/Info.plist.in b/share/qt/Info.plist.in index ac13c00c6..ab7e2ed32 100755 --- a/share/qt/Info.plist.in +++ b/share/qt/Info.plist.in @@ -97,9 +97,6 @@ NSHighResolutionCapable True - LSAppNapIsDisabled - True - NSRequiresAquaSystemAppearance True diff --git a/src/Makefile.am b/src/Makefile.am index 88eb3759a..0f4f6215f 100755 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -103,7 +103,6 @@ endif # axe core # BITCOIN_CORE_H = \ addrdb.h \ - activemasternode.h \ addressindex.h \ spentindex.h \ addrman.h \ @@ -142,25 +141,25 @@ BITCOIN_CORE_H = \ evo/providertx.h \ evo/simplifiedmns.h \ evo/specialtx.h \ - privatesend.h \ - privatesend-client.h \ - privatesend-server.h \ - privatesend-util.h \ + privatesend/privatesend.h \ + privatesend/privatesend-client.h \ + privatesend/privatesend-server.h \ + privatesend/privatesend-util.h \ dsnotificationinterface.h \ - governance.h \ - governance-classes.h \ - governance-exceptions.h \ - governance-object.h \ - governance-validators.h \ - governance-vote.h \ - governance-votedb.h \ + governance/governance.h \ + governance/governance-classes.h \ + governance/governance-exceptions.h \ + governance/governance-object.h \ + governance/governance-validators.h \ + governance/governance-vote.h \ + governance/governance-votedb.h \ flat-database.h \ hdchain.h \ httprpc.h \ httpserver.h \ indirectmap.h \ init.h \ - instantx.h \ + instantsend.h \ key.h \ keepass.h \ keystore.h \ @@ -179,10 +178,11 @@ BITCOIN_CORE_H = \ llmq/quorums_signing.h \ llmq/quorums_signing_shares.h \ llmq/quorums_utils.h \ - masternode-meta.h \ - masternode-payments.h \ - masternode-sync.h \ - masternode-utils.h \ + masternode/activemasternode.h \ + masternode/masternode-meta.h \ + masternode/masternode-payments.h \ + masternode/masternode-sync.h \ + masternode/masternode-utils.h \ memusage.h \ merkleblock.h \ messagesigner.h \ @@ -259,7 +259,6 @@ libaxe_util_a-clientversion.$(OBJEXT): obj/build.h libaxe_server_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(MINIUPNPC_CPPFLAGS) $(EVENT_CFLAGS) $(EVENT_PTHREADS_CFLAGS) libaxe_server_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libaxe_server_a_SOURCES = \ - activemasternode.cpp \ addrman.cpp \ addrdb.cpp \ alert.cpp \ @@ -279,14 +278,14 @@ libaxe_server_a_SOURCES = \ httprpc.cpp \ httpserver.cpp \ init.cpp \ - instantx.cpp \ + instantsend.cpp \ dbwrapper.cpp \ - governance.cpp \ - governance-classes.cpp \ - governance-object.cpp \ - governance-validators.cpp \ - governance-vote.cpp \ - governance-votedb.cpp \ + governance/governance.cpp \ + governance/governance-classes.cpp \ + governance/governance-object.cpp \ + governance/governance-validators.cpp \ + governance/governance-vote.cpp \ + governance/governance-votedb.cpp \ llmq/quorums.cpp \ llmq/quorums_blockprocessor.cpp \ llmq/quorums_commitment.cpp \ @@ -300,10 +299,11 @@ libaxe_server_a_SOURCES = \ llmq/quorums_signing.cpp \ llmq/quorums_signing_shares.cpp \ llmq/quorums_utils.cpp \ - masternode-meta.cpp \ - masternode-payments.cpp \ - masternode-sync.cpp \ - masternode-utils.cpp \ + masternode/activemasternode.cpp \ + masternode/masternode-meta.cpp \ + masternode/masternode-payments.cpp \ + masternode/masternode-sync.cpp \ + masternode/masternode-utils.cpp \ merkleblock.cpp \ messagesigner.cpp \ miner.cpp \ @@ -314,8 +314,8 @@ libaxe_server_a_SOURCES = \ policy/fees.cpp \ policy/policy.cpp \ pow.cpp \ - privatesend.cpp \ - privatesend-server.cpp \ + privatesend/privatesend.cpp \ + privatesend/privatesend-server.cpp \ rest.cpp \ rpc/blockchain.cpp \ rpc/masternode.cpp \ @@ -357,8 +357,8 @@ libaxe_wallet_a_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) libaxe_wallet_a_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS) libaxe_wallet_a_SOURCES = \ keepass.cpp \ - privatesend-client.cpp \ - privatesend-util.cpp \ + privatesend/privatesend-client.cpp \ + privatesend/privatesend-util.cpp \ wallet/crypter.cpp \ wallet/db.cpp \ wallet/rpcdump.cpp \ diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include index 73c6a6a27..1ec43102c 100755 --- a/src/Makefile.qt.include +++ b/src/Makefile.qt.include @@ -102,7 +102,8 @@ QT_MOC_CPP = \ BITCOIN_MM = \ qt/macdockiconhandler.mm \ - qt/macnotificationhandler.mm + qt/macnotificationhandler.mm \ + qt/macos_appnap.mm QT_MOC = \ qt/axe.moc \ @@ -139,6 +140,7 @@ BITCOIN_QT_H = \ qt/intro.h \ qt/macdockiconhandler.h \ qt/macnotificationhandler.h \ + qt/macos_appnap.h \ qt/modaloverlay.h \ qt/masternodelist.h \ qt/networkstyle.h \ diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include index f2b86b99b..910ea48a2 100755 --- a/src/Makefile.qttest.include +++ b/src/Makefile.qttest.include @@ -13,7 +13,9 @@ TEST_QT_MOC_CPP = \ qt/test/moc_uritests.cpp if ENABLE_WALLET -TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp +TEST_QT_MOC_CPP += \ + qt/test/moc_paymentservertests.cpp \ + qt/test/moc_wallettests.cpp endif TEST_QT_H = \ @@ -22,7 +24,16 @@ TEST_QT_H = \ qt/test/uritests.h \ qt/test/paymentrequestdata.h \ qt/test/paymentservertests.h \ - qt/test/trafficgraphdatatests.h + qt/test/trafficgraphdatatests.h \ + qt/test/wallettests.h + +TEST_BITCOIN_CPP = \ + test/test_axe.cpp \ + test/testutil.cpp + +TEST_BITCOIN_H = \ + test/test_axe.h \ + test/testutil.h qt_test_test_axe_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \ $(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS) @@ -33,10 +44,13 @@ qt_test_test_axe_qt_SOURCES = \ qt/test/test_main.cpp \ qt/test/uritests.cpp \ qt/test/trafficgraphdatatests.cpp \ - $(TEST_QT_H) + $(TEST_QT_H) \ + $(TEST_BITCOIN_CPP) \ + $(TEST_BITCOIN_H) if ENABLE_WALLET qt_test_test_axe_qt_SOURCES += \ - qt/test/paymentservertests.cpp + qt/test/paymentservertests.cpp \ + qt/test/wallettests.cpp endif nodist_qt_test_test_axe_qt_SOURCES = $(TEST_QT_MOC_CPP) diff --git a/src/Makefile.test.include b/src/Makefile.test.include index 96634ecb0..3c36e6031 100755 --- a/src/Makefile.test.include +++ b/src/Makefile.test.include @@ -1,6 +1,5 @@ # Copyright (c) 2013-2016 The Bitcoin Core developers # Copyright (c) 2014-2018 The Dash Core developers -# Copyright (c) 2017-2018 The AXE Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -9,48 +8,6 @@ bin_PROGRAMS += test/test_axe TEST_SRCDIR = test TEST_BINARY=test/test_axe$(EXEEXT) - -EXTRA_DIST += \ - test/bctest.py \ - test/bitcoin-util-test.py \ - test/data/bitcoin-util-test.json \ - test/data/blanktxv1.hex \ - test/data/blanktxv1.json \ - test/data/blanktxv2.hex \ - test/data/blanktxv2.json \ - test/data/tt-delin1-out.hex \ - test/data/tt-delin1-out.json \ - test/data/tt-delout1-out.hex \ - test/data/tt-delout1-out.json \ - test/data/tt-locktime317000-out.hex \ - test/data/tt-locktime317000-out.json \ - test/data/tx394b54bb.hex \ - test/data/txcreate1.hex \ - test/data/txcreate1.json \ - test/data/txcreate2.hex \ - test/data/txcreate2.json \ - test/data/txcreatedata1.hex \ - test/data/txcreatedata1.json \ - test/data/txcreatedata2.hex \ - test/data/txcreatedata2.json \ - test/data/txcreatedata_seq0.hex \ - test/data/txcreatedata_seq0.json \ - test/data/txcreatedata_seq1.hex \ - test/data/txcreatedata_seq1.json \ - test/data/txcreatemultisig1.hex \ - test/data/txcreatemultisig1.json \ - test/data/txcreatemultisig2.hex \ - test/data/txcreatemultisig2.json \ - test/data/txcreateoutpubkey1.hex \ - test/data/txcreateoutpubkey1.json \ - test/data/txcreatescript1.hex \ - test/data/txcreatescript1.json \ - test/data/txcreatescript2.hex \ - test/data/txcreatescript2.json \ - test/data/txcreatesignv1.hex \ - test/data/txcreatesignv1.json \ - test/data/txcreatesignv2.hex - JSON_TEST_FILES = \ test/data/script_tests.json \ test/data/base58_keys_valid.json \ @@ -80,6 +37,7 @@ BITCOIN_TESTS =\ test/bip39_tests.cpp \ test/blockencodings_tests.cpp \ test/bloom_tests.cpp \ + test/bls_tests.cpp \ test/bswap_tests.cpp \ test/checkqueue_tests.cpp \ test/cachemap_tests.cpp \ @@ -107,6 +65,7 @@ BITCOIN_TESTS =\ test/policyestimator_tests.cpp \ test/pow_tests.cpp \ test/prevector_tests.cpp \ + test/random_tests.cpp \ test/raii_event_tests.cpp \ test/ratecheck_tests.cpp \ test/reverselock_tests.cpp \ @@ -125,6 +84,7 @@ BITCOIN_TESTS =\ test/subsidy_tests.cpp \ test/test_axe.cpp \ test/test_axe.h \ + test/test_axe_main.cpp \ test/test_random.h \ test/testutil.cpp \ test/testutil.h \ @@ -140,6 +100,7 @@ BITCOIN_TESTS += \ wallet/test/wallet_test_fixture.cpp \ wallet/test/wallet_test_fixture.h \ wallet/test/accounting_tests.cpp \ + wallet/test/wallet_tests.cpp \ wallet/test/crypto_tests.cpp endif @@ -167,9 +128,6 @@ CLEAN_BITCOIN_TEST = test/*.gcda test/*.gcno $(GENERATED_TEST_FILES) CLEANFILES += $(CLEAN_BITCOIN_TEST) -# This file is problematic for out-of-tree builds if it exists. -DISTCLEANFILES += test/buildenv.pyc - axe_test: $(TEST_BINARY) axe_test_check: $(TEST_BINARY) FORCE @@ -179,8 +137,8 @@ axe_test_clean : FORCE rm -f $(CLEAN_BITCOIN_TEST) $(test_test_axe_OBJECTS) $(TEST_BINARY) #check-local: -# @echo "Running test/bitcoin-util-test.py..." -# $(AM_V_at)srcdir=$(srcdir) PYTHONPATH=$(builddir)/test $(PYTHON) $(srcdir)/test/bitcoin-util-test.py +# @echo "Running test/util/bitcoin-util-test.py..." +# $(PYTHON) $(top_builddir)/test/util/bitcoin-util-test.py # $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C secp256k1 check #if EMBEDDED_UNIVALUE # $(AM_V_at)$(MAKE) $(AM_MAKEFLAGS) -C univalue check diff --git a/src/addrman.cpp b/src/addrman.cpp index c94df08aa..10b449153 100755 --- a/src/addrman.cpp +++ b/src/addrman.cpp @@ -533,6 +533,23 @@ void CAddrMan::SetServices_(const CService& addr, ServiceFlags nServices) info.nServices = nServices; } +CAddrInfo CAddrMan::GetAddressInfo_(const CService& addr) +{ + CAddrInfo* pinfo = Find(addr); + + // if not found, bail out + if (!pinfo) + return CAddrInfo(); + + CAddrInfo& info = *pinfo; + + // check whether we are talking about the exact same CService (including same port) + if (info != addr) + return CAddrInfo(); + + return *pinfo; +} + int CAddrMan::RandomInt(int nMax){ return GetRandInt(nMax); } diff --git a/src/addrman.h b/src/addrman.h index c69e67f4d..9c000faaf 100755 --- a/src/addrman.h +++ b/src/addrman.h @@ -265,6 +265,9 @@ class CAddrMan //! Update an entry's service bits. void SetServices_(const CService &addr, ServiceFlags nServices); + //! Get address info for address + CAddrInfo GetAddressInfo_(const CService& addr); + public: /** * serialized format: @@ -593,6 +596,18 @@ class CAddrMan Check(); } + CAddrInfo GetAddressInfo(const CService& addr) + { + CAddrInfo addrRet; + { + LOCK(cs); + Check(); + addrRet = GetAddressInfo_(addr); + Check(); + } + return addrRet; + } + }; #endif // BITCOIN_ADDRMAN_H diff --git a/src/axe-tx.cpp b/src/axe-tx.cpp index f0b5acd2f..16270f259 100755 --- a/src/axe-tx.cpp +++ b/src/axe-tx.cpp @@ -471,22 +471,6 @@ static bool findSighashFlags(int& flags, const std::string& flagStr) return false; } -uint256 ParseHashUO(std::map& o, std::string strKey) -{ - if (!o.count(strKey)) - return uint256(); - return ParseHashUV(o[strKey], strKey); -} - -std::vector ParseHexUO(std::map& o, std::string strKey) -{ - if (!o.count(strKey)) { - std::vector emptyVec; - return emptyVec; - } - return ParseHexUV(o[strKey], strKey); -} - static void MutateTxSign(CMutableTransaction& tx, const std::string& flagStr) { int nHashType = SIGHASH_ALL; diff --git a/src/bls/bls.cpp b/src/bls/bls.cpp index c8a2dc6b6..4bee430c8 100755 --- a/src/bls/bls.cpp +++ b/src/bls/bls.cpp @@ -424,33 +424,6 @@ bool CBLSSignature::Recover(const std::vector& sigs, const std::v } #ifndef BUILD_BITCOIN_INTERNAL -void CBLSLazySignature::SetSig(const CBLSSignature& _sig) -{ - std::unique_lock l(mutex); - bufValid = false; - sigInitialized = true; - sig = _sig; -} - -const CBLSSignature& CBLSLazySignature::GetSig() const -{ - std::unique_lock l(mutex); - static CBLSSignature invalidSig; - if (!bufValid && !sigInitialized) { - return invalidSig; - } - if (!sigInitialized) { - sig.SetBuf(buf, sizeof(buf)); - if (!sig.CheckMalleable(buf, sizeof(buf))) { - bufValid = false; - sigInitialized = false; - sig = invalidSig; - } else { - sigInitialized = true; - } - } - return sig; -} static std::once_flag init_flag; static mt_pooled_secure_allocator* secure_allocator_instance; diff --git a/src/bls/bls.h b/src/bls/bls.h index 7de0d009e..c101450e5 100755 --- a/src/bls/bls.h +++ b/src/bls/bls.h @@ -170,6 +170,11 @@ class CBLSWrapper } public: + inline void Serialize(CSizeComputer& s) const + { + s.seek(SerSize); + } + template inline void Serialize(Stream& s) const { @@ -310,29 +315,34 @@ class CBLSSignature : public CBLSWrapper +class CBLSLazyWrapper { private: mutable std::mutex mutex; - mutable char buf[BLS_CURVE_SIG_SIZE]; + mutable char buf[BLSObject::SerSize]; mutable bool bufValid{false}; - mutable CBLSSignature sig; - mutable bool sigInitialized{false}; + mutable BLSObject obj; + mutable bool objInitialized{false}; + + mutable uint256 hash; public: - CBLSLazySignature() + CBLSLazyWrapper() { memset(buf, 0, sizeof(buf)); + // the all-zero buf is considered a valid buf, but the resulting object will return false for IsValid + bufValid = true; } - CBLSLazySignature(const CBLSLazySignature& r) + CBLSLazyWrapper(const CBLSLazyWrapper& r) { *this = r; } - CBLSLazySignature& operator=(const CBLSLazySignature& r) + CBLSLazyWrapper& operator=(const CBLSLazyWrapper& r) { std::unique_lock l(r.mutex); bufValid = r.bufValid; @@ -341,25 +351,32 @@ class CBLSLazySignature } else { memset(buf, 0, sizeof(buf)); } - sigInitialized = r.sigInitialized; - if (r.sigInitialized) { - sig = r.sig; + objInitialized = r.objInitialized; + if (r.objInitialized) { + obj = r.obj; } else { - sig.Reset(); + obj.Reset(); } + hash = r.hash; return *this; } + inline void Serialize(CSizeComputer& s) const + { + s.seek(BLSObject::SerSize); + } + template inline void Serialize(Stream& s) const { std::unique_lock l(mutex); - if (!sigInitialized && !bufValid) { - throw std::ios_base::failure("sig and buf not initialized"); + if (!objInitialized && !bufValid) { + throw std::ios_base::failure("obj and buf not initialized"); } if (!bufValid) { - sig.GetBuf(buf, sizeof(buf)); + obj.GetBuf(buf, sizeof(buf)); bufValid = true; + hash = uint256(); } s.write(buf, sizeof(buf)); } @@ -370,12 +387,78 @@ class CBLSLazySignature std::unique_lock l(mutex); s.read(buf, sizeof(buf)); bufValid = true; - sigInitialized = false; + objInitialized = false; + hash = uint256(); } - void SetSig(const CBLSSignature& _sig); - const CBLSSignature& GetSig() const; + void Set(const BLSObject& _obj) + { + std::unique_lock l(mutex); + bufValid = false; + objInitialized = true; + obj = _obj; + hash = uint256(); + } + const BLSObject& Get() const + { + std::unique_lock l(mutex); + static BLSObject invalidObj; + if (!bufValid && !objInitialized) { + return invalidObj; + } + if (!objInitialized) { + obj.SetBuf(buf, sizeof(buf)); + if (!obj.CheckMalleable(buf, sizeof(buf))) { + bufValid = false; + objInitialized = false; + obj = invalidObj; + } else { + objInitialized = true; + } + } + return obj; + } + + bool operator==(const CBLSLazyWrapper& r) const + { + if (bufValid && r.bufValid) { + return memcmp(buf, r.buf, sizeof(buf)) == 0; + } + if (objInitialized && r.objInitialized) { + return obj == r.obj; + } + return Get() == r.Get(); + } + + bool operator!=(const CBLSLazyWrapper& r) const + { + return !(*this == r); + } + + uint256 GetHash() const + { + std::unique_lock l(mutex); + if (!bufValid) { + obj.GetBuf(buf, sizeof(buf)); + bufValid = true; + hash = uint256(); + } + if (hash.IsNull()) { + UpdateHash(); + } + return hash; + } +private: + void UpdateHash() const + { + CHashWriter ss(SER_GETHASH, PROTOCOL_VERSION); + ss.write(buf, sizeof(buf)); + hash = ss.GetHash(); + } }; +typedef CBLSLazyWrapper CBLSLazySignature; +typedef CBLSLazyWrapper CBLSLazyPublicKey; +typedef CBLSLazyWrapper CBLSLazySecretKey; #endif typedef std::vector BLSIdVector; diff --git a/src/chainparams.cpp b/src/chainparams.cpp index 41e940588..b17bd291e 100755 --- a/src/chainparams.cpp +++ b/src/chainparams.cpp @@ -324,7 +324,6 @@ class CMainParams : public CChainParams { consensus.llmqChainLocks = Consensus::LLMQ_400_60; consensus.llmqForInstantSend = Consensus::LLMQ_50_60; - fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = true; fRequireRoutableExternalIP = true; @@ -364,11 +363,12 @@ class CMainParams : public CChainParams { ( 100315, uint256S("0x0000000000002f905a48b6b6e26d77ea86483d07f02081d2ab1de5f6279a0311")) ( 161083, uint256S("0x0000000000092122485e390355bf4345ee51b0b14ba0d8c8ee6571ab41cca881")) ( 224426, uint256S("0x00000000000007c736e43a5a953dc4fd98e70e886a9740a487ea1dc9cd25a29f")) + ( 335882, uint256S("0x000000000000024b3200646b6f26f2f1ab1591a9f130e7fcf61cb3fadb07624a")) }; chainTxData = ChainTxData{ - 1552505648, // * UNIX timestamp of last known number of transactions - 95857, // * total number of transactions between genesis and that timestamp + 1570140907, // * UNIX timestamp of last known number of transactions + 99324, // * total number of transactions between genesis and that timestamp // (the tx=... number in the SetBestChain debug.log lines) 0.1 // * estimated number of transactions per second after that timestamp }; @@ -502,7 +502,6 @@ class CTestNetParams : public CChainParams { consensus.llmqChainLocks = Consensus::LLMQ_50_60; consensus.llmqForInstantSend = Consensus::LLMQ_50_60; - fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = false; fRequireRoutableExternalIP = true; @@ -661,7 +660,6 @@ class CDevNetParams : public CChainParams { consensus.llmqChainLocks = Consensus::LLMQ_50_60; consensus.llmqForInstantSend = Consensus::LLMQ_50_60; - fMiningRequiresPeers = true; fDefaultConsistencyChecks = false; fRequireStandard = false; fMineBlocksOnDemand = false; @@ -785,7 +783,6 @@ class CRegTestParams : public CChainParams { vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds. vSeeds.clear(); //!< Regtest mode doesn't have any DNS seeds. - fMiningRequiresPeers = false; fDefaultConsistencyChecks = true; fRequireStandard = false; fRequireRoutableExternalIP = false; diff --git a/src/chainparams.h b/src/chainparams.h index 2d85ee12b..8ebb14b9b 100755 --- a/src/chainparams.h +++ b/src/chainparams.h @@ -63,8 +63,6 @@ class CChainParams const CBlock& GenesisBlock() const { return genesis; } const CBlock& DevNetGenesisBlock() const { return devnetGenesis; } - /** Make miner wait to have peers to avoid wasting work */ - bool MiningRequiresPeers() const { return fMiningRequiresPeers; } /** Default value for -checkmempool and -checkblockindex argument */ bool DefaultConsistencyChecks() const { return fDefaultConsistencyChecks; } /** Policy: Filter transactions that do not match well-defined patterns */ @@ -108,7 +106,6 @@ class CChainParams CBlock genesis; CBlock devnetGenesis; std::vector vFixedSeeds; - bool fMiningRequiresPeers; bool fDefaultConsistencyChecks; bool fRequireStandard; bool fRequireRoutableExternalIP; diff --git a/src/clientversion.h b/src/clientversion.h index f98b23a72..2ac17a0c7 100755 --- a/src/clientversion.h +++ b/src/clientversion.h @@ -16,8 +16,8 @@ //! These need to be macros, as clientversion.cpp's and axe*-res.rc's voodoo requires it #define CLIENT_VERSION_MAJOR 1 #define CLIENT_VERSION_MINOR 4 -#define CLIENT_VERSION_REVISION 0 -#define CLIENT_VERSION_BUILD 2 +#define CLIENT_VERSION_REVISION 1 +#define CLIENT_VERSION_BUILD 0 //! Set to true for release, false for prerelease or test build #define CLIENT_VERSION_IS_RELEASE true diff --git a/src/coins.h b/src/coins.h index 86de77199..b546645d6 100755 --- a/src/coins.h +++ b/src/coins.h @@ -128,7 +128,6 @@ class CCoinsViewCursor virtual bool GetKey(COutPoint &key) const = 0; virtual bool GetValue(Coin &coin) const = 0; - /* Don't care about GetKeySize here */ virtual unsigned int GetValueSize() const = 0; virtual bool Valid() const = 0; diff --git a/src/compat.h b/src/compat.h index 1d3b454d0..5ccdec51a 100755 --- a/src/compat.h +++ b/src/compat.h @@ -47,10 +47,8 @@ #include #endif -#ifdef WIN32 -#define MSG_DONTWAIT 0 -#else -typedef u_int SOCKET; +#ifndef WIN32 +typedef unsigned int SOCKET; #include "errno.h" #define WSAGetLastError() errno #define WSAEINVAL EINVAL @@ -74,11 +72,6 @@ typedef u_int SOCKET; #define MAX_PATH 1024 #endif -// As Solaris does not have the MSG_NOSIGNAL flag for send(2) syscall, it is defined as 0 -#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) -#define MSG_NOSIGNAL 0 -#endif - #if HAVE_DECL_STRNLEN == 0 size_t strnlen( const char *start, size_t max_len); #endif // HAVE_DECL_STRNLEN diff --git a/src/dbwrapper.h b/src/dbwrapper.h index d32c394d1..e434eeeaf 100755 --- a/src/dbwrapper.h +++ b/src/dbwrapper.h @@ -391,6 +391,11 @@ class CDBWrapper pdb->CompactRange(&slKey1, &slKey2); } + void CompactFull() const + { + pdb->CompactRange(nullptr, nullptr); + } + }; template @@ -551,6 +556,7 @@ class CDBTransaction { protected: Parent &parent; CommitTarget &commitTarget; + ssize_t memoryUsage{0}; // signed, just in case we made an error in the calculations so that we don't get an overflow struct DataStreamCmp { static bool less(const CDataStream& a, const CDataStream& b) { @@ -564,6 +570,8 @@ class CDBTransaction { }; struct ValueHolder { + size_t memoryUsage; + ValueHolder(size_t _memoryUsage) : memoryUsage(_memoryUsage) {} virtual ~ValueHolder() = default; virtual void Write(const CDataStream& ssKey, CommitTarget &parent) = 0; }; @@ -571,7 +579,7 @@ class CDBTransaction { template struct ValueHolderImpl : ValueHolder { - ValueHolderImpl(const V &_value) : value(_value) { } + ValueHolderImpl(const V &_value, size_t _memoryUsage) : ValueHolder(_memoryUsage), value(_value) {} virtual void Write(const CDataStream& ssKey, CommitTarget &commitTarget) { // we're moving the value instead of copying it. This means that Write() can only be called once per @@ -605,9 +613,18 @@ class CDBTransaction { template void Write(const CDataStream& ssKey, const V& v) { - deletes.erase(ssKey); + auto valueMemoryUsage = ::GetSerializeSize(v, SER_DISK, CLIENT_VERSION); + + if (deletes.erase(ssKey)) { + memoryUsage -= ssKey.size(); + } auto it = writes.emplace(ssKey, nullptr).first; - it->second = std::make_unique>(v); + if (it->second) { + memoryUsage -= ssKey.size() + it->second->memoryUsage; + } + it->second = std::make_unique>(v, valueMemoryUsage); + + memoryUsage += ssKey.size() + valueMemoryUsage; } template @@ -657,13 +674,20 @@ class CDBTransaction { } void Erase(const CDataStream& ssKey) { - writes.erase(ssKey); - deletes.emplace(ssKey); + auto it = writes.find(ssKey); + if (it != writes.end()) { + memoryUsage -= ssKey.size() + it->second->memoryUsage; + writes.erase(it); + } + if (deletes.emplace(ssKey).second) { + memoryUsage += ssKey.size(); + } } void Clear() { writes.clear(); deletes.clear(); + memoryUsage = 0; } void Commit() { @@ -680,6 +704,19 @@ class CDBTransaction { return writes.empty() && deletes.empty(); } + size_t GetMemoryUsage() const { + if (memoryUsage < 0) { + // something went wrong when we accounted/calculated used memory... + static volatile bool didPrint = false; + if (!didPrint) { + LogPrintf("CDBTransaction::%s -- negative memoryUsage (%d)", __func__, memoryUsage); + didPrint = true; + } + return 0; + } + return (size_t)memoryUsage; + } + CDBTransactionIterator* NewIterator() { return new CDBTransactionIterator(*this); } diff --git a/src/dsnotificationinterface.cpp b/src/dsnotificationinterface.cpp index e4c174336..9bcf1e3ea 100755 --- a/src/dsnotificationinterface.cpp +++ b/src/dsnotificationinterface.cpp @@ -4,13 +4,13 @@ #include "chainparams.h" #include "dsnotificationinterface.h" -#include "instantx.h" -#include "governance.h" -#include "masternode-payments.h" -#include "masternode-sync.h" -#include "privatesend.h" +#include "instantsend.h" +#include "governance/governance.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" +#include "privatesend/privatesend.h" #ifdef ENABLE_WALLET -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #endif // ENABLE_WALLET #include "validation.h" diff --git a/src/evo/deterministicmns.cpp b/src/evo/deterministicmns.cpp index 934297a13..673a2156f 100755 --- a/src/evo/deterministicmns.cpp +++ b/src/evo/deterministicmns.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 The Axe Core developers +// Copyright (c) 2018-2019 The Dash Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -38,7 +38,7 @@ std::string CDeterministicMNState::ToString() const return strprintf("CDeterministicMNState(nRegisteredHeight=%d, nLastPaidHeight=%d, nPoSePenalty=%d, nPoSeRevivedHeight=%d, nPoSeBanHeight=%d, nRevocationReason=%d, " "ownerAddress=%s, pubKeyOperator=%s, votingAddress=%s, addr=%s, payoutAddress=%s, operatorPayoutAddress=%s)", nRegisteredHeight, nLastPaidHeight, nPoSePenalty, nPoSeRevivedHeight, nPoSeBanHeight, nRevocationReason, - CBitcoinAddress(keyIDOwner).ToString(), pubKeyOperator.ToString(), CBitcoinAddress(keyIDVoting).ToString(), addr.ToStringIPPort(false), payoutAddress, operatorPayoutAddress); + CBitcoinAddress(keyIDOwner).ToString(), pubKeyOperator.Get().ToString(), CBitcoinAddress(keyIDVoting).ToString(), addr.ToStringIPPort(false), payoutAddress, operatorPayoutAddress); } void CDeterministicMNState::ToJson(UniValue& obj) const @@ -60,7 +60,7 @@ void CDeterministicMNState::ToJson(UniValue& obj) const CBitcoinAddress payoutAddress(dest); obj.push_back(Pair("payoutAddress", payoutAddress.ToString())); } - obj.push_back(Pair("pubKeyOperator", pubKeyOperator.ToString())); + obj.push_back(Pair("pubKeyOperator", pubKeyOperator.Get().ToString())); if (ExtractDestination(scriptOperatorPayout, dest)) { CBitcoinAddress operatorPayoutAddress(dest); obj.push_back(Pair("operatorPayoutAddress", operatorPayoutAddress.ToString())); @@ -147,7 +147,7 @@ CDeterministicMNCPtr CDeterministicMNList::GetValidMN(const uint256& proTxHash) CDeterministicMNCPtr CDeterministicMNList::GetMNByOperatorKey(const CBLSPublicKey& pubKey) { for (const auto& p : mnMap) { - if (p.second->pdmnState->pubKeyOperator == pubKey) { + if (p.second->pdmnState->pubKeyOperator.Get() == pubKey) { return p.second; } } @@ -168,11 +168,29 @@ CDeterministicMNCPtr CDeterministicMNList::GetValidMNByCollateral(const COutPoin return dmn; } -CDeterministicMNCPtr CDeterministicMNList::GetValidMNByService(const CService& service) const +CDeterministicMNCPtr CDeterministicMNList::GetMNByService(const CService& service) const { return GetUniquePropertyMN(service); } +CDeterministicMNCPtr CDeterministicMNList::GetValidMNByService(const CService& service) const +{ + auto dmn = GetUniquePropertyMN(service); + if (dmn && !IsMNValid(dmn)) { + return nullptr; + } + return dmn; +} + +CDeterministicMNCPtr CDeterministicMNList::GetMNByInternalId(uint64_t internalId) const +{ + auto proTxHash = mnInternalIdMap.find(internalId); + if (!proTxHash) { + return nullptr; + } + return GetMN(*proTxHash); +} + static int CompareByLastPaid_GetHeight(const CDeterministicMN& dmn) { int height = dmn.pdmnState->nLastPaidHeight; @@ -217,21 +235,21 @@ CDeterministicMNCPtr CDeterministicMNList::GetMNPayee() const std::vector CDeterministicMNList::GetProjectedMNPayees(int nCount) const { + if (nCount > GetValidMNsCount()) { + nCount = GetValidMNsCount(); + } + std::vector result; result.reserve(nCount); - CDeterministicMNList tmpMNList = *this; - for (int h = nHeight; h < nHeight + nCount; h++) { - tmpMNList.SetHeight(h); - - CDeterministicMNCPtr payee = tmpMNList.GetMNPayee(); - // push the original MN object instead of the one from the temporary list - result.push_back(GetMN(payee->proTxHash)); + ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) { + result.emplace_back(dmn); + }); + std::sort(result.begin(), result.end(), [&](const CDeterministicMNCPtr& a, const CDeterministicMNCPtr& b) { + return CompareByLastPaid(a, b); + }); - CDeterministicMNStatePtr newState = std::make_shared(*payee->pdmnState); - newState->nLastPaidHeight = h; - tmpMNList.UpdateMN(payee->proTxHash, newState); - } + result.resize(nCount); return result; } @@ -340,25 +358,31 @@ void CDeterministicMNList::PoSeDecrease(const uint256& proTxHash) CDeterministicMNListDiff CDeterministicMNList::BuildDiff(const CDeterministicMNList& to) const { CDeterministicMNListDiff diffRet; - diffRet.prevBlockHash = blockHash; - diffRet.blockHash = to.blockHash; - diffRet.nHeight = to.nHeight; to.ForEachMN(false, [&](const CDeterministicMNCPtr& toPtr) { auto fromPtr = GetMN(toPtr->proTxHash); if (fromPtr == nullptr) { - diffRet.addedMNs.emplace(toPtr->proTxHash, toPtr); - } else if (*toPtr->pdmnState != *fromPtr->pdmnState) { - diffRet.updatedMNs.emplace(toPtr->proTxHash, toPtr->pdmnState); + diffRet.addedMNs.emplace_back(toPtr); + } else if (fromPtr != toPtr || fromPtr->pdmnState != toPtr->pdmnState) { + CDeterministicMNStateDiff stateDiff(*fromPtr->pdmnState, *toPtr->pdmnState); + if (stateDiff.fields) { + diffRet.updatedMNs.emplace(toPtr->internalId, std::move(stateDiff)); + } } }); ForEachMN(false, [&](const CDeterministicMNCPtr& fromPtr) { auto toPtr = to.GetMN(fromPtr->proTxHash); if (toPtr == nullptr) { - diffRet.removedMns.insert(fromPtr->proTxHash); + diffRet.removedMns.emplace(fromPtr->internalId); } }); + // added MNs need to be sorted by internalId so that these are added in correct order when the diff is applied later + // otherwise internalIds will not match with the original list + std::sort(diffRet.addedMNs.begin(), diffRet.addedMNs.end(), [](const CDeterministicMNCPtr& a, const CDeterministicMNCPtr& b) { + return a->internalId < b->internalId; + }); + return diffRet; } @@ -390,22 +414,25 @@ CSimplifiedMNListDiff CDeterministicMNList::BuildSimplifiedDiff(const CDetermini return diffRet; } -CDeterministicMNList CDeterministicMNList::ApplyDiff(const CDeterministicMNListDiff& diff) const +CDeterministicMNList CDeterministicMNList::ApplyDiff(const CBlockIndex* pindex, const CDeterministicMNListDiff& diff) const { - assert(diff.prevBlockHash == blockHash && diff.nHeight == nHeight + 1); - CDeterministicMNList result = *this; - result.blockHash = diff.blockHash; - result.nHeight = diff.nHeight; + result.blockHash = pindex->GetBlockHash(); + result.nHeight = pindex->nHeight; - for (const auto& hash : diff.removedMns) { - result.RemoveMN(hash); + for (const auto& id : diff.removedMns) { + auto dmn = result.GetMNByInternalId(id); + assert(dmn); + result.RemoveMN(dmn->proTxHash); } - for (const auto& p : diff.addedMNs) { - result.AddMN(p.second); + for (const auto& dmn : diff.addedMNs) { + assert(dmn->internalId == result.GetTotalRegisteredCount()); + result.AddMN(dmn); + result.SetTotalRegisteredCount(result.GetTotalRegisteredCount() + 1); } for (const auto& p : diff.updatedMNs) { - result.UpdateMN(p.first, p.second); + auto dmn = result.GetMNByInternalId(p.first); + result.UpdateMN(dmn, p.second); } return result; @@ -415,30 +442,46 @@ void CDeterministicMNList::AddMN(const CDeterministicMNCPtr& dmn) { assert(!mnMap.find(dmn->proTxHash)); mnMap = mnMap.set(dmn->proTxHash, dmn); + mnInternalIdMap = mnInternalIdMap.set(dmn->internalId, dmn->proTxHash); AddUniqueProperty(dmn, dmn->collateralOutpoint); if (dmn->pdmnState->addr != CService()) { AddUniqueProperty(dmn, dmn->pdmnState->addr); } AddUniqueProperty(dmn, dmn->pdmnState->keyIDOwner); - if (dmn->pdmnState->pubKeyOperator.IsValid()) { + if (dmn->pdmnState->pubKeyOperator.Get().IsValid()) { AddUniqueProperty(dmn, dmn->pdmnState->pubKeyOperator); } } -void CDeterministicMNList::UpdateMN(const uint256& proTxHash, const CDeterministicMNStateCPtr& pdmnState) +void CDeterministicMNList::UpdateMN(const CDeterministicMNCPtr& oldDmn, const CDeterministicMNStateCPtr& pdmnState) { - auto oldDmn = mnMap.find(proTxHash); assert(oldDmn != nullptr); - auto dmn = std::make_shared(**oldDmn); + auto dmn = std::make_shared(*oldDmn); auto oldState = dmn->pdmnState; dmn->pdmnState = pdmnState; - mnMap = mnMap.set(proTxHash, dmn); + mnMap = mnMap.set(oldDmn->proTxHash, dmn); UpdateUniqueProperty(dmn, oldState->addr, pdmnState->addr); UpdateUniqueProperty(dmn, oldState->keyIDOwner, pdmnState->keyIDOwner); UpdateUniqueProperty(dmn, oldState->pubKeyOperator, pdmnState->pubKeyOperator); } +void CDeterministicMNList::UpdateMN(const uint256& proTxHash, const CDeterministicMNStateCPtr& pdmnState) +{ + auto oldDmn = mnMap.find(proTxHash); + assert(oldDmn != nullptr); + UpdateMN(*oldDmn, pdmnState); +} + +void CDeterministicMNList::UpdateMN(const CDeterministicMNCPtr& oldDmn, const CDeterministicMNStateDiff& stateDiff) +{ + assert(oldDmn != nullptr); + auto oldState = oldDmn->pdmnState; + auto newState = std::make_shared(*oldState); + stateDiff.ApplyToState(*newState); + UpdateMN(oldDmn, newState); +} + void CDeterministicMNList::RemoveMN(const uint256& proTxHash) { auto dmn = GetMN(proTxHash); @@ -448,10 +491,11 @@ void CDeterministicMNList::RemoveMN(const uint256& proTxHash) DeleteUniqueProperty(dmn, dmn->pdmnState->addr); } DeleteUniqueProperty(dmn, dmn->pdmnState->keyIDOwner); - if (dmn->pdmnState->pubKeyOperator.IsValid()) { + if (dmn->pdmnState->pubKeyOperator.Get().IsValid()) { DeleteUniqueProperty(dmn, dmn->pdmnState->pubKeyOperator); } mnMap = mnMap.erase(proTxHash); + mnInternalIdMap = mnInternalIdMap.erase(dmn->internalId); } CDeterministicMNManager::CDeterministicMNManager(CEvoDB& _evoDb) : @@ -491,12 +535,12 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockInde newList.SetBlockHash(block.GetHash()); - oldList = GetListForBlock(pindex->pprev->GetBlockHash()); + oldList = GetListForBlock(pindex->pprev); diff = oldList.BuildDiff(newList); - evoDb.Write(std::make_pair(DB_LIST_DIFF, diff.blockHash), diff); + evoDb.Write(std::make_pair(DB_LIST_DIFF, newList.GetBlockHash()), diff); if ((nHeight % SNAPSHOT_LIST_PERIOD) == 0 || oldList.GetHeight() == -1) { - evoDb.Write(std::make_pair(DB_LIST_SNAPSHOT, diff.blockHash), newList); + evoDb.Write(std::make_pair(DB_LIST_SNAPSHOT, newList.GetBlockHash()), newList); LogPrintf("CDeterministicMNManager::%s -- Wrote snapshot. nHeight=%d, mapCurMNs.allMNsCount=%d\n", __func__, nHeight, newList.GetAllMNsCount()); } @@ -505,7 +549,7 @@ bool CDeterministicMNManager::ProcessBlock(const CBlock& block, const CBlockInde // Don't hold cs while calling signals if (diff.HasChanges()) { GetMainSignals().NotifyMasternodeListChanged(false, oldList, diff); - uiInterface.NotifyMasternodeListChanged(); + uiInterface.NotifyMasternodeListChanged(newList); } if (nHeight == consensusParams.DIP0003EnforcementHeight) { @@ -537,8 +581,8 @@ bool CDeterministicMNManager::UndoBlock(const CBlock& block, const CBlockIndex* if (diff.HasChanges()) { // need to call this before erasing - curList = GetListForBlock(blockHash); - prevList = GetListForBlock(pindex->pprev->GetBlockHash()); + curList = GetListForBlock(pindex); + prevList = GetListForBlock(pindex->pprev); } evoDb.Erase(std::make_pair(DB_LIST_DIFF, blockHash)); @@ -550,7 +594,7 @@ bool CDeterministicMNManager::UndoBlock(const CBlock& block, const CBlockIndex* if (diff.HasChanges()) { auto inversedDiff = curList.BuildDiff(prevList); GetMainSignals().NotifyMasternodeListChanged(true, curList, inversedDiff); - uiInterface.NotifyMasternodeListChanged(); + uiInterface.NotifyMasternodeListChanged(prevList); } const auto& consensusParams = Params().GetConsensus(); @@ -565,8 +609,7 @@ void CDeterministicMNManager::UpdatedBlockTip(const CBlockIndex* pindex) { LOCK(cs); - tipHeight = pindex->nHeight; - tipBlockHash = pindex->GetBlockHash(); + tipIndex = pindex; } bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const CBlockIndex* pindexPrev, CValidationState& _state, CDeterministicMNList& mnListRet, bool debugLogs) @@ -575,7 +618,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C int nHeight = pindexPrev->nHeight + 1; - CDeterministicMNList oldList = GetListForBlock(pindexPrev->GetBlockHash()); + CDeterministicMNList oldList = GetListForBlock(pindexPrev); CDeterministicMNList newList = oldList; newList.SetBlockHash(uint256()); // we can't know the final block hash, so better not return a (invalid) block hash newList.SetHeight(nHeight); @@ -619,6 +662,8 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C auto dmn = std::make_shared(); dmn->proTxHash = tx.GetHash(); + dmn->internalId = newList.GetTotalRegisteredCount(); + newList.SetTotalRegisteredCount(newList.GetTotalRegisteredCount() + 1); // collateralOutpoint is either pointing to an external collateral or to the ProRegTx itself if (proTx.collateralOutpoint.hash.IsNull()) { @@ -692,7 +737,7 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C if (newState->nPoSeBanHeight != -1) { // only revive when all keys are set - if (newState->pubKeyOperator.IsValid() && !newState->keyIDVoting.IsNull() && !newState->keyIDOwner.IsNull()) { + if (newState->pubKeyOperator.Get().IsValid() && !newState->keyIDVoting.IsNull() && !newState->keyIDOwner.IsNull()) { newState->nPoSePenalty = 0; newState->nPoSeBanHeight = -1; newState->nPoSeRevivedHeight = nHeight; @@ -720,12 +765,12 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C return _state.DoS(100, false, REJECT_INVALID, "bad-protx-hash"); } auto newState = std::make_shared(*dmn->pdmnState); - if (newState->pubKeyOperator != proTx.pubKeyOperator) { + if (newState->pubKeyOperator.Get() != proTx.pubKeyOperator) { // reset all operator related fields and put MN into PoSe-banned state in case the operator key changes newState->ResetOperatorFields(); newState->BanIfNotBanned(nHeight); } - newState->pubKeyOperator = proTx.pubKeyOperator; + newState->pubKeyOperator.Set(proTx.pubKeyOperator); newState->keyIDVoting = proTx.keyIDVoting; newState->scriptPayout = proTx.scriptPayout; @@ -762,7 +807,15 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C assert(false); // this should have been handled already } if (!qc.commitment.IsNull()) { - HandleQuorumCommitment(qc.commitment, newList, debugLogs); + const auto& params = Params().GetConsensus().llmqs.at((Consensus::LLMQType)qc.commitment.llmqType); + int quorumHeight = qc.nHeight - (qc.nHeight % params.dkgInterval); + auto quorumIndex = pindexPrev->GetAncestor(quorumHeight); + if (!quorumIndex || quorumIndex->GetBlockHash() != qc.commitment.quorumHash) { + // we should actually never get into this case as validation should have catched it...but lets be sure + return _state.DoS(100, false, REJECT_INVALID, "bad-qc-quorum-hash"); + } + + HandleQuorumCommitment(qc.commitment, quorumIndex, newList, debugLogs); } } } @@ -798,11 +851,11 @@ bool CDeterministicMNManager::BuildNewListFromBlock(const CBlock& block, const C return true; } -void CDeterministicMNManager::HandleQuorumCommitment(llmq::CFinalCommitment& qc, CDeterministicMNList& mnList, bool debugLogs) +void CDeterministicMNManager::HandleQuorumCommitment(llmq::CFinalCommitment& qc, const CBlockIndex* pindexQuorum, CDeterministicMNList& mnList, bool debugLogs) { // The commitment has already been validated at this point so it's safe to use members of it - auto members = llmq::CLLMQUtils::GetAllQuorumMembers((Consensus::LLMQType)qc.llmqType, qc.quorumHash); + auto members = llmq::CLLMQUtils::GetAllQuorumMembers((Consensus::LLMQType)qc.llmqType, pindexQuorum); for (size_t i = 0; i < members.size(); i++) { if (!mnList.HasMN(members[i]->proTxHash)) { @@ -835,58 +888,60 @@ void CDeterministicMNManager::DecreasePoSePenalties(CDeterministicMNList& mnList } } -CDeterministicMNList CDeterministicMNManager::GetListForBlock(const uint256& blockHash) +CDeterministicMNList CDeterministicMNManager::GetListForBlock(const CBlockIndex* pindex) { LOCK(cs); - auto it = mnListsCache.find(blockHash); - if (it != mnListsCache.end()) { - return it->second; - } - - uint256 blockHashTmp = blockHash; CDeterministicMNList snapshot; - std::list listDiff; + std::list> listDiff; while (true) { // try using cache before reading from disk - it = mnListsCache.find(blockHashTmp); + auto it = mnListsCache.find(pindex->GetBlockHash()); if (it != mnListsCache.end()) { snapshot = it->second; break; } - if (evoDb.Read(std::make_pair(DB_LIST_SNAPSHOT, blockHashTmp), snapshot)) { + if (evoDb.Read(std::make_pair(DB_LIST_SNAPSHOT, pindex->GetBlockHash()), snapshot)) { + mnListsCache.emplace(pindex->GetBlockHash(), snapshot); break; } CDeterministicMNListDiff diff; - if (!evoDb.Read(std::make_pair(DB_LIST_DIFF, blockHashTmp), diff)) { - snapshot = CDeterministicMNList(blockHashTmp, -1); + if (!evoDb.Read(std::make_pair(DB_LIST_DIFF, pindex->GetBlockHash()), diff)) { + snapshot = CDeterministicMNList(pindex->GetBlockHash(), -1, 0); + mnListsCache.emplace(pindex->GetBlockHash(), snapshot); break; } - listDiff.emplace_front(diff); - blockHashTmp = diff.prevBlockHash; + listDiff.emplace_front(pindex, std::move(diff)); + pindex = pindex->pprev; } - for (const auto& diff : listDiff) { + for (const auto& p : listDiff) { + auto diffIndex = p.first; + auto& diff = p.second; if (diff.HasChanges()) { - snapshot = snapshot.ApplyDiff(diff); + snapshot = snapshot.ApplyDiff(diffIndex, diff); } else { - snapshot.SetBlockHash(diff.blockHash); - snapshot.SetHeight(diff.nHeight); + snapshot.SetBlockHash(diffIndex->GetBlockHash()); + snapshot.SetHeight(diffIndex->nHeight); } + + mnListsCache.emplace(diffIndex->GetBlockHash(), snapshot); } - mnListsCache.emplace(blockHash, snapshot); return snapshot; } CDeterministicMNList CDeterministicMNManager::GetListAtChainTip() { LOCK(cs); - return GetListForBlock(tipBlockHash); + if (!tipIndex) { + return {}; + } + return GetListForBlock(tipIndex); } bool CDeterministicMNManager::IsProTxWithCollateral(const CTransactionRef& tx, uint32_t n) @@ -916,7 +971,7 @@ bool CDeterministicMNManager::IsDIP3Enforced(int nHeight) LOCK(cs); if (nHeight == -1) { - nHeight = tipHeight; + nHeight = tipIndex->nHeight; } return nHeight >= Params().GetConsensus().DIP0003EnforcementHeight; @@ -936,3 +991,115 @@ void CDeterministicMNManager::CleanupCache(int nHeight) mnListsCache.erase(h); } } + +bool CDeterministicMNManager::UpgradeDiff(CDBBatch& batch, const CBlockIndex* pindexNext, const CDeterministicMNList& curMNList, CDeterministicMNList& newMNList) +{ + CDataStream oldDiffData(SER_DISK, CLIENT_VERSION); + if (!evoDb.GetRawDB().ReadDataStream(std::make_pair(DB_LIST_DIFF, pindexNext->GetBlockHash()), oldDiffData)) { + LogPrintf("CDeterministicMNManager::%s -- no diff found for %s\n", __func__, pindexNext->GetBlockHash().ToString()); + newMNList = curMNList; + newMNList.SetBlockHash(pindexNext->GetBlockHash()); + newMNList.SetHeight(pindexNext->nHeight); + return false; + } + + CDeterministicMNListDiff_OldFormat oldDiff; + oldDiffData >> oldDiff; + + CDeterministicMNListDiff newDiff; + size_t addedCount = 0; + for (auto& p : oldDiff.addedMNs) { + auto dmn = std::make_shared(*p.second); + dmn->internalId = curMNList.GetTotalRegisteredCount() + addedCount; + newDiff.addedMNs.emplace_back(dmn); + + addedCount++; + } + for (auto& p : oldDiff.removedMns) { + auto dmn = curMNList.GetMN(p); + newDiff.removedMns.emplace(dmn->internalId); + } + + // applies added/removed MNs + newMNList = curMNList.ApplyDiff(pindexNext, newDiff); + + // manually apply updated MNs and calc new state diffs + for (auto& p : oldDiff.updatedMNs) { + auto oldMN = newMNList.GetMN(p.first); + newMNList.UpdateMN(p.first, p.second); + auto newMN = newMNList.GetMN(p.first); + assert(oldMN && newMN); + + newDiff.updatedMNs.emplace(std::piecewise_construct, + std::forward_as_tuple(oldMN->internalId), + std::forward_as_tuple(*oldMN->pdmnState, *newMN->pdmnState)); + } + + batch.Write(std::make_pair(DB_LIST_DIFF, pindexNext->GetBlockHash()), newDiff); + + return true; +} + +// TODO this can be completely removed in a future version +void CDeterministicMNManager::UpgradeDBIfNeeded() +{ + LOCK(cs_main); + + if (chainActive.Tip() == nullptr) { + return; + } + + if (evoDb.GetRawDB().Exists(EVODB_BEST_BLOCK)) { + return; + } + + // Removing the old EVODB_BEST_BLOCK value early results in older version to crash immediately, even if the upgrade + // process is cancelled in-between. But if the new version sees that the old EVODB_BEST_BLOCK is already removed, + // then we must assume that the upgrade process was already running before but was interrupted. + if (chainActive.Height() > 1 && !evoDb.GetRawDB().Exists(std::string("b_b"))) { + LogPrintf("CDeterministicMNManager::%s -- ERROR, upgrade process was interrupted and can't be continued. You need to reindex now.\n", __func__); + } + evoDb.GetRawDB().Erase(std::string("b_b")); + + if (chainActive.Height() < Params().GetConsensus().DIP0003Height) { + // not reached DIP3 height yet, so no upgrade needed + auto dbTx = evoDb.BeginTransaction(); + evoDb.WriteBestBlock(chainActive.Tip()->GetBlockHash()); + dbTx->Commit(); + return; + } + + LogPrintf("CDeterministicMNManager::%s -- upgrading DB to use compact diffs\n", __func__); + + CDBBatch batch(evoDb.GetRawDB()); + + CDeterministicMNList curMNList; + curMNList.SetHeight(Params().GetConsensus().DIP0003Height - 1); + curMNList.SetBlockHash(chainActive[Params().GetConsensus().DIP0003Height - 1]->GetBlockHash()); + + for (int nHeight = Params().GetConsensus().DIP0003Height; nHeight <= chainActive.Height(); nHeight++) { + auto pindex = chainActive[nHeight]; + + CDeterministicMNList newMNList; + UpgradeDiff(batch, pindex, curMNList, newMNList); + + if ((nHeight % SNAPSHOT_LIST_PERIOD) == 0) { + batch.Write(std::make_pair(DB_LIST_SNAPSHOT, pindex->GetBlockHash()), newMNList); + evoDb.GetRawDB().WriteBatch(batch); + batch.Clear(); + } + + curMNList = newMNList; + } + + evoDb.GetRawDB().WriteBatch(batch); + + LogPrintf("CDeterministicMNManager::%s -- done upgrading\n", __func__); + + // Writing EVODB_BEST_BLOCK (which is b_b2 now) marks the DB as upgraded + auto dbTx = evoDb.BeginTransaction(); + evoDb.WriteBestBlock(chainActive.Tip()->GetBlockHash()); + dbTx->Commit(); + + evoDb.GetRawDB().CompactFull(); +} diff --git a/src/evo/deterministicmns.h b/src/evo/deterministicmns.h index c0d6f38ca..dabac46f2 100755 --- a/src/evo/deterministicmns.h +++ b/src/evo/deterministicmns.h @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 The Axe Core developers +// Copyright (c) 2018-2019 The Dash Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -44,7 +44,7 @@ class CDeterministicMNState uint256 confirmedHashWithProRegTxHash; CKeyID keyIDOwner; - CBLSPublicKey pubKeyOperator; + CBLSLazyPublicKey pubKeyOperator; CKeyID keyIDVoting; CService addr; CScript scriptPayout; @@ -55,7 +55,7 @@ class CDeterministicMNState CDeterministicMNState(const CProRegTx& proTx) { keyIDOwner = proTx.keyIDOwner; - pubKeyOperator = proTx.pubKeyOperator; + pubKeyOperator.Set(proTx.pubKeyOperator); keyIDVoting = proTx.keyIDVoting; addr = proTx.addr; scriptPayout = proTx.scriptPayout; @@ -83,13 +83,13 @@ class CDeterministicMNState READWRITE(pubKeyOperator); READWRITE(keyIDVoting); READWRITE(addr); - READWRITE(*(CScriptBase*)(&scriptPayout)); - READWRITE(*(CScriptBase*)(&scriptOperatorPayout)); + READWRITE(scriptPayout); + READWRITE(scriptOperatorPayout); } void ResetOperatorFields() { - pubKeyOperator = CBLSPublicKey(); + pubKeyOperator.Set(CBLSPublicKey()); addr = CService(); scriptOperatorPayout = CScript(); nRevocationReason = CProUpRevTx::REASON_NOT_SPECIFIED; @@ -109,35 +109,81 @@ class CDeterministicMNState h.Finalize(confirmedHashWithProRegTxHash.begin()); } - bool operator==(const CDeterministicMNState& rhs) const +public: + std::string ToString() const; + void ToJson(UniValue& obj) const; +}; +typedef std::shared_ptr CDeterministicMNStatePtr; +typedef std::shared_ptr CDeterministicMNStateCPtr; + +class CDeterministicMNStateDiff +{ +public: + enum Field : uint32_t { + Field_nRegisteredHeight = 0x0001, + Field_nLastPaidHeight = 0x0002, + Field_nPoSePenalty = 0x0004, + Field_nPoSeRevivedHeight = 0x0008, + Field_nPoSeBanHeight = 0x0010, + Field_nRevocationReason = 0x0020, + Field_confirmedHash = 0x0040, + Field_confirmedHashWithProRegTxHash = 0x0080, + Field_keyIDOwner = 0x0100, + Field_pubKeyOperator = 0x0200, + Field_keyIDVoting = 0x0400, + Field_addr = 0x0800, + Field_scriptPayout = 0x1000, + Field_scriptOperatorPayout = 0x2000, + }; + +#define DMN_STATE_DIFF_ALL_FIELDS \ + DMN_STATE_DIFF_LINE(nRegisteredHeight) \ + DMN_STATE_DIFF_LINE(nLastPaidHeight) \ + DMN_STATE_DIFF_LINE(nPoSePenalty) \ + DMN_STATE_DIFF_LINE(nPoSeRevivedHeight) \ + DMN_STATE_DIFF_LINE(nPoSeBanHeight) \ + DMN_STATE_DIFF_LINE(nRevocationReason) \ + DMN_STATE_DIFF_LINE(confirmedHash) \ + DMN_STATE_DIFF_LINE(confirmedHashWithProRegTxHash) \ + DMN_STATE_DIFF_LINE(keyIDOwner) \ + DMN_STATE_DIFF_LINE(pubKeyOperator) \ + DMN_STATE_DIFF_LINE(keyIDVoting) \ + DMN_STATE_DIFF_LINE(addr) \ + DMN_STATE_DIFF_LINE(scriptPayout) \ + DMN_STATE_DIFF_LINE(scriptOperatorPayout) + +public: + uint32_t fields{0}; + // we reuse the state class, but only the members as noted by fields are valid + CDeterministicMNState state; + +public: + CDeterministicMNStateDiff() {} + CDeterministicMNStateDiff(const CDeterministicMNState& a, const CDeterministicMNState& b) { - return nRegisteredHeight == rhs.nRegisteredHeight && - nLastPaidHeight == rhs.nLastPaidHeight && - nPoSePenalty == rhs.nPoSePenalty && - nPoSeRevivedHeight == rhs.nPoSeRevivedHeight && - nPoSeBanHeight == rhs.nPoSeBanHeight && - nRevocationReason == rhs.nRevocationReason && - confirmedHash == rhs.confirmedHash && - confirmedHashWithProRegTxHash == rhs.confirmedHashWithProRegTxHash && - keyIDOwner == rhs.keyIDOwner && - pubKeyOperator == rhs.pubKeyOperator && - keyIDVoting == rhs.keyIDVoting && - addr == rhs.addr && - scriptPayout == rhs.scriptPayout && - scriptOperatorPayout == rhs.scriptOperatorPayout; +#define DMN_STATE_DIFF_LINE(f) if (a.f != b.f) { state.f = b.f; fields |= Field_##f; } + DMN_STATE_DIFF_ALL_FIELDS +#undef DMN_STATE_DIFF_LINE } - bool operator!=(const CDeterministicMNState& rhs) const + ADD_SERIALIZE_METHODS; + + template + inline void SerializationOp(Stream& s, Operation ser_action) { - return !(rhs == *this); + READWRITE(VARINT(fields)); +#define DMN_STATE_DIFF_LINE(f) if (fields & Field_##f) READWRITE(state.f); + DMN_STATE_DIFF_ALL_FIELDS +#undef DMN_STATE_DIFF_LINE } -public: - std::string ToString() const; - void ToJson(UniValue& obj) const; + void ApplyToState(CDeterministicMNState& target) const + { +#define DMN_STATE_DIFF_LINE(f) if (fields & Field_##f) target.f = state.f; + DMN_STATE_DIFF_ALL_FIELDS +#undef DMN_STATE_DIFF_LINE + } }; -typedef std::shared_ptr CDeterministicMNStatePtr; -typedef std::shared_ptr CDeterministicMNStateCPtr; class CDeterministicMN { @@ -150,22 +196,36 @@ class CDeterministicMN } uint256 proTxHash; + uint64_t internalId{std::numeric_limits::max()}; COutPoint collateralOutpoint; uint16_t nOperatorReward; CDeterministicMNStateCPtr pdmnState; public: - ADD_SERIALIZE_METHODS; - template - inline void SerializationOp(Stream& s, Operation ser_action) + inline void SerializationOp(Stream& s, Operation ser_action, bool oldFormat) { READWRITE(proTxHash); + if (!oldFormat) { + READWRITE(VARINT(internalId)); + } READWRITE(collateralOutpoint); READWRITE(nOperatorReward); READWRITE(pdmnState); } + template + void Serialize(Stream& s) const + { + NCONST_PTR(this)->SerializationOp(s, CSerActionSerialize(), false); + } + + template + void Unserialize(Stream& s, bool oldFormat = false) + { + SerializationOp(s, CSerActionUnserialize(), oldFormat); + } + public: std::string ToString() const; void ToJson(UniValue& obj) const; @@ -195,43 +255,78 @@ void UnserializeImmerMap(Stream& is, immer::map& m) } } +// For some reason the compiler is not able to choose the correct Serialize/Deserialize methods without a specialized +// version of SerReadWrite. It otherwise always chooses the version that calls a.Serialize() +template +inline void SerReadWrite(Stream& s, const immer::map& m, CSerActionSerialize ser_action) +{ + ::SerializeImmerMap(s, m); +} + +template +inline void SerReadWrite(Stream& s, immer::map& obj, CSerActionUnserialize ser_action) +{ + ::UnserializeImmerMap(s, obj); +} + + class CDeterministicMNList { public: typedef immer::map MnMap; + typedef immer::map MnInternalIdMap; typedef immer::map > MnUniquePropertyMap; private: uint256 blockHash; int nHeight{-1}; + uint32_t nTotalRegisteredCount{0}; MnMap mnMap; + MnInternalIdMap mnInternalIdMap; // map of unique properties like address and keys // we keep track of this as checking for duplicates would otherwise be painfully slow - // the entries in the map are ref counted as some properties might appear multiple times per MN (e.g. operator/owner keys) MnUniquePropertyMap mnUniquePropertyMap; public: CDeterministicMNList() {} - explicit CDeterministicMNList(const uint256& _blockHash, int _height) : + explicit CDeterministicMNList(const uint256& _blockHash, int _height, uint32_t _totalRegisteredCount) : blockHash(_blockHash), - nHeight(_height) + nHeight(_height), + nTotalRegisteredCount(_totalRegisteredCount) { } - ADD_SERIALIZE_METHODS; - template - inline void SerializationOp(Stream& s, Operation ser_action) + inline void SerializationOpBase(Stream& s, Operation ser_action) { READWRITE(blockHash); READWRITE(nHeight); - if (ser_action.ForRead()) { - UnserializeImmerMap(s, mnMap); - UnserializeImmerMap(s, mnUniquePropertyMap); - } else { - SerializeImmerMap(s, mnMap); - SerializeImmerMap(s, mnUniquePropertyMap); + READWRITE(nTotalRegisteredCount); + } + + template + void Serialize(Stream& s) const + { + NCONST_PTR(this)->SerializationOpBase(s, CSerActionSerialize()); + // Serialize the map as a vector + WriteCompactSize(s, mnMap.size()); + for (const auto& p : mnMap) { + s << *p.second; + } + } + + template + void Unserialize(Stream& s) { + mnMap = MnMap(); + mnUniquePropertyMap = MnUniquePropertyMap(); + mnInternalIdMap = MnInternalIdMap(); + + SerializationOpBase(s, CSerActionUnserialize()); + + size_t cnt = ReadCompactSize(s); + for (size_t i = 0; i < cnt; i++) { + AddMN(std::make_shared(deserialize, s)); } } @@ -279,6 +374,14 @@ class CDeterministicMNList { nHeight = _height; } + uint32_t GetTotalRegisteredCount() const + { + return nTotalRegisteredCount; + } + void SetTotalRegisteredCount(uint32_t _count) + { + nTotalRegisteredCount = _count; + } bool IsMNValid(const uint256& proTxHash) const; bool IsMNPoSeBanned(const uint256& proTxHash) const; @@ -306,7 +409,9 @@ class CDeterministicMNList CDeterministicMNCPtr GetMNByOperatorKey(const CBLSPublicKey& pubKey); CDeterministicMNCPtr GetMNByCollateral(const COutPoint& collateralOutpoint) const; CDeterministicMNCPtr GetValidMNByCollateral(const COutPoint& collateralOutpoint) const; + CDeterministicMNCPtr GetMNByService(const CService& service) const; CDeterministicMNCPtr GetValidMNByService(const CService& service) const; + CDeterministicMNCPtr GetMNByInternalId(uint64_t internalId) const; CDeterministicMNCPtr GetMNPayee() const; /** @@ -361,10 +466,12 @@ class CDeterministicMNList CDeterministicMNListDiff BuildDiff(const CDeterministicMNList& to) const; CSimplifiedMNListDiff BuildSimplifiedDiff(const CDeterministicMNList& to) const; - CDeterministicMNList ApplyDiff(const CDeterministicMNListDiff& diff) const; + CDeterministicMNList ApplyDiff(const CBlockIndex* pindex, const CDeterministicMNListDiff& diff) const; void AddMN(const CDeterministicMNCPtr& dmn); + void UpdateMN(const CDeterministicMNCPtr& oldDmn, const CDeterministicMNStateCPtr& pdmnState); void UpdateMN(const uint256& proTxHash, const CDeterministicMNStateCPtr& pdmnState); + void UpdateMN(const CDeterministicMNCPtr& oldDmn, const CDeterministicMNStateDiff& stateDiff); void RemoveMN(const uint256& proTxHash); template @@ -434,25 +541,48 @@ class CDeterministicMNList class CDeterministicMNListDiff { public: - uint256 prevBlockHash; - uint256 blockHash; - int nHeight{-1}; - std::map addedMNs; - std::map updatedMNs; - std::set removedMns; + std::vector addedMNs; + // keys are all relating to the internalId of MNs + std::map updatedMNs; + std::set removedMns; public: - ADD_SERIALIZE_METHODS; + template + void Serialize(Stream& s) const + { + s << addedMNs; + WriteCompactSize(s, updatedMNs.size()); + for (const auto& p : updatedMNs) { + WriteVarInt(s, p.first); + s << p.second; + } + WriteCompactSize(s, removedMns.size()); + for (const auto& p : removedMns) { + WriteVarInt(s, p); + } + } - template - inline void SerializationOp(Stream& s, Operation ser_action) + template + void Unserialize(Stream& s) { - READWRITE(prevBlockHash); - READWRITE(blockHash); - READWRITE(nHeight); - READWRITE(addedMNs); - READWRITE(updatedMNs); - READWRITE(removedMns); + updatedMNs.clear(); + removedMns.clear(); + + size_t tmp; + uint64_t tmp2; + s >> addedMNs; + tmp = ReadCompactSize(s); + for (size_t i = 0; i < tmp; i++) { + CDeterministicMNStateDiff diff; + tmp2 = ReadVarInt(s); + s >> diff; + updatedMNs.emplace(tmp2, std::move(diff)); + } + tmp = ReadCompactSize(s); + for (size_t i = 0; i < tmp; i++) { + tmp2 = ReadVarInt(s); + removedMns.emplace(tmp2); + } } public: @@ -462,6 +592,37 @@ class CDeterministicMNListDiff } }; +// TODO can be removed in a future version +class CDeterministicMNListDiff_OldFormat +{ +public: + uint256 prevBlockHash; + uint256 blockHash; + int nHeight{-1}; + std::map addedMNs; + std::map updatedMNs; + std::set removedMns; + +public: + template + void Unserialize(Stream& s) { + addedMNs.clear(); + s >> prevBlockHash; + s >> blockHash; + s >> nHeight; + size_t cnt = ReadCompactSize(s); + for (size_t i = 0; i < cnt; i++) { + uint256 proTxHash; + auto dmn = std::make_shared(); + s >> proTxHash; + dmn->Unserialize(s, true); + addedMNs.emplace(proTxHash, dmn); + } + s >> updatedMNs; + s >> removedMns; + } +}; + class CDeterministicMNManager { static const int SNAPSHOT_LIST_PERIOD = 576; // once per day @@ -474,8 +635,7 @@ class CDeterministicMNManager CEvoDB& evoDb; std::map mnListsCache; - int tipHeight{-1}; - uint256 tipBlockHash; + const CBlockIndex* tipIndex{nullptr}; public: CDeterministicMNManager(CEvoDB& _evoDb); @@ -487,10 +647,10 @@ class CDeterministicMNManager // the returned list will not contain the correct block hash (we can't know it yet as the coinbase TX is not updated yet) bool BuildNewListFromBlock(const CBlock& block, const CBlockIndex* pindexPrev, CValidationState& state, CDeterministicMNList& mnListRet, bool debugLogs); - void HandleQuorumCommitment(llmq::CFinalCommitment& qc, CDeterministicMNList& mnList, bool debugLogs); + void HandleQuorumCommitment(llmq::CFinalCommitment& qc, const CBlockIndex* pindexQuorum, CDeterministicMNList& mnList, bool debugLogs); void DecreasePoSePenalties(CDeterministicMNList& mnList); - CDeterministicMNList GetListForBlock(const uint256& blockHash); + CDeterministicMNList GetListForBlock(const CBlockIndex* pindex); CDeterministicMNList GetListAtChainTip(); // Test if given TX is a ProRegTx which also contains the collateral at index n @@ -498,6 +658,11 @@ class CDeterministicMNManager bool IsDIP3Enforced(int nHeight = -1); +public: + // TODO these can all be removed in a future version + bool UpgradeDiff(CDBBatch& batch, const CBlockIndex* pindexNext, const CDeterministicMNList& curMNList, CDeterministicMNList& newMNList); + void UpgradeDBIfNeeded(); + private: void CleanupCache(int nHeight); }; diff --git a/src/evo/evodb.h b/src/evo/evodb.h index f27d9d5f7..724036644 100755 --- a/src/evo/evodb.h +++ b/src/evo/evodb.h @@ -9,7 +9,9 @@ #include "sync.h" #include "uint256.h" -static const std::string EVODB_BEST_BLOCK = "b_b"; +// "b_b" was used in the initial version of deterministic MN storage +// "b_b2" was used after compact diffs were introduced +static const std::string EVODB_BEST_BLOCK = "b_b2"; class CEvoDB { @@ -73,6 +75,11 @@ class CEvoDB return db; } + size_t GetMemoryUsage() + { + return rootDBTransaction.GetMemoryUsage(); + } + bool CommitRootTransaction(); bool VerifyBestBlock(const uint256& hash); diff --git a/src/evo/mnauth.cpp b/src/evo/mnauth.cpp index 553aa1e81..75b02b506 100755 --- a/src/evo/mnauth.cpp +++ b/src/evo/mnauth.cpp @@ -4,9 +4,9 @@ #include "mnauth.h" -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "evo/deterministicmns.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "net.h" #include "net_processing.h" #include "netmessagemaker.h" @@ -72,7 +72,7 @@ void CMNAuth::ProcessMessage(CNode* pnode, const std::string& strCommand, CDataS } auto mnList = deterministicMNManager->GetListAtChainTip(); - auto dmn = mnList.GetValidMN(mnauth.proRegTxHash); + auto dmn = mnList.GetMN(mnauth.proRegTxHash); if (!dmn) { LOCK(cs_main); // in case he was unlucky and not up to date, just let him be connected as a regular node, which gives him @@ -89,7 +89,7 @@ void CMNAuth::ProcessMessage(CNode* pnode, const std::string& strCommand, CDataS signHash = ::SerializeHash(std::make_tuple(dmn->pdmnState->pubKeyOperator, pnode->sentMNAuthChallenge, !pnode->fInbound)); } - if (!mnauth.sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator, signHash)) { + if (!mnauth.sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator.Get(), signHash)) { LOCK(cs_main); // Same as above, MN seems to not know about his fate yet, so give him a chance to update. If this is a // malicious actor (DoSing us), we'll ban him soon. @@ -127,13 +127,17 @@ void CMNAuth::NotifyMasternodeListChanged(bool undo, const CDeterministicMNList& if (pnode->verifiedProRegTxHash.IsNull()) { return; } + auto verifiedDmn = oldMNList.GetMN(pnode->verifiedProRegTxHash); + if (!verifiedDmn) { + return; + } bool doRemove = false; - if (diff.removedMns.count(pnode->verifiedProRegTxHash)) { + if (diff.removedMns.count(verifiedDmn->internalId)) { doRemove = true; } else { - auto it = diff.updatedMNs.find(pnode->verifiedProRegTxHash); + auto it = diff.updatedMNs.find(verifiedDmn->internalId); if (it != diff.updatedMNs.end()) { - if (it->second->pubKeyOperator.GetHash() != pnode->verifiedPubKeyHash) { + if ((it->second.fields & CDeterministicMNStateDiff::Field_pubKeyOperator) && it->second.state.pubKeyOperator.GetHash() != pnode->verifiedPubKeyHash) { doRemove = true; } } diff --git a/src/evo/providertx.cpp b/src/evo/providertx.cpp index 41a129678..02dc664e7 100755 --- a/src/evo/providertx.cpp +++ b/src/evo/providertx.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 The Axe Core developers +// Copyright (c) 2018-2019 The Dash Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -174,7 +174,7 @@ bool CheckProRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CValid } if (pindexPrev) { - auto mnList = deterministicMNManager->GetListForBlock(pindexPrev->GetBlockHash()); + auto mnList = deterministicMNManager->GetListForBlock(pindexPrev); // only allow reusing of addresses when it's for the same collateral (which replaces the old MN) if (mnList.HasUniqueProperty(ptx.addr) && mnList.GetUniquePropertyMN(ptx.addr)->collateralOutpoint != collateralOutpoint) { @@ -232,7 +232,7 @@ bool CheckProUpServTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVa } if (pindexPrev) { - auto mnList = deterministicMNManager->GetListForBlock(pindexPrev->GetBlockHash()); + auto mnList = deterministicMNManager->GetListForBlock(pindexPrev); auto mn = mnList.GetMN(ptx.proTxHash); if (!mn) { return state.DoS(100, false, REJECT_INVALID, "bad-protx-hash"); @@ -257,7 +257,7 @@ bool CheckProUpServTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVa if (!CheckInputsHash(tx, ptx, state)) { return false; } - if (!CheckHashSig(ptx, mn->pdmnState->pubKeyOperator, state)) { + if (!CheckHashSig(ptx, mn->pdmnState->pubKeyOperator.Get(), state)) { return false; } } @@ -297,7 +297,7 @@ bool CheckProUpRegTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVal } if (pindexPrev) { - auto mnList = deterministicMNManager->GetListForBlock(pindexPrev->GetBlockHash()); + auto mnList = deterministicMNManager->GetListForBlock(pindexPrev); auto dmn = mnList.GetMN(ptx.proTxHash); if (!dmn) { return state.DoS(100, false, REJECT_INVALID, "bad-protx-hash"); @@ -369,14 +369,14 @@ bool CheckProUpRevTx(const CTransaction& tx, const CBlockIndex* pindexPrev, CVal } if (pindexPrev) { - auto mnList = deterministicMNManager->GetListForBlock(pindexPrev->GetBlockHash()); + auto mnList = deterministicMNManager->GetListForBlock(pindexPrev); auto dmn = mnList.GetMN(ptx.proTxHash); if (!dmn) return state.DoS(100, false, REJECT_INVALID, "bad-protx-hash"); if (!CheckInputsHash(tx, ptx, state)) return false; - if (!CheckHashSig(ptx, dmn->pdmnState->pubKeyOperator, state)) + if (!CheckHashSig(ptx, dmn->pdmnState->pubKeyOperator.Get(), state)) return false; } diff --git a/src/evo/providertx.h b/src/evo/providertx.h index f4a0cdaea..029ef8f2e 100755 --- a/src/evo/providertx.h +++ b/src/evo/providertx.h @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 The Axe Core developers +// Copyright (c) 2018 The Dash Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -49,7 +49,7 @@ class CProRegTx READWRITE(pubKeyOperator); READWRITE(keyIDVoting); READWRITE(nOperatorReward); - READWRITE(*(CScriptBase*)(&scriptPayout)); + READWRITE(scriptPayout); READWRITE(inputsHash); if (!(s.GetType() & SER_GETHASH)) { READWRITE(vchSig); @@ -86,7 +86,7 @@ class CProUpServTx READWRITE(nVersion); READWRITE(proTxHash); READWRITE(addr); - READWRITE(*(CScriptBase*)(&scriptOperatorPayout)); + READWRITE(scriptOperatorPayout); READWRITE(inputsHash); if (!(s.GetType() & SER_GETHASH)) { READWRITE(sig); @@ -124,7 +124,7 @@ class CProUpRegTx READWRITE(nMode); READWRITE(pubKeyOperator); READWRITE(keyIDVoting); - READWRITE(*(CScriptBase*)(&scriptPayout)); + READWRITE(scriptPayout); READWRITE(inputsHash); if (!(s.GetType() & SER_GETHASH)) { READWRITE(vchSig); diff --git a/src/evo/simplifiedmns.cpp b/src/evo/simplifiedmns.cpp index cd9f34c80..db272d02e 100755 --- a/src/evo/simplifiedmns.cpp +++ b/src/evo/simplifiedmns.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2019 The Axe Core developers +// Copyright (c) 2017-2019 The Dash Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -37,7 +37,7 @@ uint256 CSimplifiedMNListEntry::CalcHash() const std::string CSimplifiedMNListEntry::ToString() const { return strprintf("CSimplifiedMNListEntry(proRegTxHash=%s, confirmedHash=%s, service=%s, pubKeyOperator=%s, votingAddress=%s, isValid=%d)", - proRegTxHash.ToString(), confirmedHash.ToString(), service.ToString(false), pubKeyOperator.ToString(), CBitcoinAddress(keyIDVoting).ToString(), isValid); + proRegTxHash.ToString(), confirmedHash.ToString(), service.ToString(false), pubKeyOperator.Get().ToString(), CBitcoinAddress(keyIDVoting).ToString(), isValid); } void CSimplifiedMNListEntry::ToJson(UniValue& obj) const @@ -47,30 +47,34 @@ void CSimplifiedMNListEntry::ToJson(UniValue& obj) const obj.push_back(Pair("proRegTxHash", proRegTxHash.ToString())); obj.push_back(Pair("confirmedHash", confirmedHash.ToString())); obj.push_back(Pair("service", service.ToString(false))); - obj.push_back(Pair("pubKeyOperator", pubKeyOperator.ToString())); + obj.push_back(Pair("pubKeyOperator", pubKeyOperator.Get().ToString())); obj.push_back(Pair("votingAddress", CBitcoinAddress(keyIDVoting).ToString())); obj.push_back(Pair("isValid", isValid)); } CSimplifiedMNList::CSimplifiedMNList(const std::vector& smlEntries) { - mnList = smlEntries; + mnList.resize(smlEntries.size()); + for (size_t i = 0; i < smlEntries.size(); i++) { + mnList[i] = std::make_unique(smlEntries[i]); + } - std::sort(mnList.begin(), mnList.end(), [&](const CSimplifiedMNListEntry& a, const CSimplifiedMNListEntry& b) { - return a.proRegTxHash.Compare(b.proRegTxHash) < 0; + std::sort(mnList.begin(), mnList.end(), [&](const std::unique_ptr& a, const std::unique_ptr& b) { + return a->proRegTxHash.Compare(b->proRegTxHash) < 0; }); } CSimplifiedMNList::CSimplifiedMNList(const CDeterministicMNList& dmnList) { - mnList.reserve(dmnList.GetAllMNsCount()); + mnList.resize(dmnList.GetAllMNsCount()); - dmnList.ForEachMN(false, [this](const CDeterministicMNCPtr& dmn) { - mnList.emplace_back(*dmn); + size_t i = 0; + dmnList.ForEachMN(false, [this, &i](const CDeterministicMNCPtr& dmn) { + mnList[i++] = std::make_unique(*dmn); }); - std::sort(mnList.begin(), mnList.end(), [&](const CSimplifiedMNListEntry& a, const CSimplifiedMNListEntry& b) { - return a.proRegTxHash.Compare(b.proRegTxHash) < 0; + std::sort(mnList.begin(), mnList.end(), [&](const std::unique_ptr& a, const std::unique_ptr& b) { + return a->proRegTxHash.Compare(b->proRegTxHash) < 0; }); } @@ -79,7 +83,7 @@ uint256 CSimplifiedMNList::CalcMerkleRoot(bool* pmutated) const std::vector leaves; leaves.reserve(mnList.size()); for (const auto& e : mnList) { - leaves.emplace_back(e.CalcHash()); + leaves.emplace_back(e->CalcHash()); } return ComputeMerkleRoot(leaves, pmutated); } @@ -213,10 +217,15 @@ bool BuildSimplifiedMNListDiff(const uint256& baseBlockHash, const uint256& bloc LOCK(deterministicMNManager->cs); - auto baseDmnList = deterministicMNManager->GetListForBlock(baseBlockHash); - auto dmnList = deterministicMNManager->GetListForBlock(blockHash); + auto baseDmnList = deterministicMNManager->GetListForBlock(baseBlockIndex); + auto dmnList = deterministicMNManager->GetListForBlock(blockIndex); mnListDiffRet = baseDmnList.BuildSimplifiedDiff(dmnList); + // We need to return the value that was provided by the other peer as it otherwise won't be able to recognize the + // response. This will usually be identical to the block found in baseBlockIndex. The only difference is when a + // null block hash was provided to get the diff from the genesis block. + mnListDiffRet.baseBlockHash = baseBlockHash; + if (!mnListDiffRet.BuildQuorumsDiff(baseBlockIndex, blockIndex)) { errorRet = strprintf("failed to build quorums diff"); return false; diff --git a/src/evo/simplifiedmns.h b/src/evo/simplifiedmns.h index 4540d832d..fffe8def9 100755 --- a/src/evo/simplifiedmns.h +++ b/src/evo/simplifiedmns.h @@ -27,7 +27,7 @@ class CSimplifiedMNListEntry uint256 proRegTxHash; uint256 confirmedHash; CService service; - CBLSPublicKey pubKeyOperator; + CBLSLazyPublicKey pubKeyOperator; CKeyID keyIDVoting; bool isValid; @@ -74,7 +74,7 @@ class CSimplifiedMNListEntry class CSimplifiedMNList { public: - std::vector mnList; + std::vector> mnList; public: CSimplifiedMNList() {} diff --git a/src/governance-classes.cpp b/src/governance/governance-classes.cpp similarity index 100% rename from src/governance-classes.cpp rename to src/governance/governance-classes.cpp diff --git a/src/governance-classes.h b/src/governance/governance-classes.h similarity index 100% rename from src/governance-classes.h rename to src/governance/governance-classes.h diff --git a/src/governance-exceptions.h b/src/governance/governance-exceptions.h similarity index 100% rename from src/governance-exceptions.h rename to src/governance/governance-exceptions.h diff --git a/src/governance-object.cpp b/src/governance/governance-object.cpp similarity index 97% rename from src/governance-object.cpp rename to src/governance/governance-object.cpp index f9763a134..7c97c21e1 100755 --- a/src/governance-object.cpp +++ b/src/governance/governance-object.cpp @@ -8,16 +8,13 @@ #include "governance-validators.h" #include "governance-vote.h" #include "governance.h" -#include "instantx.h" -#include "masternode-meta.h" -#include "masternode-sync.h" +#include "masternode/masternode-meta.h" +#include "masternode/masternode-sync.h" #include "messagesigner.h" #include "spork.h" #include "util.h" #include "validation.h" -#include "llmq/quorums_instantsend.h" - #include #include @@ -121,7 +118,7 @@ bool CGovernanceObject::ProcessVote(CNode* pfrom, } auto mnList = deterministicMNManager->GetListAtChainTip(); - auto dmn = mnList.GetValidMNByCollateral(vote.GetMasternodeOutpoint()); + auto dmn = mnList.GetMNByCollateral(vote.GetMasternodeOutpoint()); if (!dmn) { std::ostringstream ostr; @@ -235,7 +232,7 @@ void CGovernanceObject::ClearMasternodeVotes() vote_m_it it = mapCurrentMNVotes.begin(); while (it != mapCurrentMNVotes.end()) { - if (!mnList.HasValidMNByCollateral(it->first)) { + if (!mnList.HasMNByCollateral(it->first)) { fileVotes.RemoveVotesFromMasternode(it->first); mapCurrentMNVotes.erase(it++); } else { @@ -500,8 +497,8 @@ bool CGovernanceObject::IsValidLocally(std::string& strError, bool& fMissingMast } // Check that we have a valid MN signature - if (!CheckSignature(dmn->pdmnState->pubKeyOperator)) { - strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey = " + dmn->pdmnState->pubKeyOperator.ToString(); + if (!CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) { + strError = "Invalid masternode signature for: " + strOutpoint + ", pubkey = " + dmn->pdmnState->pubKeyOperator.Get().ToString(); return false; } @@ -599,8 +596,7 @@ bool CGovernanceObject::IsCollateralValid(std::string& strError, bool& fMissingC } } - if ((nConfirmationsIn < GOVERNANCE_FEE_CONFIRMATIONS) && - (!instantsend.IsLockedInstantSendTransaction(nCollateralHash) || llmq::quorumInstantSendManager->IsLocked(nCollateralHash))) { + if ((nConfirmationsIn < GOVERNANCE_FEE_CONFIRMATIONS)) { strError = strprintf("Collateral requires at least %d confirmations to be relayed throughout the network (it has only %d)", GOVERNANCE_FEE_CONFIRMATIONS, nConfirmationsIn); if (nConfirmationsIn >= GOVERNANCE_MIN_RELAY_FEE_CONFIRMATIONS) { fMissingConfirmations = true; diff --git a/src/governance-object.h b/src/governance/governance-object.h similarity index 100% rename from src/governance-object.h rename to src/governance/governance-object.h diff --git a/src/governance-validators.cpp b/src/governance/governance-validators.cpp similarity index 100% rename from src/governance-validators.cpp rename to src/governance/governance-validators.cpp diff --git a/src/governance-validators.h b/src/governance/governance-validators.h similarity index 100% rename from src/governance-validators.h rename to src/governance/governance-validators.h diff --git a/src/governance-vote.cpp b/src/governance/governance-vote.cpp similarity index 99% rename from src/governance-vote.cpp rename to src/governance/governance-vote.cpp index 6a0509432..32ece1f1a 100755 --- a/src/governance-vote.cpp +++ b/src/governance/governance-vote.cpp @@ -4,7 +4,7 @@ #include "governance-vote.h" #include "governance-object.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "messagesigner.h" #include "spork.h" #include "util.h" @@ -280,7 +280,7 @@ bool CGovernanceVote::IsValid(bool useVotingKey) const if (useVotingKey) { return CheckSignature(dmn->pdmnState->keyIDVoting); } else { - return CheckSignature(dmn->pdmnState->pubKeyOperator); + return CheckSignature(dmn->pdmnState->pubKeyOperator.Get()); } } diff --git a/src/governance-vote.h b/src/governance/governance-vote.h similarity index 100% rename from src/governance-vote.h rename to src/governance/governance-vote.h diff --git a/src/governance-votedb.cpp b/src/governance/governance-votedb.cpp similarity index 100% rename from src/governance-votedb.cpp rename to src/governance/governance-votedb.cpp diff --git a/src/governance-votedb.h b/src/governance/governance-votedb.h similarity index 100% rename from src/governance-votedb.h rename to src/governance/governance-votedb.h diff --git a/src/governance.cpp b/src/governance/governance.cpp similarity index 98% rename from src/governance.cpp rename to src/governance/governance.cpp index 9b2b98af5..d458d8ad7 100755 --- a/src/governance.cpp +++ b/src/governance/governance.cpp @@ -9,8 +9,8 @@ #include "governance-validators.h" #include "governance-vote.h" #include "init.h" -#include "masternode-meta.h" -#include "masternode-sync.h" +#include "masternode/masternode-meta.h" +#include "masternode/masternode-sync.h" #include "messagesigner.h" #include "net_processing.h" #include "netfulfilledman.h" @@ -24,7 +24,7 @@ CGovernanceManager governance; int nSubmittedFinalBudget; -const std::string CGovernanceManager::SERIALIZATION_VERSION_STRING = "CGovernanceManager-Version-14"; +const std::string CGovernanceManager::SERIALIZATION_VERSION_STRING = "CGovernanceManager-Version-15"; const int CGovernanceManager::MAX_TIME_FUTURE_DEVIATION = 60 * 60; const int CGovernanceManager::RELIABLE_PROPAGATION_TIME = 60; @@ -491,11 +491,11 @@ std::vector CGovernanceManager::GetCurrentVotes(const uint256& auto mnList = deterministicMNManager->GetListAtChainTip(); std::map mapMasternodes; if (mnCollateralOutpointFilter.IsNull()) { - mnList.ForEachMN(true, [&](const CDeterministicMNCPtr& dmn) { + mnList.ForEachMN(false, [&](const CDeterministicMNCPtr& dmn) { mapMasternodes.emplace(dmn->collateralOutpoint, dmn); }); } else { - auto dmn = mnList.GetValidMNByCollateral(mnCollateralOutpointFilter); + auto dmn = mnList.GetMNByCollateral(mnCollateralOutpointFilter); if (dmn) { mapMasternodes.emplace(dmn->collateralOutpoint, dmn); } @@ -585,14 +585,14 @@ bool CGovernanceManager::ConfirmInventoryRequest(const CInv& inv) return false; } break; - } + } case MSG_GOVERNANCE_OBJECT_VOTE: { if (cmapVoteToObject.HasKey(inv.hash)) { LogPrint("gobject", "CGovernanceManager::ConfirmInventoryRequest already have governance vote, returning false\n"); return false; } break; - } + } default: LogPrint("gobject", "CGovernanceManager::ConfirmInventoryRequest unknown type, returning false\n"); return false; @@ -1337,15 +1337,15 @@ void CGovernanceManager::RemoveInvalidVotes() std::vector changedKeyMNs; for (const auto& p : diff.updatedMNs) { - auto oldDmn = lastMNListForVotingKeys.GetMN(p.first); - if (p.second->keyIDVoting != oldDmn->pdmnState->keyIDVoting) { + auto oldDmn = lastMNListForVotingKeys.GetMNByInternalId(p.first); + if ((p.second.fields & CDeterministicMNStateDiff::Field_keyIDVoting) && p.second.state.keyIDVoting != oldDmn->pdmnState->keyIDVoting) { changedKeyMNs.emplace_back(oldDmn->collateralOutpoint); - } else if (p.second->pubKeyOperator != oldDmn->pdmnState->pubKeyOperator) { + } else if ((p.second.fields & CDeterministicMNStateDiff::Field_pubKeyOperator) && p.second.state.pubKeyOperator != oldDmn->pdmnState->pubKeyOperator) { changedKeyMNs.emplace_back(oldDmn->collateralOutpoint); } } - for (const auto& proTxHash : diff.removedMns) { - auto oldDmn = lastMNListForVotingKeys.GetMN(proTxHash); + for (const auto& id : diff.removedMns) { + auto oldDmn = lastMNListForVotingKeys.GetMNByInternalId(id); changedKeyMNs.emplace_back(oldDmn->collateralOutpoint); } diff --git a/src/governance.h b/src/governance/governance.h similarity index 99% rename from src/governance.h rename to src/governance/governance.h index 466b0f971..968960f60 100755 --- a/src/governance.h +++ b/src/governance/governance.h @@ -342,7 +342,11 @@ class CGovernanceManager LOCK(cs); std::string strVersion; if (ser_action.ForRead()) { + Clear(); READWRITE(strVersion); + if (strVersion != SERIALIZATION_VERSION_STRING) { + return; + } } else { strVersion = SERIALIZATION_VERSION_STRING; READWRITE(strVersion); @@ -354,10 +358,6 @@ class CGovernanceManager READWRITE(mapObjects); READWRITE(mapLastMasternodeObject); READWRITE(lastMNListForVotingKeys); - if (ser_action.ForRead() && (strVersion != SERIALIZATION_VERSION_STRING)) { - Clear(); - return; - } } void UpdatedBlockTip(const CBlockIndex* pindex, CConnman& connman); diff --git a/src/httpserver.cpp b/src/httpserver.cpp index c889999df..84c0d5215 100755 --- a/src/httpserver.cpp +++ b/src/httpserver.cpp @@ -147,13 +147,6 @@ class WorkQueue cond.wait(lock); } } - - /** Return current depth of queue */ - size_t Depth() - { - std::unique_lock lock(cs); - return queue.size(); - } }; struct HTTPPathHandler @@ -489,6 +482,7 @@ void StopHTTPServer() workQueue->WaitExit(); #endif delete workQueue; + workQueue = nullptr; } if (eventBase) { LogPrint("http", "Waiting for HTTP event thread to exit\n"); diff --git a/src/init.cpp b/src/init.cpp index a7c6a9ab5..227e0a21f 100755 --- a/src/init.cpp +++ b/src/init.cpp @@ -44,24 +44,24 @@ #include "wallet/wallet.h" #endif -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "dsnotificationinterface.h" #include "flat-database.h" -#include "governance.h" -#include "instantx.h" +#include "governance/governance.h" +#include "instantsend.h" #ifdef ENABLE_WALLET #include "keepass.h" #endif -#include "masternode-meta.h" -#include "masternode-payments.h" -#include "masternode-sync.h" -#include "masternode-utils.h" +#include "masternode/masternode-meta.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" +#include "masternode/masternode-utils.h" #include "messagesigner.h" #include "netfulfilledman.h" #ifdef ENABLE_WALLET -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #endif // ENABLE_WALLET -#include "privatesend-server.h" +#include "privatesend/privatesend-server.h" #include "spork.h" #include "warnings.h" @@ -1831,6 +1831,8 @@ bool AppInitMain(boost::thread_group& threadGroup, CScheduler& scheduler) break; } + deterministicMNManager->UpgradeDBIfNeeded(); + uiInterface.InitMessage(_("Verifying blocks...")); if (fHavePruned && GetArg("-checkblocks", DEFAULT_CHECKBLOCKS) > MIN_BLOCKS_TO_KEEP) { LogPrintf("Prune: pruned datadir may not have more than %d blocks; only checking available blocks", diff --git a/src/instantx.cpp b/src/instantsend.cpp similarity index 99% rename from src/instantx.cpp rename to src/instantsend.cpp index 6b5488cd3..73272b3a8 100755 --- a/src/instantx.cpp +++ b/src/instantsend.cpp @@ -2,14 +2,14 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "init.h" -#include "instantx.h" +#include "instantsend.h" #include "key.h" #include "validation.h" -#include "masternode-payments.h" -#include "masternode-sync.h" -#include "masternode-utils.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" +#include "masternode/masternode-utils.h" #include "messagesigner.h" #include "net.h" #include "netmessagemaker.h" @@ -1123,7 +1123,7 @@ bool CTxLockVote::CheckSignature() const CBLSSignature sig; sig.SetBuf(vchMasternodeSignature); - if (!sig.IsValid() || !sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator, hash)) { + if (!sig.IsValid() || !sig.VerifyInsecure(dmn->pdmnState->pubKeyOperator.Get(), hash)) { LogPrintf("CTxLockVote::CheckSignature -- VerifyInsecure() failed\n"); return false; } diff --git a/src/instantx.h b/src/instantsend.h similarity index 100% rename from src/instantx.h rename to src/instantsend.h diff --git a/src/key.h b/src/key.h index ff5252b7a..b218f2cb7 100755 --- a/src/key.h +++ b/src/key.h @@ -45,7 +45,7 @@ class CKey //! The actual byte data std::vector > keydata; - //! Check whether the 32-byte array pointed to be vch is valid keydata. + //! Check whether the 32-byte array pointed to by vch is valid keydata. bool static Check(const unsigned char* vch); public: diff --git a/src/llmq/quorums.cpp b/src/llmq/quorums.cpp index cf3e22ba3..6b784d67f 100755 --- a/src/llmq/quorums.cpp +++ b/src/llmq/quorums.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 The Axe Core developers +// Copyright (c) 2018-2019 The Dash Core developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -12,10 +12,10 @@ #include "evo/specialtx.h" -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "chainparams.h" #include "init.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "univalue.h" #include "validation.h" @@ -49,10 +49,10 @@ CQuorum::~CQuorum() } } -void CQuorum::Init(const CFinalCommitment& _qc, int _height, const uint256& _minedBlockHash, const std::vector& _members) +void CQuorum::Init(const CFinalCommitment& _qc, const CBlockIndex* _pindexQuorum, const uint256& _minedBlockHash, const std::vector& _members) { qc = _qc; - height = _height; + pindexQuorum = _pindexQuorum; members = _members; minedBlockHash = _minedBlockHash; } @@ -193,9 +193,9 @@ void CQuorumManager::EnsureQuorumConnections(Consensus::LLMQType llmqType, const if (!g_connman->HasMasternodeQuorumNodes(llmqType, quorum->qc.quorumHash)) { std::set connections; if (quorum->IsMember(myProTxHash)) { - connections = CLLMQUtils::GetQuorumConnections(llmqType, quorum->qc.quorumHash, myProTxHash); + connections = CLLMQUtils::GetQuorumConnections(llmqType, quorum->pindexQuorum, myProTxHash); } else { - auto cindexes = CLLMQUtils::CalcDeterministicWatchConnections(llmqType, quorum->qc.quorumHash, quorum->members.size(), 1); + auto cindexes = CLLMQUtils::CalcDeterministicWatchConnections(llmqType, quorum->pindexQuorum, quorum->members.size(), 1); for (auto idx : cindexes) { connections.emplace(quorum->members[idx]->proTxHash); } @@ -212,7 +212,7 @@ void CQuorumManager::EnsureQuorumConnections(Consensus::LLMQType llmqType, const debugMsg += strprintf(" %s (%s)\n", c.ToString(), dmn->pdmnState->addr.ToString(false)); } } - LogPrint("llmq", debugMsg); + LogPrint("llmq", debugMsg.c_str()); } g_connman->AddMasternodeQuorumNodes(llmqType, quorum->qc.quorumHash, connections); } @@ -231,9 +231,9 @@ bool CQuorumManager::BuildQuorumFromCommitment(const CFinalCommitment& qc, const assert(pindexQuorum); assert(qc.quorumHash == pindexQuorum->GetBlockHash()); - auto members = CLLMQUtils::GetAllQuorumMembers((Consensus::LLMQType)qc.llmqType, qc.quorumHash); + auto members = CLLMQUtils::GetAllQuorumMembers((Consensus::LLMQType)qc.llmqType, pindexQuorum); - quorum->Init(qc, pindexQuorum->nHeight, minedBlockHash, members); + quorum->Init(qc, pindexQuorum, minedBlockHash, members); bool hasValidVvec = false; if (quorum->ReadContributions(evoDb)) { @@ -262,7 +262,7 @@ bool CQuorumManager::BuildQuorumContributions(const CFinalCommitment& fqc, std:: std::vector memberIndexes; std::vector vvecs; BLSSecretKeyVector skContributions; - if (!dkgManager.GetVerifiedContributions((Consensus::LLMQType)fqc.llmqType, fqc.quorumHash, fqc.validMembers, memberIndexes, vvecs, skContributions)) { + if (!dkgManager.GetVerifiedContributions((Consensus::LLMQType)fqc.llmqType, quorum->pindexQuorum, fqc.validMembers, memberIndexes, vvecs, skContributions)) { return false; } @@ -313,7 +313,7 @@ std::vector CQuorumManager::ScanQuorums(Consensus::LLMQType llmqTyp auto& params = Params().GetConsensus().llmqs.at(llmqType); auto cacheKey = std::make_pair(llmqType, pindexStart->GetBlockHash()); - const size_t cacheMaxSize = 25; // largest active set + 1 + const size_t cacheMaxSize = params.signingActiveQuorumCount + 1; std::vector result; diff --git a/src/llmq/quorums.h b/src/llmq/quorums.h index 508fe06e1..75fb7a038 100755 --- a/src/llmq/quorums.h +++ b/src/llmq/quorums.h @@ -37,7 +37,7 @@ class CQuorum public: const Consensus::LLMQParams& params; CFinalCommitment qc; - int height; + const CBlockIndex* pindexQuorum; uint256 minedBlockHash; std::vector members; @@ -55,7 +55,7 @@ class CQuorum public: CQuorum(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker) : params(_params), blsCache(_blsWorker), stopCachePopulatorThread(false) {} ~CQuorum(); - void Init(const CFinalCommitment& _qc, int _height, const uint256& _minedBlockHash, const std::vector& _members); + void Init(const CFinalCommitment& _qc, const CBlockIndex* _pindexQuorum, const uint256& _minedBlockHash, const std::vector& _members); bool IsMember(const uint256& proTxHash) const; bool IsValidMember(const uint256& proTxHash) const; diff --git a/src/llmq/quorums_blockprocessor.cpp b/src/llmq/quorums_blockprocessor.cpp index 510f97ffe..8336a04d7 100755 --- a/src/llmq/quorums_blockprocessor.cpp +++ b/src/llmq/quorums_blockprocessor.cpp @@ -57,6 +57,7 @@ void CQuorumBlockProcessor::ProcessMessage(CNode* pfrom, const std::string& strC const auto& params = Params().GetConsensus().llmqs.at(type); // Verify that quorumHash is part of the active chain and that it's the first block in the DKG interval + const CBlockIndex* pquorumIndex; { LOCK(cs_main); if (!mapBlockIndex.count(qc.quorumHash)) { @@ -66,7 +67,7 @@ void CQuorumBlockProcessor::ProcessMessage(CNode* pfrom, const std::string& strC // fully synced return; } - auto pquorumIndex = mapBlockIndex[qc.quorumHash]; + pquorumIndex = mapBlockIndex[qc.quorumHash]; if (chainActive.Tip()->GetAncestor(pquorumIndex->nHeight) != pquorumIndex) { LogPrintf("CQuorumBlockProcessor::%s -- block %s not in active chain, peer=%d\n", __func__, qc.quorumHash.ToString(), pfrom->id); @@ -98,7 +99,7 @@ void CQuorumBlockProcessor::ProcessMessage(CNode* pfrom, const std::string& strC } } - auto members = CLLMQUtils::GetAllQuorumMembers(type, qc.quorumHash); + auto members = CLLMQUtils::GetAllQuorumMembers(type, pquorumIndex); if (!qc.Verify(members, true)) { LOCK(cs_main); @@ -203,14 +204,14 @@ bool CQuorumBlockProcessor::ProcessCommitment(int nHeight, const uint256& blockH return state.DoS(100, false, REJECT_INVALID, "bad-qc-height"); } - auto members = CLLMQUtils::GetAllQuorumMembers(params.type, quorumHash); + auto quorumIndex = mapBlockIndex.at(qc.quorumHash); + auto members = CLLMQUtils::GetAllQuorumMembers(params.type, quorumIndex); if (!qc.Verify(members, true)) { return state.DoS(100, false, REJECT_INVALID, "bad-qc-invalid"); } // Store commitment in DB - auto quorumIndex = mapBlockIndex.at(qc.quorumHash); evoDb.Write(std::make_pair(DB_MINED_COMMITMENT, std::make_pair((uint8_t)params.type, quorumHash)), std::make_pair(qc, blockHash)); evoDb.Write(BuildInversedHeightKey(params.type, nHeight), quorumIndex->nHeight); diff --git a/src/llmq/quorums_chainlocks.cpp b/src/llmq/quorums_chainlocks.cpp index 11de470f9..8907c3ce2 100755 --- a/src/llmq/quorums_chainlocks.cpp +++ b/src/llmq/quorums_chainlocks.cpp @@ -9,7 +9,7 @@ #include "quorums_utils.h" #include "chain.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "net_processing.h" #include "scheduler.h" #include "spork.h" @@ -551,7 +551,7 @@ void CChainLocksHandler::HandleNewRecoveredSig(const llmq::CRecoveredSig& recove clsig.nHeight = lastSignedHeight; clsig.blockHash = lastSignedMsgHash; - clsig.sig = recoveredSig.sig.GetSig(); + clsig.sig = recoveredSig.sig.Get(); } ProcessNewChainLock(-1, clsig, ::SerializeHash(clsig)); } diff --git a/src/llmq/quorums_commitment.cpp b/src/llmq/quorums_commitment.cpp index 9deb39663..5347a7064 100755 --- a/src/llmq/quorums_commitment.cpp +++ b/src/llmq/quorums_commitment.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 The Axe Core developers +// Copyright (c) 2018-2019 The Dash Core developers // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -88,7 +88,7 @@ bool CFinalCommitment::Verify(const std::vector& members, if (!signers[i]) { continue; } - memberPubKeys.emplace_back(members[i]->pdmnState->pubKeyOperator); + memberPubKeys.emplace_back(members[i]->pdmnState->pubKeyOperator.Get()); } if (!membersSig.VerifySecureAggregated(memberPubKeys, commitmentHash)) { @@ -193,7 +193,7 @@ bool CheckLLMQCommitment(const CTransaction& tx, const CBlockIndex* pindexPrev, return true; } - auto members = CLLMQUtils::GetAllQuorumMembers(params.type, qcTx.commitment.quorumHash); + auto members = CLLMQUtils::GetAllQuorumMembers(params.type, pindexQuorum); if (!qcTx.commitment.Verify(members, false)) { return state.DoS(100, false, REJECT_INVALID, "bad-qc-invalid"); } diff --git a/src/llmq/quorums_debug.cpp b/src/llmq/quorums_debug.cpp index 4f6c6f505..8d1a5ca3d 100755 --- a/src/llmq/quorums_debug.cpp +++ b/src/llmq/quorums_debug.cpp @@ -5,6 +5,7 @@ #include "quorums_debug.h" #include "chainparams.h" +#include "validation.h" #include "evo/deterministicmns.h" #include "quorums_utils.h" @@ -23,7 +24,17 @@ UniValue CDKGDebugSessionStatus::ToJson(int detailLevel) const std::vector dmnMembers; if (detailLevel == 2) { - dmnMembers = CLLMQUtils::GetAllQuorumMembers((Consensus::LLMQType) llmqType, quorumHash); + const CBlockIndex* pindex = nullptr; + { + LOCK(cs_main); + auto it = mapBlockIndex.find(quorumHash); + if (it != mapBlockIndex.end()) { + pindex = it->second; + } + } + if (pindex != nullptr) { + dmnMembers = CLLMQUtils::GetAllQuorumMembers((Consensus::LLMQType) llmqType, pindex); + } } ret.push_back(Pair("llmqType", llmqType)); diff --git a/src/llmq/quorums_dkgsession.cpp b/src/llmq/quorums_dkgsession.cpp index d226aa361..24674d79e 100755 --- a/src/llmq/quorums_dkgsession.cpp +++ b/src/llmq/quorums_dkgsession.cpp @@ -11,7 +11,7 @@ #include "evo/specialtx.h" -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "chainparams.h" #include "init.h" #include "net.h" @@ -60,7 +60,7 @@ static bool ShouldSimulateError(const std::string& type) } CDKGLogger::CDKGLogger(const CDKGSession& _quorumDkg, const std::string& _func) : - CDKGLogger(_quorumDkg.params.type, _quorumDkg.quorumHash, _quorumDkg.height, _quorumDkg.AreWeMember(), _func) + CDKGLogger(_quorumDkg.params.type, _quorumDkg.pindexQuorum->GetBlockHash(), _quorumDkg.pindexQuorum->nHeight, _quorumDkg.AreWeMember(), _func) { } @@ -88,14 +88,13 @@ CDKGMember::CDKGMember(CDeterministicMNCPtr _dmn, size_t _idx) : } -bool CDKGSession::Init(int _height, const uint256& _quorumHash, const std::vector& mns, const uint256& _myProTxHash) +bool CDKGSession::Init(const CBlockIndex* _pindexQuorum, const std::vector& mns, const uint256& _myProTxHash) { if (mns.size() < params.minSize) { return false; } - height = _height; - quorumHash = _quorumHash; + pindexQuorum = _pindexQuorum; members.resize(mns.size()); memberIds.resize(members.size()); @@ -121,7 +120,7 @@ bool CDKGSession::Init(int _height, const uint256& _quorumHash, const std::vecto } if (!myProTxHash.IsNull()) { - quorumDKGDebugManager->InitLocalSessionStatus(params.type, quorumHash, height); + quorumDKGDebugManager->InitLocalSessionStatus(params.type, pindexQuorum->GetBlockHash(), pindexQuorum->nHeight); } CDKGLogger logger(*this, __func__); @@ -170,7 +169,7 @@ void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages) CDKGContribution qc; qc.llmqType = (uint8_t)params.type; - qc.quorumHash = quorumHash; + qc.quorumHash = pindexQuorum->GetBlockHash(); qc.proTxHash = myProTxHash; qc.vvec = vvecContribution; @@ -187,7 +186,7 @@ void CDKGSession::SendContributions(CDKGPendingMessages& pendingMessages) skContrib.MakeNewKey(); } - if (!qc.contributions->Encrypt(i, m->dmn->pdmnState->pubKeyOperator, skContrib, PROTOCOL_VERSION)) { + if (!qc.contributions->Encrypt(i, m->dmn->pdmnState->pubKeyOperator.Get(), skContrib, PROTOCOL_VERSION)) { logger.Batch("failed to encrypt contribution for %s", m->dmn->proTxHash.ToString()); return; } @@ -216,7 +215,7 @@ bool CDKGSession::PreVerifyMessage(const uint256& hash, const CDKGContribution& retBan = false; - if (qc.quorumHash != quorumHash) { + if (qc.quorumHash != pindexQuorum->GetBlockHash()) { logger.Batch("contribution for wrong quorum, rejecting"); return false; } @@ -316,7 +315,7 @@ void CDKGSession::ReceiveMessage(const uint256& hash, const CDKGContribution& qc return; } - dkgManager.WriteVerifiedVvecContribution(params.type, qc.quorumHash, qc.proTxHash, qc.vvec); + dkgManager.WriteVerifiedVvecContribution(params.type, pindexQuorum, qc.proTxHash, qc.vvec); bool complain = false; CBLSSecretKey skContribution; @@ -398,7 +397,7 @@ void CDKGSession::VerifyPendingContributions() }); } else { size_t memberIdx = memberIndexes[i]; - dkgManager.WriteVerifiedSkContribution(params.type, quorumHash, members[memberIdx]->dmn->proTxHash, skContributions[i]); + dkgManager.WriteVerifiedSkContribution(params.type, pindexQuorum, members[memberIdx]->dmn->proTxHash, skContributions[i]); } } @@ -449,7 +448,7 @@ void CDKGSession::SendComplaint(CDKGPendingMessages& pendingMessages) CDKGComplaint qc(params); qc.llmqType = (uint8_t)params.type; - qc.quorumHash = quorumHash; + qc.quorumHash = pindexQuorum->GetBlockHash(); qc.proTxHash = myProTxHash; int badCount = 0; @@ -490,7 +489,7 @@ bool CDKGSession::PreVerifyMessage(const uint256& hash, const CDKGComplaint& qc, retBan = false; - if (qc.quorumHash != quorumHash) { + if (qc.quorumHash != pindexQuorum->GetBlockHash()) { logger.Batch("complaint for wrong quorum, rejecting"); return false; } @@ -643,7 +642,7 @@ void CDKGSession::SendJustification(CDKGPendingMessages& pendingMessages, const CDKGJustification qj; qj.llmqType = (uint8_t)params.type; - qj.quorumHash = quorumHash; + qj.quorumHash = pindexQuorum->GetBlockHash(); qj.proTxHash = myProTxHash; qj.contributions.reserve(forMembers.size()); @@ -688,7 +687,7 @@ bool CDKGSession::PreVerifyMessage(const uint256& hash, const CDKGJustification& retBan = false; - if (qj.quorumHash != quorumHash) { + if (qj.quorumHash != pindexQuorum->GetBlockHash()) { logger.Batch("justification for wrong quorum, rejecting"); return false; } @@ -824,7 +823,7 @@ void CDKGSession::ReceiveMessage(const uint256& hash, const CDKGJustification& q receivedSkContributions[member->idx] = skContribution; member->weComplain = false; - dkgManager.WriteVerifiedSkContribution(params.type, quorumHash, member->dmn->proTxHash, skContribution); + dkgManager.WriteVerifiedSkContribution(params.type, pindexQuorum, member->dmn->proTxHash, skContribution); } member->complaintsFromOthers.erase(member2->dmn->proTxHash); } @@ -899,7 +898,7 @@ void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages) CDKGPrematureCommitment qc(params); qc.llmqType = (uint8_t)params.type; - qc.quorumHash = quorumHash; + qc.quorumHash = pindexQuorum->GetBlockHash(); qc.proTxHash = myProTxHash; for (size_t i = 0; i < members.size(); i++) { @@ -925,7 +924,7 @@ void CDKGSession::SendCommitment(CDKGPendingMessages& pendingMessages) std::vector memberIndexes; std::vector vvecs; BLSSecretKeyVector skContributions; - if (!dkgManager.GetVerifiedContributions(params.type, quorumHash, qc.validMembers, memberIndexes, vvecs, skContributions)) { + if (!dkgManager.GetVerifiedContributions(params.type, pindexQuorum, qc.validMembers, memberIndexes, vvecs, skContributions)) { logger.Batch("failed to get valid contributions"); return; } @@ -1012,7 +1011,7 @@ bool CDKGSession::PreVerifyMessage(const uint256& hash, const CDKGPrematureCommi retBan = false; - if (qc.quorumHash != quorumHash) { + if (qc.quorumHash != pindexQuorum->GetBlockHash()) { logger.Batch("commitment for wrong quorum, rejecting"); return false; } @@ -1091,7 +1090,7 @@ void CDKGSession::ReceiveMessage(const uint256& hash, const CDKGPrematureCommitm std::vector vvecs; BLSSecretKeyVector skContributions; BLSVerificationVectorPtr quorumVvec; - if (dkgManager.GetVerifiedContributions(params.type, qc.quorumHash, qc.validMembers, memberIndexes, vvecs, skContributions)) { + if (dkgManager.GetVerifiedContributions(params.type, pindexQuorum, qc.validMembers, memberIndexes, vvecs, skContributions)) { quorumVvec = cache.BuildQuorumVerificationVector(::SerializeHash(memberIndexes), vvecs); } @@ -1219,7 +1218,7 @@ std::vector CDKGSession::FinalizeCommitments() fqc.signers[signerIndex] = true; aggSigs.emplace_back(qc.sig); - aggPks.emplace_back(m->dmn->pdmnState->pubKeyOperator); + aggPks.emplace_back(m->dmn->pdmnState->pubKeyOperator.Get()); signerIds.emplace_back(m->id); thresholdSigs.emplace_back(qc.quorumSig); diff --git a/src/llmq/quorums_dkgsession.h b/src/llmq/quorums_dkgsession.h index 31c05a6b6..07c2a0ed8 100755 --- a/src/llmq/quorums_dkgsession.h +++ b/src/llmq/quorums_dkgsession.h @@ -249,8 +249,7 @@ class CDKGSession CBLSWorkerCache cache; CDKGSessionManager& dkgManager; - uint256 quorumHash; - int height{-1}; + const CBlockIndex* pindexQuorum; private: std::vector> members; @@ -287,7 +286,7 @@ class CDKGSession CDKGSession(const Consensus::LLMQParams& _params, CBLSWorker& _blsWorker, CDKGSessionManager& _dkgManager) : params(_params), blsWorker(_blsWorker), cache(_blsWorker), dkgManager(_dkgManager) {} - bool Init(int _height, const uint256& _quorumHash, const std::vector& mns, const uint256& _myProTxHash); + bool Init(const CBlockIndex* pindexQuorum, const std::vector& mns, const uint256& _myProTxHash); size_t GetMyMemberIndex() const { return myIdx; } diff --git a/src/llmq/quorums_dkgsessionhandler.cpp b/src/llmq/quorums_dkgsessionhandler.cpp index 04eb2b4aa..9c1a36347 100755 --- a/src/llmq/quorums_dkgsessionhandler.cpp +++ b/src/llmq/quorums_dkgsessionhandler.cpp @@ -8,7 +8,7 @@ #include "quorums_init.h" #include "quorums_utils.h" -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "chainparams.h" #include "init.h" #include "net_processing.h" @@ -139,7 +139,7 @@ void CDKGSessionHandler::ProcessMessage(CNode* pfrom, const std::string& strComm } } -bool CDKGSessionHandler::InitNewQuorum(int newQuorumHeight, const uint256& newQuorumHash) +bool CDKGSessionHandler::InitNewQuorum(const CBlockIndex* pindexQuorum) { //AssertLockHeld(cs_main); @@ -147,13 +147,13 @@ bool CDKGSessionHandler::InitNewQuorum(int newQuorumHeight, const uint256& newQu curSession = std::make_shared(params, blsWorker, dkgManager); - if (!deterministicMNManager->IsDIP3Enforced(newQuorumHeight)) { + if (!deterministicMNManager->IsDIP3Enforced(pindexQuorum->nHeight)) { return false; } - auto mns = CLLMQUtils::GetAllQuorumMembers(params.type, newQuorumHash); + auto mns = CLLMQUtils::GetAllQuorumMembers(params.type, pindexQuorum); - if (!curSession->Init(newQuorumHeight, newQuorumHash, mns, activeMasternodeInfo.proTxHash)) { + if (!curSession->Init(pindexQuorum, mns, activeMasternodeInfo.proTxHash)) { LogPrintf("CDKGSessionManager::%s -- quorum initialiation failed\n", __func__); return false; } @@ -313,7 +313,7 @@ std::set BatchVerifyMessageSigs(CDKGSession& session, const std::vector< break; } - pubKeys.emplace_back(member->dmn->pdmnState->pubKeyOperator); + pubKeys.emplace_back(member->dmn->pdmnState->pubKeyOperator.Get()); messageHashes.emplace_back(msgHash); } if (!revertToSingleVerification) { @@ -353,7 +353,7 @@ std::set BatchVerifyMessageSigs(CDKGSession& session, const std::vector< const auto& msg = *p.second; auto member = session.GetMember(msg.proTxHash); - bool valid = msg.sig.VerifyInsecure(member->dmn->pdmnState->pubKeyOperator, msg.GetSignHash()); + bool valid = msg.sig.VerifyInsecure(member->dmn->pdmnState->pubKeyOperator.Get(), msg.GetSignHash()); if (!valid) { ret.emplace(p.first); } @@ -455,7 +455,13 @@ void CDKGSessionHandler::HandleDKGRound() curQuorumHeight = quorumHeight; } - if (!InitNewQuorum(curQuorumHeight, curQuorumHash)) { + const CBlockIndex* pindexQuorum; + { + LOCK(cs_main); + pindexQuorum = mapBlockIndex.at(curQuorumHash); + } + + if (!InitNewQuorum(pindexQuorum)) { // should actually never happen WaitForNewQuorum(curQuorumHash); throw AbortPhaseException(); @@ -470,16 +476,16 @@ void CDKGSessionHandler::HandleDKGRound() if (curSession->AreWeMember() || GetBoolArg("-watchquorums", DEFAULT_WATCH_QUORUMS)) { std::set connections; if (curSession->AreWeMember()) { - connections = CLLMQUtils::GetQuorumConnections(params.type, curQuorumHash, curSession->myProTxHash); + connections = CLLMQUtils::GetQuorumConnections(params.type, pindexQuorum, curSession->myProTxHash); } else { - auto cindexes = CLLMQUtils::CalcDeterministicWatchConnections(params.type, curQuorumHash, curSession->members.size(), 1); + auto cindexes = CLLMQUtils::CalcDeterministicWatchConnections(params.type, pindexQuorum, curSession->members.size(), 1); for (auto idx : cindexes) { connections.emplace(curSession->members[idx]->dmn->proTxHash); } } if (!connections.empty()) { if (LogAcceptCategory("llmq-dkg")) { - std::string debugMsg = strprintf("CDKGSessionManager::%s -- adding masternodes quorum connections for quorum %s:\n", __func__, curSession->quorumHash.ToString()); + std::string debugMsg = strprintf("CDKGSessionManager::%s -- adding masternodes quorum connections for quorum %s:\n", __func__, curSession->pindexQuorum->GetBlockHash().ToString()); auto mnList = deterministicMNManager->GetListAtChainTip(); for (const auto& c : connections) { auto dmn = mnList.GetValidMN(c); @@ -489,7 +495,7 @@ void CDKGSessionHandler::HandleDKGRound() debugMsg += strprintf(" %s (%s)\n", c.ToString(), dmn->pdmnState->addr.ToString(false)); } } - LogPrint("llmq-dkg", debugMsg); + LogPrint("llmq-dkg", debugMsg.c_str()); } g_connman->AddMasternodeQuorumNodes(params.type, curQuorumHash, connections); } diff --git a/src/llmq/quorums_dkgsessionhandler.h b/src/llmq/quorums_dkgsessionhandler.h index 3319fffa1..dc9c495fd 100755 --- a/src/llmq/quorums_dkgsessionhandler.h +++ b/src/llmq/quorums_dkgsessionhandler.h @@ -125,7 +125,7 @@ class CDKGSessionHandler void ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStream& vRecv, CConnman& connman); private: - bool InitNewQuorum(int newQuorumHeight, const uint256& newQuorumHash); + bool InitNewQuorum(const CBlockIndex* pindexQuorum); std::pair GetPhaseAndQuorumHash() const; diff --git a/src/llmq/quorums_dkgsessionmgr.cpp b/src/llmq/quorums_dkgsessionmgr.cpp index 9ac2b37f2..ad62a31ad 100755 --- a/src/llmq/quorums_dkgsessionmgr.cpp +++ b/src/llmq/quorums_dkgsessionmgr.cpp @@ -198,19 +198,19 @@ bool CDKGSessionManager::GetPrematureCommitment(const uint256& hash, CDKGPrematu return false; } -void CDKGSessionManager::WriteVerifiedVvecContribution(Consensus::LLMQType llmqType, const uint256& quorumHash, const uint256& proTxHash, const BLSVerificationVectorPtr& vvec) +void CDKGSessionManager::WriteVerifiedVvecContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const BLSVerificationVectorPtr& vvec) { - llmqDb.Write(std::make_tuple(DB_VVEC, (uint8_t)llmqType, quorumHash, proTxHash), *vvec); + llmqDb.Write(std::make_tuple(DB_VVEC, (uint8_t) llmqType, pindexQuorum->GetBlockHash(), proTxHash), *vvec); } -void CDKGSessionManager::WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const uint256& quorumHash, const uint256& proTxHash, const CBLSSecretKey& skContribution) +void CDKGSessionManager::WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const CBLSSecretKey& skContribution) { - llmqDb.Write(std::make_tuple(DB_SKCONTRIB, (uint8_t)llmqType, quorumHash, proTxHash), skContribution); + llmqDb.Write(std::make_tuple(DB_SKCONTRIB, (uint8_t) llmqType, pindexQuorum->GetBlockHash(), proTxHash), skContribution); } -bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::vector& validMembers, std::vector& memberIndexesRet, std::vector& vvecsRet, BLSSecretKeyVector& skContributionsRet) +bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const std::vector& validMembers, std::vector& memberIndexesRet, std::vector& vvecsRet, BLSSecretKeyVector& skContributionsRet) { - auto members = CLLMQUtils::GetAllQuorumMembers(llmqType, quorumHash); + auto members = CLLMQUtils::GetAllQuorumMembers(llmqType, pindexQuorum); memberIndexesRet.clear(); vvecsRet.clear(); @@ -222,7 +222,7 @@ bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, if (validMembers[i]) { BLSVerificationVectorPtr vvec; CBLSSecretKey skContribution; - if (!GetVerifiedContribution(llmqType, quorumHash, members[i]->proTxHash, vvec, skContribution)) { + if (!GetVerifiedContribution(llmqType, pindexQuorum, members[i]->proTxHash, vvec, skContribution)) { return false; } @@ -234,10 +234,10 @@ bool CDKGSessionManager::GetVerifiedContributions(Consensus::LLMQType llmqType, return true; } -bool CDKGSessionManager::GetVerifiedContribution(Consensus::LLMQType llmqType, const uint256& quorumHash, const uint256& proTxHash, BLSVerificationVectorPtr& vvecRet, CBLSSecretKey& skContributionRet) +bool CDKGSessionManager::GetVerifiedContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, BLSVerificationVectorPtr& vvecRet, CBLSSecretKey& skContributionRet) { LOCK(contributionsCacheCs); - ContributionsCacheKey cacheKey = {llmqType, quorumHash, proTxHash}; + ContributionsCacheKey cacheKey = {llmqType, pindexQuorum->GetBlockHash(), proTxHash}; auto it = contributionsCache.find(cacheKey); if (it != contributionsCache.end()) { vvecRet = it->second.vvec; @@ -248,10 +248,10 @@ bool CDKGSessionManager::GetVerifiedContribution(Consensus::LLMQType llmqType, c BLSVerificationVector vvec; BLSVerificationVectorPtr vvecPtr; CBLSSecretKey skContribution; - if (llmqDb.Read(std::make_tuple(DB_VVEC, (uint8_t)llmqType, quorumHash, proTxHash), vvec)) { + if (llmqDb.Read(std::make_tuple(DB_VVEC, (uint8_t) llmqType, pindexQuorum->GetBlockHash(), proTxHash), vvec)) { vvecPtr = std::make_shared(std::move(vvec)); } - llmqDb.Read(std::make_tuple(DB_SKCONTRIB, (uint8_t)llmqType, quorumHash, proTxHash), skContribution); + llmqDb.Read(std::make_tuple(DB_SKCONTRIB, (uint8_t) llmqType, pindexQuorum->GetBlockHash(), proTxHash), skContribution); it = contributionsCache.emplace(cacheKey, ContributionsCacheEntry{GetTimeMillis(), vvecPtr, skContribution}).first; diff --git a/src/llmq/quorums_dkgsessionmgr.h b/src/llmq/quorums_dkgsessionmgr.h index 5b0125959..9349efe16 100755 --- a/src/llmq/quorums_dkgsessionmgr.h +++ b/src/llmq/quorums_dkgsessionmgr.h @@ -63,10 +63,10 @@ class CDKGSessionManager bool GetPrematureCommitment(const uint256& hash, CDKGPrematureCommitment& ret) const; // Verified contributions are written while in the DKG - void WriteVerifiedVvecContribution(Consensus::LLMQType llmqType, const uint256& quorumHash, const uint256& proTxHash, const BLSVerificationVectorPtr& vvec); - void WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const uint256& quorumHash, const uint256& proTxHash, const CBLSSecretKey& skContribution); - bool GetVerifiedContributions(Consensus::LLMQType llmqType, const uint256& quorumHash, const std::vector& validMembers, std::vector& memberIndexesRet, std::vector& vvecsRet, BLSSecretKeyVector& skContributionsRet); - bool GetVerifiedContribution(Consensus::LLMQType llmqType, const uint256& quorumHash, const uint256& proTxHash, BLSVerificationVectorPtr& vvecRet, CBLSSecretKey& skContributionRet); + void WriteVerifiedVvecContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const BLSVerificationVectorPtr& vvec); + void WriteVerifiedSkContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, const CBLSSecretKey& skContribution); + bool GetVerifiedContributions(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const std::vector& validMembers, std::vector& memberIndexesRet, std::vector& vvecsRet, BLSSecretKeyVector& skContributionsRet); + bool GetVerifiedContribution(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& proTxHash, BLSVerificationVectorPtr& vvecRet, CBLSSecretKey& skContributionRet); private: void CleanupCache(); diff --git a/src/llmq/quorums_instantsend.cpp b/src/llmq/quorums_instantsend.cpp index f27049a1d..2cad16f65 100755 --- a/src/llmq/quorums_instantsend.cpp +++ b/src/llmq/quorums_instantsend.cpp @@ -10,7 +10,7 @@ #include "chainparams.h" #include "coins.h" #include "txmempool.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "net_processing.h" #include "spork.h" #include "validation.h" @@ -20,7 +20,7 @@ #endif // needed for AUTO_IX_MEMPOOL_THRESHOLD -#include "instantx.h" +#include "instantsend.h" #include #include @@ -61,13 +61,6 @@ void CInstantSendDb::WriteNewInstantSendLock(const uint256& hash, const CInstant } } -void CInstantSendDb::RemoveInstantSendLock(const uint256& hash, CInstantSendLockPtr islock) -{ - CDBBatch batch(db); - RemoveInstantSendLock(batch, hash, islock); - db.WriteBatch(batch); -} - void CInstantSendDb::RemoveInstantSendLock(CDBBatch& batch, const uint256& hash, CInstantSendLockPtr islock) { if (!islock) { @@ -185,6 +178,28 @@ bool CInstantSendDb::HasArchivedInstantSendLock(const uint256& islockHash) return db.Exists(std::make_tuple(std::string("is_a2"), islockHash)); } +size_t CInstantSendDb::GetInstantSendLockCount() +{ + auto it = std::unique_ptr(db.NewIterator()); + auto firstKey = std::make_tuple(std::string("is_i"), uint256()); + + it->Seek(firstKey); + + size_t cnt = 0; + while (it->Valid()) { + decltype(firstKey) curKey; + if (!it->GetKey(curKey) || std::get<0>(curKey) != "is_i") { + break; + } + + cnt++; + + it->Next(); + } + + return cnt; +} + CInstantSendLockPtr CInstantSendDb::GetInstantSendLockByHash(const uint256& hash) { CInstantSendLockPtr ret; @@ -712,8 +727,6 @@ bool CInstantSendManager::PreVerifyInstantSendLock(NodeId nodeId, const llmq::CI bool CInstantSendManager::ProcessPendingInstantSendLocks() { - auto llmqType = Params().GetConsensus().llmqForInstantSend; - decltype(pendingInstantSendLocks) pend; { @@ -735,6 +748,44 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks() tipHeight = chainActive.Height(); } + auto llmqType = Params().GetConsensus().llmqForInstantSend; + + // Every time a new quorum enters the active set, an older one is removed. This means that between two blocks, the + // active set can be different, leading to different selection of the signing quorum. When we detect such rotation + // of the active set, we must re-check invalid sigs against the previous active set and only ban nodes when this also + // fails. + auto quorums1 = quorumSigningManager->GetActiveQuorumSet(llmqType, tipHeight); + auto quorums2 = quorumSigningManager->GetActiveQuorumSet(llmqType, tipHeight - 1); + bool quorumsRotated = quorums1 != quorums2; + + if (quorumsRotated) { + // first check against the current active set and don't ban + auto badISLocks = ProcessPendingInstantSendLocks(tipHeight, pend, false); + if (!badISLocks.empty()) { + LogPrintf("CInstantSendManager::%s -- detected LLMQ active set rotation, redoing verification on old active set\n", __func__); + + // filter out valid IS locks from "pend" + for (auto it = pend.begin(); it != pend.end(); ) { + if (!badISLocks.count(it->first)) { + it = pend.erase(it); + } else { + ++it; + } + } + // now check against the previous active set and perform banning if this fails + ProcessPendingInstantSendLocks(tipHeight - 1, pend, true); + } + } else { + ProcessPendingInstantSendLocks(tipHeight, pend, true); + } + + return true; +} + +std::unordered_set CInstantSendManager::ProcessPendingInstantSendLocks(int signHeight, const std::unordered_map>& pend, bool ban) +{ + auto llmqType = Params().GetConsensus().llmqForInstantSend; + CBLSBatchVerifier batchVerifier(false, true, 8); std::unordered_map> recSigs; @@ -747,7 +798,7 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks() continue; } - if (!islock.sig.GetSig().IsValid()) { + if (!islock.sig.Get().IsValid()) { batchVerifier.badSources.emplace(nodeId); continue; } @@ -759,13 +810,13 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks() continue; } - auto quorum = quorumSigningManager->SelectQuorumForSigning(llmqType, tipHeight, id); + auto quorum = quorumSigningManager->SelectQuorumForSigning(llmqType, signHeight, id); if (!quorum) { // should not happen, but if one fails to select, all others will also fail to select - return false; + return {}; } uint256 signHash = CLLMQUtils::BuildSignHash(llmqType, quorum->qc.quorumHash, id, islock.txid); - batchVerifier.PushMessage(nodeId, hash, signHash, islock.sig.GetSig(), quorum->qc.quorumPublicKey); + batchVerifier.PushMessage(nodeId, hash, signHash, islock.sig.Get(), quorum->qc.quorumPublicKey); // We can reconstruct the CRecoveredSig objects from the islock and pass it to the signing manager, which // avoids unnecessary double-verification of the signature. We however only do this when verification here @@ -785,7 +836,9 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks() batchVerifier.Verify(); - if (!batchVerifier.badSources.empty()) { + std::unordered_set badISLocks; + + if (ban && !batchVerifier.badSources.empty()) { LOCK(cs_main); for (auto& nodeId : batchVerifier.badSources) { // Let's not be too harsh, as the peer might simply be unlucky and might have sent us an old lock which @@ -801,6 +854,7 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks() if (batchVerifier.badMessages.count(hash)) { LogPrintf("CInstantSendManager::%s -- txid=%s, islock=%s: invalid sig in islock, peer=%d\n", __func__, islock.txid.ToString(), hash.ToString(), nodeId); + badISLocks.emplace(hash); continue; } @@ -821,7 +875,7 @@ bool CInstantSendManager::ProcessPendingInstantSendLocks() } } - return true; + return badISLocks; } void CInstantSendManager::ProcessInstantSendLock(NodeId from, const uint256& hash, const CInstantSendLock& islock) @@ -1084,6 +1138,8 @@ void CInstantSendManager::UpdatedBlockTip(const CBlockIndex* pindexNew) void CInstantSendManager::HandleFullyConfirmedBlock(const CBlockIndex* pindex) { + auto& consensusParams = Params().GetConsensus(); + std::unordered_map removeISLocks; { LOCK(cs); @@ -1101,7 +1157,14 @@ void CInstantSendManager::HandleFullyConfirmedBlock(const CBlockIndex* pindex) for (auto& in : islock->inputs) { auto inputRequestId = ::SerializeHash(std::make_pair(INPUTLOCK_REQUESTID_PREFIX, in)); inputRequestIds.erase(inputRequestId); + + // no need to keep recovered sigs for fully confirmed IS locks, as there is no chance for conflicts + // from now on. All inputs are spent now and can't be spend in any other TX. + quorumSigningManager->RemoveRecoveredSig(consensusParams.llmqForInstantSend, inputRequestId); } + + // same as in the loop + quorumSigningManager->RemoveRecoveredSig(consensusParams.llmqForInstantSend, islock->GetRequestId()); } // Find all previously unlocked TXs that got locked by this fully confirmed (ChainLock) block and remove them @@ -1412,6 +1475,11 @@ CInstantSendLockPtr CInstantSendManager::GetConflictingLock(const CTransaction& return nullptr; } +size_t CInstantSendManager::GetInstantSendLockCount() +{ + return db.GetInstantSendLockCount(); +} + void CInstantSendManager::WorkThreadMain() { while (!workInterrupt) { diff --git a/src/llmq/quorums_instantsend.h b/src/llmq/quorums_instantsend.h index 020caf7fd..4a5e28d84 100755 --- a/src/llmq/quorums_instantsend.h +++ b/src/llmq/quorums_instantsend.h @@ -53,7 +53,6 @@ class CInstantSendDb CInstantSendDb(CDBWrapper& _db) : db(_db) {} void WriteNewInstantSendLock(const uint256& hash, const CInstantSendLock& islock); - void RemoveInstantSendLock(const uint256& hash, CInstantSendLockPtr islock); void RemoveInstantSendLock(CDBBatch& batch, const uint256& hash, CInstantSendLockPtr islock); void WriteInstantSendLockMined(const uint256& hash, int nHeight); @@ -62,6 +61,7 @@ class CInstantSendDb std::unordered_map RemoveConfirmedInstantSendLocks(int nUntilHeight); void RemoveArchivedInstantSendLocks(int nUntilHeight); bool HasArchivedInstantSendLock(const uint256& islockHash); + size_t GetInstantSendLockCount(); CInstantSendLockPtr GetInstantSendLockByHash(const uint256& hash); uint256 GetInstantSendLockHashByTxid(const uint256& txid); @@ -137,6 +137,7 @@ class CInstantSendManager : public CRecoveredSigsListener void ProcessMessageInstantSendLock(CNode* pfrom, const CInstantSendLock& islock, CConnman& connman); bool PreVerifyInstantSendLock(NodeId nodeId, const CInstantSendLock& islock, bool& retBan); bool ProcessPendingInstantSendLocks(); + std::unordered_set ProcessPendingInstantSendLocks(int signHeight, const std::unordered_map>& pend, bool ban); void ProcessInstantSendLock(NodeId from, const uint256& hash, const CInstantSendLock& islock); void UpdateWalletTransaction(const uint256& txid, const CTransactionRef& tx); @@ -159,6 +160,8 @@ class CInstantSendManager : public CRecoveredSigsListener bool AlreadyHave(const CInv& inv); bool GetInstantSendLockByHash(const uint256& hash, CInstantSendLock& ret); + size_t GetInstantSendLockCount(); + void WorkThreadMain(); }; diff --git a/src/llmq/quorums_signing.cpp b/src/llmq/quorums_signing.cpp index c90a93694..a1ddb510f 100755 --- a/src/llmq/quorums_signing.cpp +++ b/src/llmq/quorums_signing.cpp @@ -6,7 +6,7 @@ #include "quorums_utils.h" #include "quorums_signing_shares.h" -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "bls/bls_batchverifier.h" #include "cxxtimer.hpp" #include "init.h" @@ -31,8 +31,8 @@ UniValue CRecoveredSig::ToJson() const ret.push_back(Pair("quorumHash", quorumHash.ToString())); ret.push_back(Pair("id", id.ToString())); ret.push_back(Pair("msgHash", msgHash.ToString())); - ret.push_back(Pair("sig", sig.GetSig().ToString())); - ret.push_back(Pair("hash", sig.GetSig().GetHash().ToString())); + ret.push_back(Pair("sig", sig.Get().ToString())); + ret.push_back(Pair("hash", sig.Get().GetHash().ToString())); return ret; } @@ -224,12 +224,15 @@ void CRecoveredSigsDb::WriteRecoveredSig(const llmq::CRecoveredSig& recSig) { CDBBatch batch(db); + uint32_t curTime = GetAdjustedTime(); + // we put these close to each other to leverage leveldb's key compaction // this way, the second key can be used for fast HasRecoveredSig checks while the first key stores the recSig auto k1 = std::make_tuple(std::string("rs_r"), recSig.llmqType, recSig.id); auto k2 = std::make_tuple(std::string("rs_r"), recSig.llmqType, recSig.id, recSig.msgHash); batch.Write(k1, recSig); - batch.Write(k2, (uint8_t)1); + // this key is also used to store the current time, so that we can easily get to the "rs_t" key when we have the id + batch.Write(k2, curTime); // store by object hash auto k3 = std::make_tuple(std::string("rs_h"), recSig.GetHash()); @@ -241,7 +244,7 @@ void CRecoveredSigsDb::WriteRecoveredSig(const llmq::CRecoveredSig& recSig) batch.Write(k4, (uint8_t)1); // store by current time. Allows fast cleanup of old recSigs - auto k5 = std::make_tuple(std::string("rs_t"), (uint32_t)htobe32(GetAdjustedTime()), recSig.llmqType, recSig.id); + auto k5 = std::make_tuple(std::string("rs_t"), (uint32_t)htobe32(curTime), recSig.llmqType, recSig.id); batch.Write(k5, (uint8_t)1); db.WriteBatch(batch); @@ -256,6 +259,50 @@ void CRecoveredSigsDb::WriteRecoveredSig(const llmq::CRecoveredSig& recSig) } } +void CRecoveredSigsDb::RemoveRecoveredSig(CDBBatch& batch, Consensus::LLMQType llmqType, const uint256& id, bool deleteTimeKey) +{ + AssertLockHeld(cs); + + CRecoveredSig recSig; + if (!ReadRecoveredSig(llmqType, id, recSig)) { + return; + } + + auto signHash = CLLMQUtils::BuildSignHash(recSig); + + auto k1 = std::make_tuple(std::string("rs_r"), recSig.llmqType, recSig.id); + auto k2 = std::make_tuple(std::string("rs_r"), recSig.llmqType, recSig.id, recSig.msgHash); + auto k3 = std::make_tuple(std::string("rs_h"), recSig.GetHash()); + auto k4 = std::make_tuple(std::string("rs_s"), signHash); + batch.Erase(k1); + batch.Erase(k2); + batch.Erase(k3); + batch.Erase(k4); + + if (deleteTimeKey) { + CDataStream writeTimeDs(SER_DISK, CLIENT_VERSION); + // TODO remove the size() == sizeof(uint32_t) in a future version (when we stop supporting upgrades from < 0.14.1) + if (db.ReadDataStream(k2, writeTimeDs) && writeTimeDs.size() == sizeof(uint32_t)) { + uint32_t writeTime; + writeTimeDs >> writeTime; + auto k5 = std::make_tuple(std::string("rs_t"), (uint32_t) htobe32(writeTime), recSig.llmqType, recSig.id); + batch.Erase(k5); + } + } + + hasSigForIdCache.erase(std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.id)); + hasSigForSessionCache.erase(signHash); + hasSigForHashCache.erase(recSig.GetHash()); +} + +void CRecoveredSigsDb::RemoveRecoveredSig(Consensus::LLMQType llmqType, const uint256& id) +{ + LOCK(cs); + CDBBatch batch(db); + RemoveRecoveredSig(batch, llmqType, id, true); + db.WriteBatch(batch); +} + void CRecoveredSigsDb::CleanupOldRecoveredSigs(int64_t maxAge) { std::unique_ptr pcursor(db.NewIterator()); @@ -292,25 +339,7 @@ void CRecoveredSigsDb::CleanupOldRecoveredSigs(int64_t maxAge) { LOCK(cs); for (auto& e : toDelete) { - CRecoveredSig recSig; - if (!ReadRecoveredSig(e.first, e.second, recSig)) { - continue; - } - - auto signHash = CLLMQUtils::BuildSignHash(recSig); - - auto k1 = std::make_tuple(std::string("rs_r"), recSig.llmqType, recSig.id); - auto k2 = std::make_tuple(std::string("rs_r"), recSig.llmqType, recSig.id, recSig.msgHash); - auto k3 = std::make_tuple(std::string("rs_h"), recSig.GetHash()); - auto k4 = std::make_tuple(std::string("rs_s"), signHash); - batch.Erase(k1); - batch.Erase(k2); - batch.Erase(k3); - batch.Erase(k4); - - hasSigForIdCache.erase(std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.id)); - hasSigForSessionCache.erase(signHash); - hasSigForHashCache.erase(recSig.GetHash()); + RemoveRecoveredSig(batch, e.first, e.second, false); if (batch.SizeEstimate() >= (1 << 24)) { db.WriteBatch(batch); @@ -575,13 +604,13 @@ bool CSigningManager::ProcessPendingRecoveredSigs(CConnman& connman) for (auto& recSig : v) { // we didn't verify the lazy signature until now - if (!recSig.sig.GetSig().IsValid()) { + if (!recSig.sig.Get().IsValid()) { batchVerifier.badSources.emplace(nodeId); break; } const auto& quorum = quorums.at(std::make_pair((Consensus::LLMQType)recSig.llmqType, recSig.quorumHash)); - batchVerifier.PushMessage(nodeId, recSig.GetHash(), CLLMQUtils::BuildSignHash(recSig), recSig.sig.GetSig(), quorum->qc.quorumPublicKey); + batchVerifier.PushMessage(nodeId, recSig.GetHash(), CLLMQUtils::BuildSignHash(recSig), recSig.sig.Get(), quorum->qc.quorumPublicKey); verifyCount++; } } @@ -680,6 +709,11 @@ void CSigningManager::PushReconstructedRecoveredSig(const llmq::CRecoveredSig& r pendingReconstructedRecoveredSigs.emplace_back(recoveredSig, quorum); } +void CSigningManager::RemoveRecoveredSig(Consensus::LLMQType llmqType, const uint256& id) +{ + db.RemoveRecoveredSig(llmqType, id); +} + void CSigningManager::Cleanup() { int64_t now = GetTimeMillis(); @@ -815,7 +849,7 @@ bool CSigningManager::GetVoteForId(Consensus::LLMQType llmqType, const uint256& return db.GetVoteForId(llmqType, id, msgHashRet); } -CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType, int signHeight, const uint256& selectionHash) +std::vector CSigningManager::GetActiveQuorumSet(Consensus::LLMQType llmqType, int signHeight) { auto& llmqParams = Params().GetConsensus().llmqs.at(llmqType); size_t poolSize = (size_t)llmqParams.signingActiveQuorumCount; @@ -825,12 +859,17 @@ CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType LOCK(cs_main); int startBlockHeight = signHeight - SIGN_HEIGHT_OFFSET; if (startBlockHeight > chainActive.Height()) { - return nullptr; + return {}; } pindexStart = chainActive[startBlockHeight]; } - auto quorums = quorumManager->ScanQuorums(llmqType, pindexStart, poolSize); + return quorumManager->ScanQuorums(llmqType, pindexStart, poolSize); +} + +CQuorumCPtr CSigningManager::SelectQuorumForSigning(Consensus::LLMQType llmqType, int signHeight, const uint256& selectionHash) +{ + auto quorums = GetActiveQuorumSet(llmqType, signHeight); if (quorums.empty()) { return nullptr; } diff --git a/src/llmq/quorums_signing.h b/src/llmq/quorums_signing.h index 18060b2bf..cb0eb24db 100755 --- a/src/llmq/quorums_signing.h +++ b/src/llmq/quorums_signing.h @@ -84,6 +84,7 @@ class CRecoveredSigsDb bool GetRecoveredSigByHash(const uint256& hash, CRecoveredSig& ret); bool GetRecoveredSigById(Consensus::LLMQType llmqType, const uint256& id, CRecoveredSig& ret); void WriteRecoveredSig(const CRecoveredSig& recSig); + void RemoveRecoveredSig(Consensus::LLMQType llmqType, const uint256& id); void CleanupOldRecoveredSigs(int64_t maxAge); @@ -96,6 +97,7 @@ class CRecoveredSigsDb private: bool ReadRecoveredSig(Consensus::LLMQType llmqType, const uint256& id, CRecoveredSig& ret); + void RemoveRecoveredSig(CDBBatch& batch, Consensus::LLMQType llmqType, const uint256& id, bool deleteTimeKey); }; class CRecoveredSigsListener @@ -144,6 +146,10 @@ class CSigningManager // This is the case for example when a signature appears as part of InstantSend or ChainLocks void PushReconstructedRecoveredSig(const CRecoveredSig& recoveredSig, const CQuorumCPtr& quorum); + // This is called when a recovered signature can be safely removed from the DB. This is only safe when some other + // mechanism prevents possible conflicts. As an example, ChainLocks prevent conflicts in confirmed TXs InstantSend votes + void RemoveRecoveredSig(Consensus::LLMQType llmqType, const uint256& id); + private: void ProcessMessageRecoveredSig(CNode* pfrom, const CRecoveredSig& recoveredSig, CConnman& connman); bool PreVerifyRecoveredSig(NodeId nodeId, const CRecoveredSig& recoveredSig, bool& retBan); @@ -171,6 +177,7 @@ class CSigningManager bool HasVotedOnId(Consensus::LLMQType llmqType, const uint256& id); bool GetVoteForId(Consensus::LLMQType llmqType, const uint256& id, uint256& msgHashRet); + std::vector GetActiveQuorumSet(Consensus::LLMQType llmqType, int signHeight); CQuorumCPtr SelectQuorumForSigning(Consensus::LLMQType llmqType, int signHeight, const uint256& selectionHash); // Verifies a recovered sig that was signed while the chain tip was at signedAtTip diff --git a/src/llmq/quorums_signing_shares.cpp b/src/llmq/quorums_signing_shares.cpp index 73fb0c4cc..c38cbb59d 100755 --- a/src/llmq/quorums_signing_shares.cpp +++ b/src/llmq/quorums_signing_shares.cpp @@ -6,7 +6,7 @@ #include "quorums_signing_shares.h" #include "quorums_utils.h" -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "bls/bls_batchverifier.h" #include "init.h" #include "net_processing.h" @@ -589,7 +589,7 @@ bool CSigSharesManager::ProcessPendingSigShares(CConnman& connman) // we didn't check this earlier because we use a lazy BLS signature and tried to avoid doing the expensive // deserialization in the message thread - if (!sigShare.sigShare.GetSig().IsValid()) { + if (!sigShare.sigShare.Get().IsValid()) { BanNode(nodeId); // don't process any additional shares from this node break; @@ -605,7 +605,7 @@ bool CSigSharesManager::ProcessPendingSigShares(CConnman& connman) assert(false); } - batchVerifier.PushMessage(nodeId, sigShare.GetKey(), sigShare.GetSignHash(), sigShare.sigShare.GetSig(), pubKeyShare); + batchVerifier.PushMessage(nodeId, sigShare.GetKey(), sigShare.GetSignHash(), sigShare.sigShare.Get(), pubKeyShare); verifyCount++; } } @@ -676,7 +676,7 @@ void CSigSharesManager::ProcessSigShare(NodeId nodeId, const CSigShare& sigShare if (!sigShares.Add(sigShare.GetKey(), sigShare)) { return; } - + sigSharesToAnnounce.Add(sigShare.GetKey(), true); auto it = timeSeenForSessions.find(sigShare.GetSignHash()); @@ -735,7 +735,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256& idsForRecovery.reserve((size_t) quorum->params.threshold); for (auto it = sigShares->begin(); it != sigShares->end() && sigSharesForRecovery.size() < quorum->params.threshold; ++it) { auto& sigShare = it->second; - sigSharesForRecovery.emplace_back(sigShare.sigShare.GetSig()); + sigSharesForRecovery.emplace_back(sigShare.sigShare.Get()); idsForRecovery.emplace_back(CBLSId::FromHash(quorum->members[sigShare.quorumMember]->proTxHash)); } @@ -762,7 +762,7 @@ void CSigSharesManager::TryRecoverSig(const CQuorumCPtr& quorum, const uint256& rs.quorumHash = quorum->qc.quorumHash; rs.id = id; rs.msgHash = msgHash; - rs.sig.SetSig(recoveredSig); + rs.sig.Set(recoveredSig); rs.UpdateHash(); // There should actually be no need to verify the self-recovered signatures as it should always succeed. Let's @@ -1422,8 +1422,8 @@ void CSigSharesManager::Sign(const CQuorumCPtr& quorum, const uint256& id, const sigShare.quorumMember = (uint16_t)memberIdx; uint256 signHash = CLLMQUtils::BuildSignHash(sigShare); - sigShare.sigShare.SetSig(skShare.Sign(signHash)); - if (!sigShare.sigShare.GetSig().IsValid()) { + sigShare.sigShare.Set(skShare.Sign(signHash)); + if (!sigShare.sigShare.Get().IsValid()) { LogPrintf("CSigSharesManager::%s -- failed to sign sigShare. signHash=%s, id=%s, msgHash=%s, time=%s\n", __func__, signHash.ToString(), sigShare.id.ToString(), sigShare.msgHash.ToString(), t.count()); return; diff --git a/src/llmq/quorums_utils.cpp b/src/llmq/quorums_utils.cpp index 35b69e8e6..3a63f9e62 100755 --- a/src/llmq/quorums_utils.cpp +++ b/src/llmq/quorums_utils.cpp @@ -12,11 +12,11 @@ namespace llmq { -std::vector CLLMQUtils::GetAllQuorumMembers(Consensus::LLMQType llmqType, const uint256& blockHash) +std::vector CLLMQUtils::GetAllQuorumMembers(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum) { auto& params = Params().GetConsensus().llmqs.at(llmqType); - auto allMns = deterministicMNManager->GetListForBlock(blockHash); - auto modifier = ::SerializeHash(std::make_pair((uint8_t)llmqType, blockHash)); + auto allMns = deterministicMNManager->GetListForBlock(pindexQuorum); + auto modifier = ::SerializeHash(std::make_pair((uint8_t) llmqType, pindexQuorum->GetBlockHash())); return allMns.CalculateQuorum(params.size, modifier); } @@ -41,11 +41,11 @@ uint256 CLLMQUtils::BuildSignHash(Consensus::LLMQType llmqType, const uint256& q return h.GetHash(); } -std::set CLLMQUtils::GetQuorumConnections(Consensus::LLMQType llmqType, const uint256& blockHash, const uint256& forMember) +std::set CLLMQUtils::GetQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& forMember) { auto& params = Params().GetConsensus().llmqs.at(llmqType); - auto mns = GetAllQuorumMembers(llmqType, blockHash); + auto mns = GetAllQuorumMembers(llmqType, pindexQuorum); std::set result; for (size_t i = 0; i < mns.size(); i++) { auto& dmn = mns[i]; @@ -73,7 +73,7 @@ std::set CLLMQUtils::GetQuorumConnections(Consensus::LLMQType llmqType, return result; } -std::set CLLMQUtils::CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, const uint256& blockHash, size_t memberCount, size_t connectionCount) +std::set CLLMQUtils::CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, size_t memberCount, size_t connectionCount) { static uint256 qwatchConnectionSeed; static std::atomic qwatchConnectionSeedGenerated{false}; @@ -89,7 +89,7 @@ std::set CLLMQUtils::CalcDeterministicWatchConnections(Consensus::LLMQTy std::set result; uint256 rnd = qwatchConnectionSeed; for (size_t i = 0; i < connectionCount; i++) { - rnd = ::SerializeHash(std::make_pair(rnd, std::make_pair((uint8_t)llmqType, blockHash))); + rnd = ::SerializeHash(std::make_pair(rnd, std::make_pair((uint8_t) llmqType, pindexQuorum->GetBlockHash()))); result.emplace(rnd.GetUint64(0) % memberCount); } return result; diff --git a/src/llmq/quorums_utils.h b/src/llmq/quorums_utils.h index 75f00e1de..26eadecbe 100755 --- a/src/llmq/quorums_utils.h +++ b/src/llmq/quorums_utils.h @@ -19,7 +19,7 @@ class CLLMQUtils { public: // includes members which failed DKG - static std::vector GetAllQuorumMembers(Consensus::LLMQType llmqType, const uint256& blockHash); + static std::vector GetAllQuorumMembers(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum); static uint256 BuildCommitmentHash(uint8_t llmqType, const uint256& blockHash, const std::vector& validMembers, const CBLSPublicKey& pubKey, const uint256& vvecHash); static uint256 BuildSignHash(Consensus::LLMQType llmqType, const uint256& quorumHash, const uint256& id, const uint256& msgHash); @@ -31,8 +31,8 @@ class CLLMQUtils return BuildSignHash((Consensus::LLMQType)s.llmqType, s.quorumHash, s.id, s.msgHash); } - static std::set GetQuorumConnections(Consensus::LLMQType llmqType, const uint256& blockHash, const uint256& forMember); - static std::set CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, const uint256& blockHash, size_t memberCount, size_t connectionCount); + static std::set GetQuorumConnections(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, const uint256& forMember); + static std::set CalcDeterministicWatchConnections(Consensus::LLMQType llmqType, const CBlockIndex* pindexQuorum, size_t memberCount, size_t connectionCount); static bool IsQuorumActive(Consensus::LLMQType llmqType, const uint256& quorumHash); diff --git a/src/activemasternode.cpp b/src/masternode/activemasternode.cpp similarity index 99% rename from src/activemasternode.cpp rename to src/masternode/activemasternode.cpp index 3484c16eb..a5eb145ce 100755 --- a/src/activemasternode.cpp +++ b/src/masternode/activemasternode.cpp @@ -5,7 +5,7 @@ #include "activemasternode.h" #include "evo/deterministicmns.h" #include "init.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "netbase.h" #include "protocol.h" #include "validation.h" @@ -134,7 +134,7 @@ void CActiveMasternodeManager::UpdatedBlockTip(const CBlockIndex* pindexNew, con if (!deterministicMNManager->IsDIP3Enforced(pindexNew->nHeight)) return; if (state == MASTERNODE_READY) { - auto mnList = deterministicMNManager->GetListForBlock(pindexNew->GetBlockHash()); + auto mnList = deterministicMNManager->GetListForBlock(pindexNew); if (!mnList.IsMNValid(mnListEntry->proTxHash)) { // MN disappeared from MN list state = MASTERNODE_REMOVED; diff --git a/src/activemasternode.h b/src/masternode/activemasternode.h similarity index 100% rename from src/activemasternode.h rename to src/masternode/activemasternode.h diff --git a/src/masternode-meta.cpp b/src/masternode/masternode-meta.cpp similarity index 96% rename from src/masternode-meta.cpp rename to src/masternode/masternode-meta.cpp index 18f07f1be..9ec37b9e2 100755 --- a/src/masternode-meta.cpp +++ b/src/masternode/masternode-meta.cpp @@ -118,7 +118,6 @@ std::string CMasternodeMetaMan::ToString() const std::ostringstream info; info << "Masternodes: meta infos object count: " << (int)metaInfos.size() << - ", deterministic masternode count: " << deterministicMNManager->GetListAtChainTip().GetAllMNsCount() << ", nDsqCount: " << (int)nDsqCount; return info.str(); } diff --git a/src/masternode-meta.h b/src/masternode/masternode-meta.h similarity index 97% rename from src/masternode-meta.h rename to src/masternode/masternode-meta.h index 8ef5c753f..fe4104611 100755 --- a/src/masternode-meta.h +++ b/src/masternode/masternode-meta.h @@ -100,7 +100,11 @@ class CMasternodeMetaMan std::string strVersion; if(ser_action.ForRead()) { + Clear(); READWRITE(strVersion); + if (strVersion != SERIALIZATION_VERSION_STRING) { + return; + } } else { strVersion = SERIALIZATION_VERSION_STRING; @@ -122,10 +126,6 @@ class CMasternodeMetaMan } READWRITE(nDsqCount); - - if(ser_action.ForRead() && (strVersion != SERIALIZATION_VERSION_STRING)) { - Clear(); - } } public: diff --git a/src/masternode-payments.cpp b/src/masternode/masternode-payments.cpp similarity index 97% rename from src/masternode-payments.cpp rename to src/masternode/masternode-payments.cpp index 241aef1b7..7e31b428f 100755 --- a/src/masternode-payments.cpp +++ b/src/masternode/masternode-payments.cpp @@ -2,12 +2,12 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "consensus/validation.h" -#include "governance-classes.h" +#include "governance/governance-classes.h" #include "init.h" -#include "masternode-payments.h" -#include "masternode-sync.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" #include "messagesigner.h" #include "netfulfilledman.h" #include "netmessagemaker.h" @@ -271,7 +271,7 @@ std::map GetRequiredPaymentsStrings(int nStartHeight, int nEnd bool doProjection = false; for(int h = nStartHeight; h < nEndHeight; h++) { if (h <= nChainTipHeight) { - auto payee = deterministicMNManager->GetListForBlock(chainActive[h - 1]->GetBlockHash()).GetMNPayee(); + auto payee = deterministicMNManager->GetListForBlock(chainActive[h - 1]).GetMNPayee(); mapPayments.emplace(h, GetRequiredPaymentsString(h, payee)); } else { doProjection = true; @@ -323,13 +323,13 @@ bool CMasternodePayments::GetBlockTxOuts(int nBlockHeight, CAmount blockReward, CAmount masternodeReward = GetMasternodePayment(nBlockHeight, blockReward); - uint256 blockHash; + const CBlockIndex* pindex; { LOCK(cs_main); - blockHash = chainActive[nBlockHeight - 1]->GetBlockHash(); + pindex = chainActive[nBlockHeight - 1]; } uint256 proTxHash; - auto dmnPayee = deterministicMNManager->GetListForBlock(blockHash).GetMNPayee(); + auto dmnPayee = deterministicMNManager->GetListForBlock(pindex).GetMNPayee(); if (!dmnPayee) { return false; } diff --git a/src/masternode-payments.h b/src/masternode/masternode-payments.h similarity index 100% rename from src/masternode-payments.h rename to src/masternode/masternode-payments.h diff --git a/src/masternode-sync.cpp b/src/masternode/masternode-sync.cpp similarity index 99% rename from src/masternode-sync.cpp rename to src/masternode/masternode-sync.cpp index 5f5744a3a..1dea1bba8 100755 --- a/src/masternode-sync.cpp +++ b/src/masternode/masternode-sync.cpp @@ -2,12 +2,12 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "activemasternode.h" -#include "governance.h" +#include "masternode/activemasternode.h" +#include "governance/governance.h" #include "init.h" #include "validation.h" -#include "masternode-payments.h" -#include "masternode-sync.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" #include "netfulfilledman.h" #include "netmessagemaker.h" #include "ui_interface.h" diff --git a/src/masternode-sync.h b/src/masternode/masternode-sync.h similarity index 100% rename from src/masternode-sync.h rename to src/masternode/masternode-sync.h diff --git a/src/masternode-utils.cpp b/src/masternode/masternode-utils.cpp similarity index 96% rename from src/masternode-utils.cpp rename to src/masternode/masternode-utils.cpp index a714fc190..28ec48aff 100755 --- a/src/masternode-utils.cpp +++ b/src/masternode/masternode-utils.cpp @@ -2,12 +2,12 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "masternode-utils.h" +#include "masternode/masternode-utils.h" #include "init.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #ifdef ENABLE_WALLET -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #endif #include "validation.h" @@ -105,4 +105,3 @@ void CMasternodeUtils::DoMaintenance(CConnman& connman) ProcessMasternodeConnections(connman); } } - diff --git a/src/masternode-utils.h b/src/masternode/masternode-utils.h similarity index 100% rename from src/masternode-utils.h rename to src/masternode/masternode-utils.h diff --git a/src/miner.cpp b/src/miner.cpp index 3663e86fc..b2fa8a080 100755 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -24,8 +24,8 @@ #include "txmempool.h" #include "util.h" #include "utilmoneystr.h" -#include "masternode-payments.h" -#include "masternode-sync.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" #include "validationinterface.h" #include "evo/specialtx.h" diff --git a/src/net.cpp b/src/net.cpp index b30a28e99..9f44ba529 100755 --- a/src/net.cpp +++ b/src/net.cpp @@ -25,9 +25,9 @@ #include "utilstrencodings.h" #include "validation.h" -#include "instantx.h" -#include "masternode-sync.h" -#include "privatesend.h" +#include "instantsend.h" +#include "masternode/masternode-sync.h" +#include "privatesend/privatesend.h" #include "llmq/quorums_instantsend.h" #ifdef WIN32 @@ -52,10 +52,15 @@ // We add a random period time (0 to 1 seconds) to feeler connections to prevent synchronization. #define FEELER_SLEEP_WINDOW 1 -#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) +#if !defined(HAVE_MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 #endif +// MSG_DONTWAIT is not available on some platforms, if it doesn't exist define it as 0 +#if !defined(HAVE_MSG_DONTWAIT) +#define MSG_DONTWAIT 0 +#endif + // Fix for ancient MinGW versions, that don't have defined these in ws2tcpip.h. // Todo: Can be removed when our pull-tester is upgraded to a modern MinGW version. #ifdef WIN32 @@ -1862,9 +1867,9 @@ void CConnman::ThreadOpenConnections() // * Increase the number of connectable addresses in the tried table. // // Method: - // * Choose a random address from new and attempt to connect to it if we can connect + // * Choose a random address from new and attempt to connect to it if we can connect // successfully it is added to tried. - // * Start attempting feeler connections only after node finishes making outbound + // * Start attempting feeler connections only after node finishes making outbound // connections. // * Only make a feeler connection once every few minutes. // @@ -1887,7 +1892,7 @@ void CConnman::ThreadOpenConnections() { CAddrInfo addr = addrman.Select(fFeeler); - bool isMasternode = mnList.GetValidMNByService(addr) != nullptr; + bool isMasternode = mnList.GetMNByService(addr) != nullptr; // if we selected an invalid address, restart if (!addr.IsValid() || setConnected.count(addr.GetGroup())) @@ -2070,6 +2075,8 @@ void CConnman::ThreadOpenMasternodeConnections() if (interruptNet) return; + int64_t nANow = GetAdjustedTime(); + // NOTE: Process only one pending masternode at a time CService addr; @@ -2079,12 +2086,17 @@ void CConnman::ThreadOpenMasternodeConnections() std::vector pending; for (const auto& group : masternodeQuorumNodes) { for (const auto& proRegTxHash : group.second) { - auto dmn = mnList.GetValidMN(proRegTxHash); + auto dmn = mnList.GetMN(proRegTxHash); if (!dmn) { continue; } const auto& addr2 = dmn->pdmnState->addr; if (!connectedNodes.count(addr2) && !IsMasternodeOrDisconnectRequested(addr2) && !connectedProRegTxHashes.count(proRegTxHash)) { + auto addrInfo = addrman.GetAddressInfo(addr2); + // back off trying connecting to an address if we already tried recently + if (addrInfo.IsValid() && nANow - addrInfo.nLastTry < 60) { + continue; + } pending.emplace_back(addr2); } } @@ -2681,11 +2693,6 @@ void CConnman::MarkAddressGood(const CAddress& addr) addrman.Good(addr); } -void CConnman::AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty) -{ - addrman.Add(addr, addrFrom, nTimePenalty); -} - void CConnman::AddNewAddresses(const std::vector& vAddr, const CAddress& addrFrom, int64_t nTimePenalty) { addrman.Add(vAddr, addrFrom, nTimePenalty); @@ -2797,7 +2804,7 @@ bool CConnman::IsMasternodeQuorumNode(const CNode* pnode) uint256 assumedProTxHash; if (pnode->verifiedProRegTxHash.IsNull() && !pnode->fInbound) { auto mnList = deterministicMNManager->GetListAtChainTip(); - auto dmn = mnList.GetValidMNByService(pnode->addr); + auto dmn = mnList.GetMNByService(pnode->addr); if (dmn == nullptr) { // This is definitely not a masternode return false; diff --git a/src/net.h b/src/net.h index 4bf1a8206..57a8b07d7 100755 --- a/src/net.h +++ b/src/net.h @@ -336,7 +336,6 @@ class CConnman size_t GetAddressCount() const; void SetServices(const CService &addr, ServiceFlags nServices); void MarkAddressGood(const CAddress& addr); - void AddNewAddress(const CAddress& addr, const CAddress& addrFrom, int64_t nTimePenalty = 0); void AddNewAddresses(const std::vector& vAddr, const CAddress& addrFrom, int64_t nTimePenalty = 0); std::vector GetAddresses(); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 180690ff3..523b0a766 100755 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -32,15 +32,15 @@ #include "validationinterface.h" #include "spork.h" -#include "governance.h" -#include "instantx.h" -#include "masternode-payments.h" -#include "masternode-sync.h" -#include "masternode-meta.h" +#include "governance/governance.h" +#include "instantsend.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" +#include "masternode/masternode-meta.h" #ifdef ENABLE_WALLET -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #endif // ENABLE_WALLET -#include "privatesend-server.h" +#include "privatesend/privatesend-server.h" #include "evo/deterministicmns.h" #include "evo/mnauth.h" @@ -2161,7 +2161,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr return true; // not an error } - auto dmn = deterministicMNManager->GetListAtChainTip().GetValidMNByCollateral(dstx.masternodeOutpoint); + auto dmn = deterministicMNManager->GetListAtChainTip().GetMNByCollateral(dstx.masternodeOutpoint); if(!dmn) { LogPrint("privatesend", "DSTX -- Can't find masternode %s to verify %s\n", dstx.masternodeOutpoint.ToStringShort(), hashTx.ToString()); return false; @@ -2174,7 +2174,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr // we have no idea about (e.g we were offline)? How to handle them? } - if (!dstx.CheckSignature(dmn->pdmnState->pubKeyOperator)) { + if (!dstx.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) { LogPrint("privatesend", "DSTX -- CheckSignature() failed for %s\n", hashTx.ToString()); return false; } diff --git a/src/netbase.cpp b/src/netbase.cpp index b8b3993fc..12a62ef69 100755 --- a/src/netbase.cpp +++ b/src/netbase.cpp @@ -25,7 +25,7 @@ #include // for to_lower() #include // for startswith() and endswith() -#if !defined(HAVE_MSG_NOSIGNAL) && !defined(MSG_NOSIGNAL) +#if !defined(HAVE_MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 #endif diff --git a/src/privatesend-client.cpp b/src/privatesend/privatesend-client.cpp similarity index 99% rename from src/privatesend-client.cpp rename to src/privatesend/privatesend-client.cpp index af1d9059f..3f3566647 100755 --- a/src/privatesend-client.cpp +++ b/src/privatesend/privatesend-client.cpp @@ -7,9 +7,9 @@ #include "consensus/validation.h" #include "core_io.h" #include "init.h" -#include "masternode-payments.h" -#include "masternode-sync.h" -#include "masternode-meta.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" +#include "masternode/masternode-meta.h" #include "netmessagemaker.h" #include "script/sign.h" #include "txmempool.h" @@ -66,7 +66,7 @@ void CPrivateSendClientManager::ProcessMessage(CNode* pfrom, const std::string& auto dmn = mnList.GetValidMNByCollateral(dsq.masternodeOutpoint); if (!dmn) return; - if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator)) { + if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) { LOCK(cs_main); Misbehaving(pfrom->id, 10); return; @@ -712,6 +712,11 @@ void CPrivateSendClientManager::AddSkippedDenom(const CAmount& nDenomValue) vecDenominationsSkipped.push_back(nDenomValue); } +void CPrivateSendClientManager::RemoveSkippedDenom(const CAmount& nDenomValue) +{ + vecDenominationsSkipped.erase(std::remove(vecDenominationsSkipped.begin(), vecDenominationsSkipped.end(), nDenomValue), vecDenominationsSkipped.end()); +} + bool CPrivateSendClientManager::WaitForAnotherBlock() { if (!masternodeSync.IsBlockchainSynced()) diff --git a/src/privatesend-client.h b/src/privatesend/privatesend-client.h similarity index 99% rename from src/privatesend-client.h rename to src/privatesend/privatesend-client.h index bc987b335..b004a9cb5 100755 --- a/src/privatesend-client.h +++ b/src/privatesend/privatesend-client.h @@ -232,7 +232,7 @@ class CPrivateSendClientManager : public CPrivateSendBaseManager bool IsDenomSkipped(const CAmount& nDenomValue); void AddSkippedDenom(const CAmount& nDenomValue); - void ClearSkippedDenominations() { vecDenominationsSkipped.clear(); } + void RemoveSkippedDenom(const CAmount& nDenomValue); void SetMinBlocksToWait(int nMinBlocksToWaitIn) { nMinBlocksToWait = nMinBlocksToWaitIn; } diff --git a/src/privatesend-server.cpp b/src/privatesend/privatesend-server.cpp similarity index 99% rename from src/privatesend-server.cpp rename to src/privatesend/privatesend-server.cpp index 8fa28ca0d..c9bfa5265 100755 --- a/src/privatesend-server.cpp +++ b/src/privatesend/privatesend-server.cpp @@ -4,12 +4,12 @@ #include "privatesend-server.h" -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "consensus/validation.h" #include "core_io.h" #include "init.h" -#include "masternode-meta.h" -#include "masternode-sync.h" +#include "masternode/masternode-meta.h" +#include "masternode/masternode-sync.h" #include "net_processing.h" #include "netmessagemaker.h" #include "script/interpreter.h" @@ -121,7 +121,7 @@ void CPrivateSendServer::ProcessMessage(CNode* pfrom, const std::string& strComm auto dmn = mnList.GetValidMNByCollateral(dsq.masternodeOutpoint); if (!dmn) return; - if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator)) { + if (!dsq.CheckSignature(dmn->pdmnState->pubKeyOperator.Get())) { LOCK(cs_main); Misbehaving(pfrom->id, 10); return; diff --git a/src/privatesend-server.h b/src/privatesend/privatesend-server.h similarity index 100% rename from src/privatesend-server.h rename to src/privatesend/privatesend-server.h diff --git a/src/privatesend-util.cpp b/src/privatesend/privatesend-util.cpp similarity index 100% rename from src/privatesend-util.cpp rename to src/privatesend/privatesend-util.cpp diff --git a/src/privatesend-util.h b/src/privatesend/privatesend-util.h similarity index 100% rename from src/privatesend-util.h rename to src/privatesend/privatesend-util.h diff --git a/src/privatesend.cpp b/src/privatesend/privatesend.cpp similarity index 99% rename from src/privatesend.cpp rename to src/privatesend/privatesend.cpp index 84774b3eb..36b4a3cd4 100755 --- a/src/privatesend.cpp +++ b/src/privatesend/privatesend.cpp @@ -4,10 +4,10 @@ #include "privatesend.h" -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "consensus/validation.h" -#include "masternode-payments.h" -#include "masternode-sync.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" #include "messagesigner.h" #include "netmessagemaker.h" #include "script/sign.h" diff --git a/src/privatesend.h b/src/privatesend/privatesend.h similarity index 100% rename from src/privatesend.h rename to src/privatesend/privatesend.h diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index a23a7351b..5cb84b342 100755 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -24,6 +24,7 @@ #include "utilitydialog.h" #ifdef ENABLE_WALLET +#include "privatesend/privatesend-client.h" #include "walletframe.h" #include "walletmodel.h" #endif // ENABLE_WALLET @@ -36,7 +37,7 @@ #include "init.h" #include "ui_interface.h" #include "util.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "masternodelist.h" #include @@ -266,6 +267,10 @@ BitcoinGUI::BitcoinGUI(const PlatformStyle *_platformStyle, const NetworkStyle * connect(progressBar, SIGNAL(clicked(QPoint)), this, SLOT(showModalOverlay())); } #endif + +#ifdef Q_OS_MAC + m_app_nap_inhibitor = new CAppNapInhibitor; +#endif } BitcoinGUI::~BitcoinGUI() @@ -277,6 +282,7 @@ BitcoinGUI::~BitcoinGUI() if(trayIcon) // Hide tray icon, as deleting will let it linger until quit (on Ubuntu) trayIcon->hide(); #ifdef Q_OS_MAC + delete m_app_nap_inhibitor; delete appMenuBar; MacDockIconHandler::cleanup(); #endif @@ -465,7 +471,7 @@ void BitcoinGUI::createActions() // Get restart command-line parameters and handle restart connect(rpcConsole, SIGNAL(handleRestart(QStringList)), this, SLOT(handleRestart(QStringList))); - + // prevents an open debug window from becoming stuck/unusable on client shutdown connect(quitAction, SIGNAL(triggered()), rpcConsole, SLOT(hide())); @@ -607,7 +613,7 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) MacDockIconHandler *dockIconHandler = MacDockIconHandler::instance(); dockIconHandler->setMainWindow((QMainWindow *)this); dockIconMenu = dockIconHandler->dockMenu(); - + createIconMenu(dockIconMenu); #endif } @@ -638,13 +644,13 @@ void BitcoinGUI::setClientModel(ClientModel *_clientModel) } #endif // ENABLE_WALLET unitDisplayControl->setOptionsModel(_clientModel->getOptionsModel()); - + OptionsModel* optionsModel = _clientModel->getOptionsModel(); if(optionsModel) { // be aware of the tray icon disable state change reported by the OptionsModel object. connect(optionsModel,SIGNAL(hideTrayIconChanged(bool)),this,SLOT(setTrayIconVisible(bool))); - + // initialize the disable state of the tray icon with the current value in the model. setTrayIconVisible(optionsModel->getHideTrayIcon()); } @@ -950,6 +956,19 @@ void BitcoinGUI::updateHeadersSyncProgressLabel() void BitcoinGUI::setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool header) { +#ifdef Q_OS_MAC + // Disabling macOS App Nap on initial sync, disk, reindex operations and mixing. + bool disableAppNap = !masternodeSync.IsSynced(); +#ifdef ENABLE_WALLET + disableAppNap |= privateSendClient.fEnablePrivateSend; +#endif // ENABLE_WALLET + if (disableAppNap) { + m_app_nap_inhibitor->disableAppNap(); + } else { + m_app_nap_inhibitor->enableAppNap(); + } +#endif // Q_OS_MAC + if (modalOverlay) { if (header) diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index 20f7b7495..d8bc81b1c 100755 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -19,6 +19,10 @@ #include #include +#ifdef Q_OS_MAC +#include +#endif + class ClientModel; class NetworkStyle; class Notificator; @@ -133,6 +137,10 @@ class BitcoinGUI : public QMainWindow HelpMessageDialog *helpMessageDialog; ModalOverlay *modalOverlay; +#ifdef Q_OS_MAC + CAppNapInhibitor* m_app_nap_inhibitor = nullptr; +#endif + /** Keep track of previous number of blocks, to detect progress */ int prevBlocks; int spinnerFrame; diff --git a/src/qt/clientmodel.cpp b/src/qt/clientmodel.cpp index 1ba75e691..bc5cb0346 100755 --- a/src/qt/clientmodel.cpp +++ b/src/qt/clientmodel.cpp @@ -20,8 +20,10 @@ #include "ui_interface.h" #include "util.h" -#include "masternode-sync.h" -#include "privatesend.h" +#include "masternode/masternode-sync.h" +#include "privatesend/privatesend.h" + +#include "llmq/quorums_instantsend.h" #include @@ -161,6 +163,14 @@ size_t ClientModel::getMempoolDynamicUsage() const return mempool.DynamicMemoryUsage(); } +size_t ClientModel::getInstantSentLockCount() const +{ + if (!llmq::quorumInstantSendManager) { + return 0; + } + return llmq::quorumInstantSendManager->GetInstantSendLockCount(); +} + double ClientModel::getVerificationProgress(const CBlockIndex *tipIn) const { CBlockIndex *tip = const_cast(tipIn); @@ -177,6 +187,7 @@ void ClientModel::updateTimer() // no locking required at this point // the following calls will acquire the required lock Q_EMIT mempoolSizeChanged(getMempoolSize(), getMempoolDynamicUsage()); + Q_EMIT islockCountChanged(getInstantSentLockCount()); Q_EMIT bytesChanged(getTotalBytesRecv(), getTotalBytesSent()); } @@ -353,16 +364,9 @@ static void BlockTipChanged(ClientModel *clientmodel, bool initialSync, const CB } } -static void NotifyMasternodeListChanged(ClientModel *clientmodel) +static void NotifyMasternodeListChanged(ClientModel *clientmodel, const CDeterministicMNList& newList) { - static int64_t nLastMasternodeUpdateNotification = 0; - int64_t now = GetTimeMillis(); - // if we are in-sync, update the UI regardless of last update time - // no need to refresh masternode list/stats as often as blocks etc. - if (masternodeSync.IsBlockchainSynced() || now - nLastMasternodeUpdateNotification > MODEL_UPDATE_DELAY*4*5) { - clientmodel->refreshMasternodeList(); - nLastMasternodeUpdateNotification = now; - } + clientmodel->setMasternodeList(newList); } static void NotifyAdditionalDataSyncProgressChanged(ClientModel *clientmodel, double nSyncProgress) @@ -381,7 +385,7 @@ void ClientModel::subscribeToCoreSignals() uiInterface.BannedListChanged.connect(boost::bind(BannedListChanged, this)); uiInterface.NotifyBlockTip.connect(boost::bind(BlockTipChanged, this, _1, _2, false)); uiInterface.NotifyHeaderTip.connect(boost::bind(BlockTipChanged, this, _1, _2, true)); - uiInterface.NotifyMasternodeListChanged.connect(boost::bind(NotifyMasternodeListChanged, this)); + uiInterface.NotifyMasternodeListChanged.connect(boost::bind(NotifyMasternodeListChanged, this, _1)); uiInterface.NotifyAdditionalDataSyncProgressChanged.connect(boost::bind(NotifyAdditionalDataSyncProgressChanged, this, _1)); } @@ -395,6 +399,6 @@ void ClientModel::unsubscribeFromCoreSignals() uiInterface.BannedListChanged.disconnect(boost::bind(BannedListChanged, this)); uiInterface.NotifyBlockTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, false)); uiInterface.NotifyHeaderTip.disconnect(boost::bind(BlockTipChanged, this, _1, _2, true)); - uiInterface.NotifyMasternodeListChanged.disconnect(boost::bind(NotifyMasternodeListChanged, this)); + uiInterface.NotifyMasternodeListChanged.disconnect(boost::bind(NotifyMasternodeListChanged, this, _1)); uiInterface.NotifyAdditionalDataSyncProgressChanged.disconnect(boost::bind(NotifyAdditionalDataSyncProgressChanged, this, _1)); } diff --git a/src/qt/clientmodel.h b/src/qt/clientmodel.h index 4b1fd25a3..db90f092f 100755 --- a/src/qt/clientmodel.h +++ b/src/qt/clientmodel.h @@ -63,6 +63,8 @@ class ClientModel : public QObject long getMempoolSize() const; //! Return the dynamic memory usage of the mempool size_t getMempoolDynamicUsage() const; + //! Return number of ISLOCKs + size_t getInstantSentLockCount() const; void setMasternodeList(const CDeterministicMNList& mnList); CDeterministicMNList getMasternodeList() const; @@ -117,6 +119,7 @@ class ClientModel : public QObject void numBlocksChanged(int count, const QDateTime& blockDate, double nVerificationProgress, bool header); void additionalDataSyncProgressChanged(double nSyncProgress); void mempoolSizeChanged(long count, size_t mempoolSizeInBytes); + void islockCountChanged(size_t count); void networkActiveChanged(bool networkActive); void alertsChanged(const QString &warnings); void bytesChanged(quint64 totalBytesIn, quint64 totalBytesOut); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 25827b177..166b4382a 100755 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -20,8 +20,8 @@ #include "validation.h" // For mempool #include "wallet/wallet.h" -#include "instantx.h" -#include "privatesend-client.h" +#include "instantsend.h" +#include "privatesend/privatesend-client.h" #include // for 'map_list_of()' diff --git a/src/qt/forms/debugwindow.ui b/src/qt/forms/debugwindow.ui index c4d92dd70..8290d6106 100755 --- a/src/qt/forms/debugwindow.ui +++ b/src/qt/forms/debugwindow.ui @@ -408,6 +408,20 @@ + + + + InstantSend locks + + + + + + + N/A + + + @@ -659,7 +673,7 @@ - &Clear + &Reset false diff --git a/src/qt/macos_appnap.h b/src/qt/macos_appnap.h new file mode 100644 index 000000000..8c2cd840b --- /dev/null +++ b/src/qt/macos_appnap.h @@ -0,0 +1,24 @@ +// Copyright (c) 2011-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#ifndef BITCOIN_QT_MACOS_APPNAP_H +#define BITCOIN_QT_MACOS_APPNAP_H + +#include + +class CAppNapInhibitor final +{ +public: + explicit CAppNapInhibitor(); + ~CAppNapInhibitor(); + + void disableAppNap(); + void enableAppNap(); + +private: + class CAppNapImpl; + std::unique_ptr impl; +}; + +#endif // BITCOIN_QT_MACOS_APPNAP_H diff --git a/src/qt/macos_appnap.mm b/src/qt/macos_appnap.mm new file mode 100644 index 000000000..8fab9c330 --- /dev/null +++ b/src/qt/macos_appnap.mm @@ -0,0 +1,71 @@ +// Copyright (c) 2011-2018 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#include "macos_appnap.h" + +#include +#include +#include + +class CAppNapInhibitor::CAppNapImpl +{ +public: + ~CAppNapImpl() + { + if(activityId) + enableAppNap(); + } + + void disableAppNap() + { + if (!activityId) + { + @autoreleasepool { + const NSActivityOptions activityOptions = + NSActivityUserInitiatedAllowingIdleSystemSleep & + ~(NSActivitySuddenTerminationDisabled | + NSActivityAutomaticTerminationDisabled); + + id processInfo = [NSProcessInfo processInfo]; + if ([processInfo respondsToSelector:@selector(beginActivityWithOptions:reason:)]) + { + activityId = [processInfo beginActivityWithOptions: activityOptions reason:@"Temporarily disable App Nap for axe-qt."]; + [activityId retain]; + } + } + } + } + + void enableAppNap() + { + if(activityId) + { + @autoreleasepool { + id processInfo = [NSProcessInfo processInfo]; + if ([processInfo respondsToSelector:@selector(endActivity:)]) + [processInfo endActivity:activityId]; + + [activityId release]; + activityId = nil; + } + } + } + +private: + NSObject* activityId; +}; + +CAppNapInhibitor::CAppNapInhibitor() : impl(new CAppNapImpl()) {} + +CAppNapInhibitor::~CAppNapInhibitor() = default; + +void CAppNapInhibitor::disableAppNap() +{ + impl->disableAppNap(); +} + +void CAppNapInhibitor::enableAppNap() +{ + impl->enableAppNap(); +} diff --git a/src/qt/masternodelist.cpp b/src/qt/masternodelist.cpp index b1f04036e..b86a84053 100755 --- a/src/qt/masternodelist.cpp +++ b/src/qt/masternodelist.cpp @@ -1,12 +1,12 @@ #include "masternodelist.h" #include "ui_masternodelist.h" -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "clientmodel.h" #include "clientversion.h" #include "guiutil.h" #include "init.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "netbase.h" #include "sync.h" #include "wallet/wallet.h" @@ -35,7 +35,9 @@ MasternodeList::MasternodeList(const PlatformStyle* platformStyle, QWidget* pare clientModel(0), walletModel(0), fFilterUpdatedDIP3(true), - nTimeFilterUpdatedDIP3(0) + nTimeFilterUpdatedDIP3(0), + nTimeUpdatedDIP3(0), + mnListChanged(true) { ui->setupUi(this); @@ -89,7 +91,7 @@ void MasternodeList::setClientModel(ClientModel* model) this->clientModel = model; if (model) { // try to update list when masternode count changes - connect(clientModel, SIGNAL(masternodeListChanged()), this, SLOT(updateDIP3ListForced())); + connect(clientModel, SIGNAL(masternodeListChanged()), this, SLOT(handleMasternodeListChanged())); } } @@ -104,37 +106,48 @@ void MasternodeList::showContextMenuDIP3(const QPoint& point) if (item) contextMenuDIP3->exec(QCursor::pos()); } -void MasternodeList::updateDIP3ListScheduled() +void MasternodeList::handleMasternodeListChanged() { - updateDIP3List(false); + LOCK(cs_dip3list); + mnListChanged = true; } -void MasternodeList::updateDIP3ListForced() +void MasternodeList::updateDIP3ListScheduled() { - updateDIP3List(true); -} + TRY_LOCK(cs_dip3list, fLockAcquired); + if (!fLockAcquired) return; -void MasternodeList::updateDIP3List(bool fForce) -{ if (!clientModel || ShutdownRequested()) { return; } - TRY_LOCK(cs_dip3list, fLockAcquired); - if (!fLockAcquired) return; - // To prevent high cpu usage update only once in MASTERNODELIST_FILTER_COOLDOWN_SECONDS seconds // after filter was last changed unless we want to force the update. - if (!fForce) { - if (!fFilterUpdatedDIP3) return; - + if (fFilterUpdatedDIP3) { int64_t nSecondsToWait = nTimeFilterUpdatedDIP3 - GetTime() + MASTERNODELIST_FILTER_COOLDOWN_SECONDS; ui->countLabelDIP3->setText(QString::fromStdString(strprintf("Please wait... %d", nSecondsToWait))); - if (nSecondsToWait > 0) return; + if (nSecondsToWait <= 0) { + updateDIP3List(); + fFilterUpdatedDIP3 = false; + } + } else if (mnListChanged) { + int64_t nSecondsToWait = nTimeUpdatedDIP3 - GetTime() + MASTERNODELIST_UPDATE_SECONDS; + + if (nSecondsToWait <= 0) { + updateDIP3List(); + mnListChanged = false; + } + } +} + +void MasternodeList::updateDIP3List() +{ + if (!clientModel || ShutdownRequested()) { + return; } - fFilterUpdatedDIP3 = false; + LOCK(cs_dip3list); QString strToFilter; ui->countLabelDIP3->setText("Updating..."); @@ -143,6 +156,8 @@ void MasternodeList::updateDIP3List(bool fForce) ui->tableWidgetMasternodesDIP3->setRowCount(0); auto mnList = clientModel->getMasternodeList(); + nTimeUpdatedDIP3 = GetTime(); + auto projectedPayees = mnList.GetProjectedMNPayees(mnList.GetValidMNsCount()); std::map nextPayments; for (size_t i = 0; i < projectedPayees.size(); i++) { diff --git a/src/qt/masternodelist.h b/src/qt/masternodelist.h index aecfd707f..e4cff4942 100755 --- a/src/qt/masternodelist.h +++ b/src/qt/masternodelist.h @@ -12,7 +12,7 @@ #include #include -#define MASTERNODELIST_UPDATE_SECONDS 15 +#define MASTERNODELIST_UPDATE_SECONDS 3 #define MASTERNODELIST_FILTER_COOLDOWN_SECONDS 3 namespace Ui @@ -42,6 +42,7 @@ class MasternodeList : public QWidget private: QMenu* contextMenuDIP3; int64_t nTimeFilterUpdatedDIP3; + int64_t nTimeUpdatedDIP3; bool fFilterUpdatedDIP3; QTimer* timer; @@ -54,9 +55,11 @@ class MasternodeList : public QWidget QString strCurrentFilterDIP3; + bool mnListChanged; + CDeterministicMNCPtr GetSelectedDIP3MN(); - void updateDIP3List(bool fForce); + void updateDIP3List(); Q_SIGNALS: void doubleClicked(const QModelIndex&); @@ -70,7 +73,7 @@ private Q_SLOTS: void copyProTxHash_clicked(); void copyCollateralOutpoint_clicked(); + void handleMasternodeListChanged(); void updateDIP3ListScheduled(); - void updateDIP3ListForced(); }; #endif // MASTERNODELIST_H diff --git a/src/qt/optionsdialog.cpp b/src/qt/optionsdialog.cpp index f97a42dc8..ff5da5a1f 100755 --- a/src/qt/optionsdialog.cpp +++ b/src/qt/optionsdialog.cpp @@ -20,7 +20,7 @@ #ifdef ENABLE_WALLET #include "wallet/wallet.h" // for CWallet::GetRequiredFee() -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #endif // ENABLE_WALLET #include @@ -83,14 +83,14 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) : } /* Display elements init */ - + /* Number of displayed decimal digits selector */ QString digits; for(int index = 2; index <=8; index++){ digits.setNum(index); ui->digits->addItem(digits, digits); } - + /* Theme selector */ ui->theme->addItem(QString("Light"), QVariant("light")); ui->theme->addItem(QString("Light-HiRes"), QVariant("light-hires")); diff --git a/src/qt/optionsmodel.cpp b/src/qt/optionsmodel.cpp index 61af5960a..542513824 100755 --- a/src/qt/optionsmodel.cpp +++ b/src/qt/optionsmodel.cpp @@ -23,7 +23,7 @@ #include "wallet/wallet.h" #include "wallet/walletdb.h" -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #endif #include @@ -63,7 +63,7 @@ void OptionsModel::Init(bool resetSettings) settings.setValue("fHideTrayIcon", false); fHideTrayIcon = settings.value("fHideTrayIcon").toBool(); Q_EMIT hideTrayIconChanged(fHideTrayIcon); - + if (!settings.contains("fMinimizeToTray")) settings.setValue("fMinimizeToTray", false); fMinimizeToTray = settings.value("fMinimizeToTray").toBool() && !fHideTrayIcon; @@ -469,14 +469,14 @@ bool OptionsModel::setData(const QModelIndex & index, const QVariant & value, in settings.setValue("digits", value); setRestartRequired(true); } - break; + break; #endif // ENABLE_WALLET case Theme: if (settings.value("theme") != value) { settings.setValue("theme", value); setRestartRequired(true); } - break; + break; case Language: if (settings.value("language") != value) { settings.setValue("language", value); diff --git a/src/qt/overviewpage.cpp b/src/qt/overviewpage.cpp index 09200dce9..8f1ab5039 100755 --- a/src/qt/overviewpage.cpp +++ b/src/qt/overviewpage.cpp @@ -18,9 +18,9 @@ #include "utilitydialog.h" #include "walletmodel.h" -#include "instantx.h" -#include "masternode-sync.h" -#include "privatesend-client.h" +#include "instantsend.h" +#include "masternode/masternode-sync.h" +#include "privatesend/privatesend-client.h" #include #include diff --git a/src/qt/res/images/crownium/axe_logo_horizontal.png b/src/qt/res/images/crownium/axe_logo_horizontal.png index 1c33d8a8e..821324db6 100644 Binary files a/src/qt/res/images/crownium/axe_logo_horizontal.png and b/src/qt/res/images/crownium/axe_logo_horizontal.png differ diff --git a/src/qt/res/images/drkblue/axe_logo_horizontal.png b/src/qt/res/images/drkblue/axe_logo_horizontal.png index 1c33d8a8e..821324db6 100644 Binary files a/src/qt/res/images/drkblue/axe_logo_horizontal.png and b/src/qt/res/images/drkblue/axe_logo_horizontal.png differ diff --git a/src/qt/res/images/light-retro/axe_logo_horizontal.png b/src/qt/res/images/light-retro/axe_logo_horizontal.png index 1c33d8a8e..821324db6 100644 Binary files a/src/qt/res/images/light-retro/axe_logo_horizontal.png and b/src/qt/res/images/light-retro/axe_logo_horizontal.png differ diff --git a/src/qt/res/images/light/axe_logo_horizontal.png b/src/qt/res/images/light/axe_logo_horizontal.png index 1c33d8a8e..821324db6 100644 Binary files a/src/qt/res/images/light/axe_logo_horizontal.png and b/src/qt/res/images/light/axe_logo_horizontal.png differ diff --git a/src/qt/res/images/trad/axe_logo_horizontal.png b/src/qt/res/images/trad/axe_logo_horizontal.png index 1c33d8a8e..821324db6 100644 Binary files a/src/qt/res/images/trad/axe_logo_horizontal.png and b/src/qt/res/images/trad/axe_logo_horizontal.png differ diff --git a/src/qt/rpcconsole.cpp b/src/qt/rpcconsole.cpp index 91e7df8a1..38e2f9bd2 100755 --- a/src/qt/rpcconsole.cpp +++ b/src/qt/rpcconsole.cpp @@ -563,6 +563,7 @@ void RPCConsole::setClientModel(ClientModel *model) connect(model, SIGNAL(bytesChanged(quint64,quint64)), this, SLOT(updateTrafficStats(quint64, quint64))); connect(model, SIGNAL(mempoolSizeChanged(long,size_t)), this, SLOT(setMempoolSize(long,size_t))); + connect(model, SIGNAL(islockCountChanged(size_t)), this, SLOT(setInstantSendLockCount(size_t))); // set up peer table ui->peerWidget->setModel(model->getPeerTableModel()); @@ -906,6 +907,11 @@ void RPCConsole::setMempoolSize(long numberOfTxs, size_t dynUsage) ui->mempoolSize->setText(QString::number(dynUsage/1000000.0, 'f', 2) + " MB"); } +void RPCConsole::setInstantSendLockCount(size_t count) +{ + ui->instantSendLockCount->setText(QString::number(count)); +} + void RPCConsole::on_lineEdit_returnPressed() { QString cmd = ui->lineEdit->text(); diff --git a/src/qt/rpcconsole.h b/src/qt/rpcconsole.h index 8f195cde5..c1466cf44 100755 --- a/src/qt/rpcconsole.h +++ b/src/qt/rpcconsole.h @@ -111,6 +111,8 @@ public Q_SLOTS: void setNumBlocks(int count, const QDateTime& blockDate, double nVerificationProgress, bool headers); /** Set size (number of transactions and memory usage) of the mempool in the UI */ void setMempoolSize(long numberOfTxs, size_t dynUsage); + /** Set number of InstantSend locks */ + void setInstantSendLockCount(size_t count); /** Go forward or back in history */ void browseHistory(int offset); /** Scroll console view to end */ diff --git a/src/qt/sendcoinsdialog.cpp b/src/qt/sendcoinsdialog.cpp index f8d348a73..201a65732 100755 --- a/src/qt/sendcoinsdialog.cpp +++ b/src/qt/sendcoinsdialog.cpp @@ -23,7 +23,7 @@ #include "txmempool.h" #include "wallet/wallet.h" -#include "privatesend.h" +#include "privatesend/privatesend.h" #include #include diff --git a/src/qt/test/rpcnestedtests.cpp b/src/qt/test/rpcnestedtests.cpp index 6b18bf8dc..db88247ce 100755 --- a/src/qt/test/rpcnestedtests.cpp +++ b/src/qt/test/rpcnestedtests.cpp @@ -155,12 +155,18 @@ void RPCNestedTests::rpcNestedTests() QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using , #endif + UnloadBlockIndex(); delete pcoinsTip; + pcoinsTip = nullptr; llmq::DestroyLLMQSystem(); delete deterministicMNManager; + deterministicMNManager = nullptr; delete pcoinsdbview; + pcoinsdbview = nullptr; delete pblocktree; + pblocktree = nullptr; delete evoDb; + evoDb = nullptr; boost::filesystem::remove_all(boost::filesystem::path(path)); } diff --git a/src/qt/test/test_main.cpp b/src/qt/test/test_main.cpp index ee889fa3f..7cd9545db 100755 --- a/src/qt/test/test_main.cpp +++ b/src/qt/test/test_main.cpp @@ -8,7 +8,6 @@ #endif #include "chainparams.h" -#include "key.h" #include "rpcnestedtests.h" #include "util.h" #include "uritests.h" @@ -17,20 +16,34 @@ #ifdef ENABLE_WALLET #include "paymentservertests.h" +#include "wallettests.h" #endif -#include +#include #include #include #include -#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000 +#if defined(QT_STATICPLUGIN) #include +#if QT_VERSION < 0x050000 Q_IMPORT_PLUGIN(qcncodecs) Q_IMPORT_PLUGIN(qjpcodecs) Q_IMPORT_PLUGIN(qtwcodecs) Q_IMPORT_PLUGIN(qkrcodecs) +#else +#if defined(QT_QPA_PLATFORM_MINIMAL) +Q_IMPORT_PLUGIN(QMinimalIntegrationPlugin); +#endif +#if defined(QT_QPA_PLATFORM_XCB) +Q_IMPORT_PLUGIN(QXcbIntegrationPlugin); +#elif defined(QT_QPA_PLATFORM_WINDOWS) +Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin); +#elif defined(QT_QPA_PLATFORM_COCOA) +Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin); +#endif +#endif #endif extern void noui_connect(); @@ -38,7 +51,6 @@ extern void noui_connect(); // This is all you need to run all the tests int main(int argc, char *argv[]) { - ECC_Start(); SetupEnvironment(); SetupNetworking(); SelectParams(CBaseChainParams::MAIN); @@ -46,32 +58,49 @@ int main(int argc, char *argv[]) bool fInvalid = false; + // Prefer the "minimal" platform for the test instead of the normal default + // platform ("xcb", "windows", or "cocoa") so tests can't unintentially + // interfere with any background GUIs and don't require extra resources. + #if defined(WIN32) + _putenv_s("QT_QPA_PLATFORM", "minimal"); + #else + setenv("QT_QPA_PLATFORM", "minimal", 0); + #endif + // Don't remove this, it's needed to access - // QCoreApplication:: in the tests - QCoreApplication app(argc, argv); + // QApplication:: and QCoreApplication:: in the tests + QApplication app(argc, argv); app.setApplicationName("Axe-Qt-test"); SSL_library_init(); URITests test1; - if (QTest::qExec(&test1) != 0) + if (QTest::qExec(&test1) != 0) { fInvalid = true; + } #ifdef ENABLE_WALLET PaymentServerTests test2; - if (QTest::qExec(&test2) != 0) + if (QTest::qExec(&test2) != 0) { fInvalid = true; + } #endif RPCNestedTests test3; - if (QTest::qExec(&test3) != 0) + if (QTest::qExec(&test3) != 0) { fInvalid = true; - + } CompatTests test4; - if (QTest::qExec(&test4) != 0) + if (QTest::qExec(&test4) != 0) { + fInvalid = true; + } +#ifdef ENABLE_WALLET + WalletTests test5; + if (QTest::qExec(&test5) != 0) { fInvalid = true; + } +#endif - TrafficGraphDataTests test5; - if (QTest::qExec(&test5) != 0) + TrafficGraphDataTests test6; + if (QTest::qExec(&test6) != 0) fInvalid = true; - ECC_Stop(); return fInvalid; } diff --git a/src/qt/test/wallettests.cpp b/src/qt/test/wallettests.cpp new file mode 100644 index 000000000..49e529638 --- /dev/null +++ b/src/qt/test/wallettests.cpp @@ -0,0 +1,116 @@ +#include "wallettests.h" + +#include "qt/bitcoinamountfield.h" +#include "qt/optionsmodel.h" +#include "qt/platformstyle.h" +#include "qt/qvalidatedlineedit.h" +#include "qt/sendcoinsdialog.h" +#include "qt/sendcoinsentry.h" +#include "qt/transactiontablemodel.h" +#include "qt/walletmodel.h" +#include "test/test_axe.h" +#include "validation.h" +#include "wallet/wallet.h" + +#include +#include +#include +#include + +namespace +{ +//! Press "Yes" button in modal send confirmation dialog. +void ConfirmSend() +{ + QTimer::singleShot(0, Qt::PreciseTimer, []() { + for (QWidget* widget : QApplication::topLevelWidgets()) { + if (widget->inherits("SendConfirmationDialog")) { + SendConfirmationDialog* dialog = qobject_cast(widget); + QAbstractButton* button = dialog->button(QMessageBox::Yes); + button->setEnabled(true); + button->click(); + } + } + }); +} + +//! Send coins to address and return txid. +uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CBitcoinAddress& address, CAmount amount) +{ + QVBoxLayout* entries = sendCoinsDialog.findChild("entries"); + SendCoinsEntry* entry = qobject_cast(entries->itemAt(0)->widget()); + entry->findChild("payTo")->setText(QString::fromStdString(address.ToString())); + entry->findChild("payAmount")->setValue(amount); + uint256 txid; + boost::signals2::scoped_connection c = wallet.NotifyTransactionChanged.connect([&txid](CWallet*, const uint256& hash, ChangeType status) { + if (status == CT_NEW) txid = hash; + }); + ConfirmSend(); + QMetaObject::invokeMethod(&sendCoinsDialog, "on_sendButton_clicked"); + return txid; +} + +//! Find index of txid in transaction list. +QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid) +{ + QString hash = QString::fromStdString(txid.ToString()); + int rows = model.rowCount({}); + for (int row = 0; row < rows; ++row) { + QModelIndex index = model.index(row, 0, {}); + if (model.data(index, TransactionTableModel::TxHashRole) == hash) { + return index; + } + } + return {}; +} +} + +//! Simple qt wallet tests. +// +// Test widgets can be debugged interactively calling show() on them and +// manually running the event loop, e.g.: +// +// sendCoinsDialog.show(); +// QEventLoop().exec(); +// +// This also requires overriding the default minimal Qt platform: +// +// src/qt/test/test_bitcoin-qt -platform xcb # Linux +// src/qt/test/test_bitcoin-qt -platform windows # Windows +// src/qt/test/test_bitcoin-qt -platform cocoa # macOS +void WalletTests::walletTests() +{ + // Set up wallet and chain with 101 blocks (1 mature block for spending). + TestChain100Setup test; + test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey())); + bitdb.MakeMock(); + CWallet wallet("wallet_test.dat"); + bool firstRun; + wallet.LoadWallet(firstRun); + { + LOCK(wallet.cs_wallet); + wallet.SetAddressBook(test.coinbaseKey.GetPubKey().GetID(), "", "receive"); + wallet.AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey()); + } + wallet.ScanForWalletTransactions(chainActive.Genesis(), true); + wallet.SetBroadcastTransactions(true); + + // Create widgets for sending coins and listing transactions. + std::unique_ptr platformStyle(PlatformStyle::instantiate("other")); + SendCoinsDialog sendCoinsDialog(platformStyle.get()); + OptionsModel optionsModel; + WalletModel walletModel(platformStyle.get(), &wallet, &optionsModel); + sendCoinsDialog.setModel(&walletModel); + + // Send two transactions, and verify they are added to transaction list. + TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel(); + QCOMPARE(transactionTableModel->rowCount({}), 101); + uint256 txid1 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 5 * COIN); + uint256 txid2 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 10 * COIN); + QCOMPARE(transactionTableModel->rowCount({}), 103); + QVERIFY(FindTx(*transactionTableModel, txid1).isValid()); + QVERIFY(FindTx(*transactionTableModel, txid2).isValid()); + + bitdb.Flush(true); + bitdb.Reset(); +} diff --git a/src/qt/test/wallettests.h b/src/qt/test/wallettests.h new file mode 100644 index 000000000..342f7916c --- /dev/null +++ b/src/qt/test/wallettests.h @@ -0,0 +1,15 @@ +#ifndef BITCOIN_QT_TEST_WALLETTESTS_H +#define BITCOIN_QT_TEST_WALLETTESTS_H + +#include +#include + +class WalletTests : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void walletTests(); +}; + +#endif // BITCOIN_QT_TEST_WALLETTESTS_H diff --git a/src/qt/transactiondesc.cpp b/src/qt/transactiondesc.cpp index 379c731db..b00161299 100755 --- a/src/qt/transactiondesc.cpp +++ b/src/qt/transactiondesc.cpp @@ -19,7 +19,7 @@ #include "wallet/db.h" #include "wallet/wallet.h" -#include "instantx.h" +#include "instantsend.h" #include #include diff --git a/src/qt/transactionrecord.cpp b/src/qt/transactionrecord.cpp index 9ee7c24eb..cd439285b 100755 --- a/src/qt/transactionrecord.cpp +++ b/src/qt/transactionrecord.cpp @@ -11,7 +11,7 @@ #include "timedata.h" #include "wallet/wallet.h" -#include "privatesend.h" +#include "privatesend/privatesend.h" #include diff --git a/src/qt/walletmodel.cpp b/src/qt/walletmodel.cpp index f8386d817..fc1f22100 100755 --- a/src/qt/walletmodel.cpp +++ b/src/qt/walletmodel.cpp @@ -23,9 +23,9 @@ #include "wallet/wallet.h" #include "wallet/walletdb.h" // for BackupWallet -#include "instantx.h" +#include "instantsend.h" #include "spork.h" -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #include "llmq/quorums_instantsend.h" #include diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index d4bf909af..efa0721b0 100755 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -11,7 +11,7 @@ #include "coins.h" #include "core_io.h" #include "consensus/validation.h" -#include "instantx.h" +#include "instantsend.h" #include "validation.h" #include "policy/policy.h" #include "primitives/transaction.h" @@ -837,6 +837,86 @@ UniValue getblockheaders(const JSONRPCRequest& request) return arrHeaders; } +UniValue getmerkleblocks(const JSONRPCRequest& request) +{ + if (request.fHelp || request.params.size() < 1 || request.params.size() > 3) + throw std::runtime_error( + "getmerkleblocks \"filter\" \"hash\" ( count )\n" + "\nReturns an array of items with information about merkleblocks starting from which match .\n" + "\nArguments:\n" + "1. \"filter\" (string, required) The hex encoded bloom filter\n" + "2. \"hash\" (string, required) The block hash\n" + "3. count (numeric, optional, default/max=" + strprintf("%s", MAX_HEADERS_RESULTS) +")\n" + "\nResult (for verbose=false):\n" + "[\n" + " \"data\", (string) A string that is serialized, hex-encoded data for a merkleblock.\n" + " ...\n" + "]\n" + "\nExamples:\n" + + HelpExampleCli("getmerkleblocks", "\"2303028005802040100040000008008400048141010000f8400420800080025004000004130000000000000001\" \"00000000007e1432d2af52e8463278bf556b55cf5049262f25634557e2e91202\" 2000") + + HelpExampleRpc("getmerkleblocks", "\"2303028005802040100040000008008400048141010000f8400420800080025004000004130000000000000001\" \"00000000007e1432d2af52e8463278bf556b55cf5049262f25634557e2e91202\" 2000") + ); + + LOCK(cs_main); + + CBloomFilter filter; + std::string strFilter = request.params[0].get_str(); + CDataStream ssBloomFilter(ParseHex(strFilter), SER_NETWORK, PROTOCOL_VERSION); + ssBloomFilter >> filter; + if (!filter.IsWithinSizeConstraints()) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Filter is not within size constraints"); + } + filter.UpdateEmptyFull(); + + std::string strHash = request.params[1].get_str(); + uint256 hash(uint256S(strHash)); + + if (mapBlockIndex.count(hash) == 0) { + throw JSONRPCError(RPC_INVALID_ADDRESS_OR_KEY, "Block not found"); + } + + int nCount = MAX_HEADERS_RESULTS; + if (request.params.size() > 2) + nCount = request.params[2].get_int(); + + if (nCount <= 0 || nCount > (int)MAX_HEADERS_RESULTS) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "Count is out of range"); + } + + CBlock block; + CBlockIndex* pblockindex = mapBlockIndex[hash]; + + if (fHavePruned && !(pblockindex->nStatus & BLOCK_HAVE_DATA) && pblockindex->nTx > 0) { + throw JSONRPCError(RPC_MISC_ERROR, "Block not available (pruned data)"); + } + + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) { + // Block not found on disk. This could be because we have the block + // header in our index but don't have the block (for example if a + // non-whitelisted node sends us an unrequested long chain of valid + // blocks, we add the headers to our index, but don't accept the + // block). + throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk"); + } + + UniValue arrMerkleBlocks(UniValue::VARR); + + for (; pblockindex; pblockindex = chainActive.Next(pblockindex)) + { + if (!ReadBlockFromDisk(block, pblockindex, Params().GetConsensus())) { + // this shouldn't happen, we already checked pruning case earlier + throw JSONRPCError(RPC_MISC_ERROR, "Block not found on disk"); + } + CDataStream ssMerkleBlock(SER_NETWORK, PROTOCOL_VERSION); + ssMerkleBlock << CMerkleBlock(block, filter); + std::string strHex = HexStr(ssMerkleBlock); + arrMerkleBlocks.push_back(strHex); + if (--nCount <= 0) + break; + } + return arrMerkleBlocks; +} + UniValue getblock(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() < 1 || request.params.size() > 2) @@ -1503,6 +1583,7 @@ UniValue mempoolInfoToJSON() size_t maxmempool = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; ret.push_back(Pair("maxmempool", (int64_t) maxmempool)); ret.push_back(Pair("mempoolminfee", ValueFromAmount(mempool.GetMinFee(maxmempool).GetFeePerK()))); + ret.push_back(Pair("instantsendlocks", (int64_t)llmq::quorumInstantSendManager->GetInstantSendLockCount())); return ret; } @@ -1520,6 +1601,7 @@ UniValue getmempoolinfo(const JSONRPCRequest& request) " \"usage\": xxxxx, (numeric) Total memory usage for the mempool\n" " \"maxmempool\": xxxxx, (numeric) Maximum memory usage for the mempool\n" " \"mempoolminfee\": xxxxx (numeric) Minimum fee for tx to be accepted\n" + " \"instantsendlocks\": xxxxx, (numeric) Number of unconfirmed instant send locks\n" "}\n" "\nExamples:\n" + HelpExampleCli("getmempoolinfo", "") @@ -1760,6 +1842,7 @@ static const CRPCCommand commands[] = { "blockchain", "getblockhash", &getblockhash, true, {"height"} }, { "blockchain", "getblockheader", &getblockheader, true, {"blockhash","verbose"} }, { "blockchain", "getblockheaders", &getblockheaders, true, {"blockhash","count","verbose"} }, + { "blockchain", "getmerkleblocks", &getmerkleblocks, true, {"filter","blockhash","count"} }, { "blockchain", "getchaintips", &getchaintips, true, {"count","branchlen"} }, { "blockchain", "getdifficulty", &getdifficulty, true, {} }, { "blockchain", "getmempoolancestors", &getmempoolancestors, true, {"txid","verbose"} }, diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index a0572f867..cc04555e4 100755 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -103,6 +103,7 @@ static const CRPCConvertParam vRPCConvertParams[] = { "getblockheader", 1, "verbose" }, { "getblockheaders", 1, "count" }, { "getblockheaders", 2, "verbose" }, + { "getmerkleblocks", 2, "count" }, { "gettransaction", 1, "include_watchonly" }, { "getrawtransaction", 1, "verbose" }, { "createrawtransaction", 0, "inputs" }, diff --git a/src/rpc/governance.cpp b/src/rpc/governance.cpp index b12a7913c..6b67bec40 100755 --- a/src/rpc/governance.cpp +++ b/src/rpc/governance.cpp @@ -2,15 +2,15 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "consensus/validation.h" -#include "governance.h" -#include "governance-vote.h" -#include "governance-classes.h" -#include "governance-validators.h" +#include "governance/governance.h" +#include "governance/governance-vote.h" +#include "governance/governance-classes.h" +#include "governance/governance-validators.h" #include "init.h" #include "validation.h" -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "messagesigner.h" #include "rpc/server.h" #include "util.h" diff --git a/src/rpc/masternode.cpp b/src/rpc/masternode.cpp index 200df1868..7778ce452 100755 --- a/src/rpc/masternode.cpp +++ b/src/rpc/masternode.cpp @@ -2,18 +2,18 @@ // Distributed under the MIT/X11 software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#include "activemasternode.h" +#include "masternode/activemasternode.h" #include "base58.h" #include "clientversion.h" #include "init.h" #include "netbase.h" #include "validation.h" -#include "masternode-payments.h" -#include "masternode-sync.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" #ifdef ENABLE_WALLET -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #endif // ENABLE_WALLET -#include "privatesend-server.h" +#include "privatesend/privatesend-server.h" #include "rpc/server.h" #include "util.h" #include "utilmoneystr.h" @@ -574,7 +574,7 @@ UniValue masternodelist(const JSONRPCRequest& request) CBitcoinAddress(dmn->pdmnState->keyIDOwner).ToString() << " " << CBitcoinAddress(dmn->pdmnState->keyIDVoting).ToString() << " " << collateralAddressStr << " " << - dmn->pdmnState->pubKeyOperator.ToString(); + dmn->pdmnState->pubKeyOperator.Get().ToString(); std::string strInfo = streamInfo.str(); if (strFilter !="" && strInfo.find(strFilter) == std::string::npos && strOutpoint.find(strFilter) == std::string::npos) return; @@ -588,7 +588,7 @@ UniValue masternodelist(const JSONRPCRequest& request) objMN.push_back(Pair("owneraddress", CBitcoinAddress(dmn->pdmnState->keyIDOwner).ToString())); objMN.push_back(Pair("votingaddress", CBitcoinAddress(dmn->pdmnState->keyIDVoting).ToString())); objMN.push_back(Pair("collateraladdress", collateralAddressStr)); - objMN.push_back(Pair("pubkeyoperator", dmn->pdmnState->pubKeyOperator.ToString())); + objMN.push_back(Pair("pubkeyoperator", dmn->pdmnState->pubKeyOperator.Get().ToString())); obj.push_back(Pair(strOutpoint, objMN)); } else if (strMode == "lastpaidblock") { if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) return; @@ -605,7 +605,7 @@ UniValue masternodelist(const JSONRPCRequest& request) obj.push_back(Pair(strOutpoint, CBitcoinAddress(dmn->pdmnState->keyIDOwner).ToString())); } else if (strMode == "pubkeyoperator") { if (strFilter !="" && strOutpoint.find(strFilter) == std::string::npos) return; - obj.push_back(Pair(strOutpoint, dmn->pdmnState->pubKeyOperator.ToString())); + obj.push_back(Pair(strOutpoint, dmn->pdmnState->pubKeyOperator.Get().ToString())); } else if (strMode == "status") { std::string strStatus = dmnToStatus(dmn); if (strFilter !="" && strStatus.find(strFilter) == std::string::npos && diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 70e722e9f..f491a6868 100755 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -24,9 +24,9 @@ #include "utilstrencodings.h" #include "validationinterface.h" -#include "governance-classes.h" -#include "masternode-payments.h" -#include "masternode-sync.h" +#include "governance/governance-classes.h" +#include "masternode/masternode-payments.h" +#include "masternode/masternode-sync.h" #include "evo/deterministicmns.h" #include "evo/specialtx.h" @@ -488,13 +488,11 @@ UniValue getblocktemplate(const JSONRPCRequest& request) if(!g_connman) throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled"); - if (Params().MiningRequiresPeers()) { - if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) - throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Axe Core is not connected!"); + if (g_connman->GetNodeCount(CConnman::CONNECTIONS_ALL) == 0) + throw JSONRPCError(RPC_CLIENT_NOT_CONNECTED, "Axe Core is not connected!"); - if (IsInitialBlockDownload()) - throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Axe Core is downloading blocks..."); - } + if (IsInitialBlockDownload()) + throw JSONRPCError(RPC_CLIENT_IN_INITIAL_DOWNLOAD, "Axe Core is downloading blocks..."); // Get expected MN/superblock payees. The call to GetBlockTxOuts might fail on regtest/devnet or when // testnet is reset. This is fine and we ignore failure (blocks will be accepted) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 8f9897396..1812dce51 100755 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -21,10 +21,13 @@ #include "wallet/walletdb.h" #endif -#include "masternode-sync.h" +#include "masternode/masternode-sync.h" #include "spork.h" #include +#ifdef HAVE_MALLOC_INFO +#include +#endif #include #include @@ -1117,16 +1120,39 @@ static UniValue RPCLockedMemoryInfo() return obj; } +#ifdef HAVE_MALLOC_INFO +static std::string RPCMallocInfo() +{ + char *ptr = nullptr; + size_t size = 0; + FILE *f = open_memstream(&ptr, &size); + if (f) { + malloc_info(0, f); + fclose(f); + if (ptr) { + std::string rv(ptr, size); + free(ptr); + return rv; + } + } + return ""; +} +#endif + UniValue getmemoryinfo(const JSONRPCRequest& request) { /* Please, avoid using the word "pool" here in the RPC interface or help, * as users will undoubtedly confuse it with the other "memory pool" */ - if (request.fHelp || request.params.size() != 0) + if (request.fHelp || request.params.size() > 1) throw std::runtime_error( - "getmemoryinfo\n" + "getmemoryinfo (\"mode\")\n" "Returns an object containing information about memory usage.\n" - "\nResult:\n" + "Arguments:\n" + "1. \"mode\" determines what kind of information is returned. This argument is optional, the default mode is \"stats\".\n" + " - \"stats\" returns general statistics about memory usage in the daemon.\n" + " - \"mallocinfo\" returns an XML string describing low-level heap state (only available if compiled with glibc 2.10+).\n" + "\nResult (mode \"stats\"):\n" "{\n" " \"locked\": { (json object) Information about locked memory manager\n" " \"used\": xxxxx, (numeric) Number of bytes used\n" @@ -1137,13 +1163,27 @@ UniValue getmemoryinfo(const JSONRPCRequest& request) " \"chunks_free\": xxxxx, (numeric) Number unused chunks\n" " }\n" "}\n" + "\nResult (mode \"mallocinfo\"):\n" + "\"...\"\n" "\nExamples:\n" + HelpExampleCli("getmemoryinfo", "") + HelpExampleRpc("getmemoryinfo", "") ); - UniValue obj(UniValue::VOBJ); - obj.push_back(Pair("locked", RPCLockedMemoryInfo())); - return obj; + + std::string mode = (request.params.size() < 1 || request.params[0].isNull()) ? "stats" : request.params[0].get_str(); + if (mode == "stats") { + UniValue obj(UniValue::VOBJ); + obj.push_back(Pair("locked", RPCLockedMemoryInfo())); + return obj; + } else if (mode == "mallocinfo") { +#ifdef HAVE_MALLOC_INFO + return RPCMallocInfo(); +#else + throw JSONRPCError(RPC_INVALID_PARAMETER, "mallocinfo is only available when compiled with glibc 2.10+"); +#endif + } else { + throw JSONRPCError(RPC_INVALID_PARAMETER, "unknown mode " + mode); + } } UniValue echo(const JSONRPCRequest& request) @@ -1164,7 +1204,7 @@ static const CRPCCommand commands[] = // --------------------- ------------------------ ----------------------- ---------- { "control", "debug", &debug, true, {} }, { "control", "getinfo", &getinfo, true, {} }, /* uses wallet if enabled */ - { "control", "getmemoryinfo", &getmemoryinfo, true, {} }, + { "control", "getmemoryinfo", &getmemoryinfo, true, {"mode"} }, { "util", "validateaddress", &validateaddress, true, {"address"} }, /* uses wallet if enabled */ { "util", "createmultisig", &createmultisig, true, {"nrequired","keys"} }, { "util", "verifymessage", &verifymessage, true, {"address","signature","message"} }, diff --git a/src/rpc/rawtransaction.cpp b/src/rpc/rawtransaction.cpp index fa1a76cab..20f70b48f 100755 --- a/src/rpc/rawtransaction.cpp +++ b/src/rpc/rawtransaction.cpp @@ -24,7 +24,7 @@ #include "txmempool.h" #include "uint256.h" #include "utilstrencodings.h" -#include "instantx.h" +#include "instantsend.h" #ifdef ENABLE_WALLET #include "wallet/rpcwallet.h" #include "wallet/wallet.h" diff --git a/src/rpc/rpcevo.cpp b/src/rpc/rpcevo.cpp index 2d5d81cde..bb9c21fbc 100755 --- a/src/rpc/rpcevo.cpp +++ b/src/rpc/rpcevo.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2018-2019 The Axe Core developers +// Copyright (c) 2018-2019 The Dash Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -623,7 +623,7 @@ UniValue protx_update_service(const JSONRPCRequest& request) throw std::runtime_error(strprintf("masternode with proTxHash %s not found", ptx.proTxHash.ToString())); } - if (keyOperator.GetPublicKey() != dmn->pdmnState->pubKeyOperator) { + if (keyOperator.GetPublicKey() != dmn->pdmnState->pubKeyOperator.Get()) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("the operator key does not belong to the registered public key")); } @@ -713,7 +713,7 @@ UniValue protx_update_registrar(const JSONRPCRequest& request) if (!dmn) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("masternode %s not found", ptx.proTxHash.ToString())); } - ptx.pubKeyOperator = dmn->pdmnState->pubKeyOperator; + ptx.pubKeyOperator = dmn->pdmnState->pubKeyOperator.Get(); ptx.keyIDVoting = dmn->pdmnState->keyIDVoting; ptx.scriptPayout = dmn->pdmnState->scriptPayout; @@ -808,7 +808,7 @@ UniValue protx_revoke(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("masternode %s not found", ptx.proTxHash.ToString())); } - if (keyOperator.GetPublicKey() != dmn->pdmnState->pubKeyOperator) { + if (keyOperator.GetPublicKey() != dmn->pdmnState->pubKeyOperator.Get()) { throw JSONRPCError(RPC_INVALID_PARAMETER, strprintf("the operator key does not belong to the registered public key")); } @@ -972,7 +972,7 @@ UniValue protx_list(const JSONRPCRequest& request) setOutpts.emplace(outpt); } - CDeterministicMNList mnList = deterministicMNManager->GetListForBlock(chainActive[height]->GetBlockHash()); + CDeterministicMNList mnList = deterministicMNManager->GetListForBlock(chainActive[height]); mnList.ForEachMN(false, [&](const CDeterministicMNCPtr& dmn) { if (setOutpts.count(dmn->collateralOutpoint) || CheckWalletOwnsKey(pwallet, dmn->pdmnState->keyIDOwner) || @@ -997,7 +997,7 @@ UniValue protx_list(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid height specified"); } - CDeterministicMNList mnList = deterministicMNManager->GetListForBlock(chainActive[height]->GetBlockHash()); + CDeterministicMNList mnList = deterministicMNManager->GetListForBlock(chainActive[height]); bool onlyValid = type == "valid"; mnList.ForEachMN(onlyValid, [&](const CDeterministicMNCPtr& dmn) { ret.push_back(BuildDMNListEntry(pwallet, dmn, detailed)); diff --git a/src/rpc/rpcquorums.cpp b/src/rpc/rpcquorums.cpp index 8fb223215..78ae2bb83 100755 --- a/src/rpc/rpcquorums.cpp +++ b/src/rpc/rpcquorums.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2017-2019 The Axe Core developers +// Copyright (c) 2017-2019 The Dash Core developers // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. @@ -76,6 +76,41 @@ void quorum_info_help() ); } +UniValue BuildQuorumInfo(const llmq::CQuorumCPtr& quorum, bool includeMembers, bool includeSkShare) +{ + UniValue ret(UniValue::VOBJ); + + ret.push_back(Pair("height", quorum->pindexQuorum->nHeight)); + ret.push_back(Pair("type", quorum->params.name)); + ret.push_back(Pair("quorumHash", quorum->qc.quorumHash.ToString())); + ret.push_back(Pair("minedBlock", quorum->minedBlockHash.ToString())); + + if (includeMembers) { + UniValue membersArr(UniValue::VARR); + for (size_t i = 0; i < quorum->members.size(); i++) { + auto& dmn = quorum->members[i]; + UniValue mo(UniValue::VOBJ); + mo.push_back(Pair("proTxHash", dmn->proTxHash.ToString())); + mo.push_back(Pair("valid", quorum->qc.validMembers[i])); + if (quorum->qc.validMembers[i]) { + CBLSPublicKey pubKey = quorum->GetPubKeyShare(i); + if (pubKey.IsValid()) { + mo.push_back(Pair("pubKeyShare", pubKey.ToString())); + } + } + membersArr.push_back(mo); + } + + ret.push_back(Pair("members", membersArr)); + } + ret.push_back(Pair("quorumPublicKey", quorum->qc.quorumPublicKey.ToString())); + CBLSSecretKey skShare = quorum->GetSkShare(); + if (includeSkShare && skShare.IsValid()) { + ret.push_back(Pair("secretKeyShare", skShare.ToString())); + } + return ret; +} + UniValue quorum_info(const JSONRPCRequest& request) { if (request.fHelp || (request.params.size() != 3 && request.params.size() != 4)) @@ -101,35 +136,7 @@ UniValue quorum_info(const JSONRPCRequest& request) throw JSONRPCError(RPC_INVALID_PARAMETER, "quorum not found"); } - UniValue ret(UniValue::VOBJ); - - ret.push_back(Pair("height", quorum->height)); - ret.push_back(Pair("quorumHash", quorum->qc.quorumHash.ToString())); - ret.push_back(Pair("minedBlock", quorum->minedBlockHash.ToString())); - - UniValue membersArr(UniValue::VARR); - for (size_t i = 0; i < quorum->members.size(); i++) { - auto& dmn = quorum->members[i]; - UniValue mo(UniValue::VOBJ); - mo.push_back(Pair("proTxHash", dmn->proTxHash.ToString())); - mo.push_back(Pair("valid", quorum->qc.validMembers[i])); - if (quorum->qc.validMembers[i]) { - CBLSPublicKey pubKey = quorum->GetPubKeyShare(i); - if (pubKey.IsValid()) { - mo.push_back(Pair("pubKeyShare", pubKey.ToString())); - } - } - membersArr.push_back(mo); - } - - ret.push_back(Pair("members", membersArr)); - ret.push_back(Pair("quorumPublicKey", quorum->qc.quorumPublicKey.ToString())); - CBLSSecretKey skShare = quorum->GetSkShare(); - if (includeSkShare && skShare.IsValid()) { - ret.push_back(Pair("secretKeyShare", skShare.ToString())); - } - - return ret; + return BuildQuorumInfo(quorum, true, includeSkShare); } void quorum_dkgstatus_help() @@ -182,6 +189,67 @@ UniValue quorum_dkgstatus(const JSONRPCRequest& request) return ret; } +void quorum_memberof_help() +{ + throw std::runtime_error( + "quorum memberof \"proTxHash\" (quorumCount)\n" + "Checks which quorums the given masternode is a member of.\n" + "\nArguments:\n" + "1. \"proTxHash\" (string, required) ProTxHash of the masternode.\n" + "2. scanQuorumsCount (number, optional) Number of quorums to scan for. If not specified,\n" + " the active quorum count for each specific quorum type is used." + ); +} + +UniValue quorum_memberof(const JSONRPCRequest& request) +{ + if (request.fHelp || (request.params.size() < 2 || request.params.size() > 3)) { + quorum_memberof_help(); + } + + uint256 protxHash = ParseHashV(request.params[1], "proTxHash"); + int scanQuorumsCount = -1; + if (request.params.size() >= 3) { + scanQuorumsCount = ParseInt32V(request.params[2], "scanQuorumsCount"); + if (scanQuorumsCount <= 0) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "invalid scanQuorumsCount parameter"); + } + } + + const CBlockIndex* pindexTip; + { + LOCK(cs_main); + pindexTip = chainActive.Tip(); + } + + auto mnList = deterministicMNManager->GetListForBlock(pindexTip); + auto dmn = mnList.GetMN(protxHash); + if (!dmn) { + throw JSONRPCError(RPC_INVALID_PARAMETER, "masternode not found"); + } + + UniValue result(UniValue::VARR); + + for (const auto& p : Params().GetConsensus().llmqs) { + auto& params = p.second; + size_t count = params.signingActiveQuorumCount; + if (scanQuorumsCount != -1) { + count = (size_t)scanQuorumsCount; + } + auto quorums = llmq::quorumManager->ScanQuorums(params.type, count); + for (auto& quorum : quorums) { + if (quorum->IsMember(dmn->proTxHash)) { + auto json = BuildQuorumInfo(quorum, false, false); + json.push_back(Pair("isValidMember", quorum->IsValidMember(dmn->proTxHash))); + json.push_back(Pair("memberIndex", quorum->GetMemberIndex(dmn->proTxHash))); + result.push_back(json); + } + } + } + + return result; +} + void quorum_sign_help() { throw std::runtime_error( @@ -318,6 +386,7 @@ UniValue quorum_dkgsimerror(const JSONRPCRequest& request) " info - Return information about a quorum\n" " dkgsimerror - Simulates DKG errors and malicious behavior.\n" " dkgstatus - Return the status of the current DKG process\n" + " memberof - Checks which quorums the given masternode is a member of\n" " sign - Threshold-sign a message\n" " hasrecsig - Test if a valid recovered signature is present\n" " getrecsig - Get a recovered signature\n" @@ -342,6 +411,8 @@ UniValue quorum(const JSONRPCRequest& request) return quorum_info(request); } else if (command == "dkgstatus") { return quorum_dkgstatus(request); + } else if (command == "memberof") { + return quorum_memberof(request); } else if (command == "sign" || command == "hasrecsig" || command == "getrecsig" || command == "isconflicting") { return quorum_sigs_cmd(request); } else if (command == "dkgsimerror") { diff --git a/src/rpc/server.h b/src/rpc/server.h index cbc2641a1..f2b502564 100755 --- a/src/rpc/server.h +++ b/src/rpc/server.h @@ -26,7 +26,6 @@ namespace RPCServer void OnStarted(boost::function slot); void OnStopped(boost::function slot); void OnPreCommand(boost::function slot); - void OnPostCommand(boost::function slot); } class CBlockIndex; diff --git a/src/script/script.h b/src/script/script.h index 74cbb2bf1..d0a784504 100755 --- a/src/script/script.h +++ b/src/script/script.h @@ -645,6 +645,15 @@ class CScript : public CScriptBase // The default std::vector::clear() does not release memory. CScriptBase().swap(*this); } + + template + void Serialize(Stream& s) const { + s << *(CScriptBase*)this; + } + template + void Unserialize(Stream& s) { + s >> *(CScriptBase*)this; + } }; class CReserveScript diff --git a/src/spentindex.h b/src/spentindex.h index a3d84e86d..c79a007a0 100755 --- a/src/spentindex.h +++ b/src/spentindex.h @@ -210,7 +210,7 @@ struct CAddressUnspentValue { template inline void SerializationOp(Stream& s, Operation ser_action) { READWRITE(satoshis); - READWRITE(*(CScriptBase*)(&script)); + READWRITE(script); READWRITE(blockHeight); } diff --git a/src/spork.cpp b/src/spork.cpp index c2e91f8a6..db37d0e79 100755 --- a/src/spork.cpp +++ b/src/spork.cpp @@ -26,9 +26,9 @@ std::map mapSporkDefaults = { {SPORK_12_RECONSIDER_BLOCKS, 0}, // 0 BLOCKS {SPORK_15_DETERMINISTIC_MNS_ENABLED, 0}, // ON {SPORK_16_INSTANTSEND_AUTOLOCKS, 0}, // ON - {SPORK_17_QUORUM_DKG_ENABLED, 289023}, // Hardcoded to mainnet - {SPORK_19_CHAINLOCKS_ENABLED, 4070908800ULL}, // OFF - {SPORK_20_INSTANTSEND_LLMQ_BASED, 4070908800ULL}, // OFF + {SPORK_17_QUORUM_DKG_ENABLED, 0}, // ON + {SPORK_19_CHAINLOCKS_ENABLED, 368964}, // Hardcoded + {SPORK_20_INSTANTSEND_LLMQ_BASED, 368965}, // Hardcoded }; bool CSporkManager::SporkValueIsActive(int nSporkID, int64_t &nActiveValueRet) const diff --git a/src/streams.h b/src/streams.h index 088a87c72..57fa9a879 100755 --- a/src/streams.h +++ b/src/streams.h @@ -365,8 +365,8 @@ class CDataStream return (*this); } - void GetAndClear(CSerializeData &data) { - data.insert(data.end(), begin(), end()); + void GetAndClear(CSerializeData &d) { + d.insert(d.end(), begin(), end()); clear(); } diff --git a/src/sync.cpp b/src/sync.cpp index 3995d12a8..924223630 100755 --- a/src/sync.cpp +++ b/src/sync.cpp @@ -45,8 +45,6 @@ struct CLockLocation { return mutexName + " " + sourceFile + ":" + itostr(sourceLine) + (fTry ? " (TRY)" : ""); } - std::string MutexName() const { return mutexName; } - bool fTry; private: std::string mutexName; diff --git a/src/sync.h b/src/sync.h index ce14d6410..ea34f1c4e 100755 --- a/src/sync.h +++ b/src/sync.h @@ -100,7 +100,6 @@ class CCriticalSection : public AnnotatedMixin } }; -typedef CCriticalSection CDynamicCriticalSection; /** Wrapped boost mutex: supports waiting but not recursive locking */ typedef AnnotatedMixin CWaitableCriticalSection; diff --git a/src/test/bitcoin-util-test.py b/src/test/bitcoin-util-test.py deleted file mode 100755 index e2087187a..000000000 --- a/src/test/bitcoin-util-test.py +++ /dev/null @@ -1,45 +0,0 @@ -#!/usr/bin/env python -# Copyright 2014 BitPay Inc. -# Copyright 2016 The Bitcoin Core developers -# Distributed under the MIT software license, see the accompanying -# file COPYING or http://www.opensource.org/licenses/mit-license.php. -from __future__ import division,print_function,unicode_literals -import os -import bctest -import buildenv -import argparse -import logging - -help_text="""Test framework for bitcoin utils. - -Runs automatically during `make check`. - -Can also be run manually from the src directory by specifying the source directory: - -test/bitcoin-util-test.py --srcdir='srcdir' [--verbose] -""" - -if __name__ == '__main__': - # Try to get the source directory from the environment variables. This will - # be set for `make check` automated runs. If environment variable is not set, - # then get the source directory from command line args. - try: - srcdir = os.environ["srcdir"] - verbose = False - except: - parser = argparse.ArgumentParser(description=help_text) - parser.add_argument('-s', '--srcdir') - parser.add_argument('-v', '--verbose', action='store_true') - args = parser.parse_args() - srcdir = args.srcdir - verbose = args.verbose - - if verbose: - level = logging.DEBUG - else: - level = logging.ERROR - formatter = '%(asctime)s - %(levelname)s - %(message)s' - # Add the format/level to the logger - logging.basicConfig(format = formatter, level=level) - - bctest.bctester(srcdir + "/test/data", "bitcoin-util-test.json", buildenv) diff --git a/src/test/buildenv.py.in b/src/test/buildenv.py.in deleted file mode 100755 index 153f34a3d..000000000 --- a/src/test/buildenv.py.in +++ /dev/null @@ -1,2 +0,0 @@ -#!/usr/bin/env python -exeext="@EXEEXT@" diff --git a/src/test/checkqueue_tests.cpp b/src/test/checkqueue_tests.cpp index a0fa63154..0083f34a9 100755 --- a/src/test/checkqueue_tests.cpp +++ b/src/test/checkqueue_tests.cpp @@ -46,7 +46,7 @@ struct FakeCheckCheckCompletion { struct FailingCheck { bool fails; - FailingCheck(bool fails) : fails(fails){}; + FailingCheck(bool _fails) : fails(_fails){}; FailingCheck() : fails(true){}; bool operator()() { @@ -411,15 +411,15 @@ BOOST_AUTO_TEST_CASE(test_CheckQueueControl_Locks) std::unique_lock l(m); tg.create_thread([&]{ CCheckQueueControl control(queue.get()); - std::unique_lock l(m); + std::unique_lock ll(m); has_lock = true; cv.notify_one(); - cv.wait(l, [&]{return has_tried;}); + cv.wait(ll, [&]{return has_tried;}); done = true; cv.notify_one(); // Wait until the done is acknowledged // - cv.wait(l, [&]{return done_ack;}); + cv.wait(ll, [&]{return done_ack;}); }); // Wait for thread to get the lock cv.wait(l, [&](){return has_lock;}); diff --git a/src/test/data/tt-delin1-out.hex b/src/test/data/tt-delin1-out.hex deleted file mode 100755 index e3edc20d1..000000000 --- a/src/test/data/tt-delin1-out.hex +++ /dev/null @@ -1 +0,0 @@ -010000001a86506a919de53e6e0867dff293f7b377017baf660d104bfda469607b49cc5801000000006a47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032cfeffffff89e8ca0da97dd6ef3773139d22213dd68d1cc8d7857c9d10ae43de6c5a1d7e13010000006a473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff36b940dc6739babeb54a73fb7d9f42b49762b30c34f6dceee81023baddeb8317010000006a473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff87e0cc318f6456e77de36f68cd980a22642a777beaeb00a6749c3a53b310f92a010000006a47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbaf152ade0bb36134b3c2b3d04bf49a102feeb35748b8fac0db0b0f6e9425932010000006a4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff777f9ca152149f6cc0e5aad31d9f4e4317cff52c9dd4777e5644be63d4b43658010000006b483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defefffffff5d0e85769174aa90d763cc550bb29330b79c523f5276752d459610c0fc67459010000006a473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffa5bb7f7970b63a3dbcff70690d1c77c857582260ff29022f91765d35eca6d35d010000006b483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff1bf3b842f83bea4fdd9fd09900186e5eebc369e7122cb31206b1dbb040f0eb60010000006a4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff45441d81e6fbe991318546de407b8788fae3a3b8ab3a6cc1a9dce35a57426c62010000006a47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbd69405c40f26d2be0b2c9a15568ad9a1c2e830b15939d7e6916e16a1ce66363010000006a47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6a734b93c3869b811805483bb439228846c9ac03c50ff5eb0290db04e33f7c67010000006b48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffd90db6aa6e9d0ebbb641df87dc935d619c43887b7e99443b6691f8e34d05e178010000006b483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffdae8cc62e11406d7dd30afed2a8396465e3feebb020d9e84044bf214cd26e88d010000006b483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffcc6193600ded8300ab8dde1b2b93b290458f465801df18de4dc2c4422e87b69f010000006b483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3064def7e62659432943a77e73a57ed579c82677eb0498f6130e5af1836b12a7010000006b483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff8837066dd8e570430210ae5151047cf17728039837f795b272fafc74caafd1a7010000006a47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff771f53363bd6b099c3e5f4d609ef80cb95472e5a4820be9182451cd6002651ab010000006b483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff905b03d4030edd8ecc5c4dc85c654df0acc3a15f4dbd496f2199eb528819a1ad010000006b483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffb5a748a8822bdd2e3c9b553e058a027c9d118f956bdacabed700c1ea5ce481ba010000006a47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff633890f647d4af11a6c48f84fdf7cb39e9a1434453c41fc7adbf5e1805118ece010000006a473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6c1d70c078396e54d12ffe889547199a8218e22adb8dfc8d42cda805655cf8cf010000006b483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3b970e8473a5556fb749f60bfe84073b0904ed4b4b8a3c137807eed19bcfabe3010000006b483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffc93cf5d6f4bad4fd5a263137cdb05dafa3b8bbcc16d055cfbbc08f2c775e9bef010000006b483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffaef36591ef575a6ab179f662dc12fc97795c1dd6ed7e06785b0fbbc2588887f1000000006b483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368fefffffff98d8a96f402d2c05a6d995a3a2874371db8eed29abef0942c44494fa1eaf2fc010000006a473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff02cebf1900000000001976a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88aca8583202070000001976a9147b771748d7c97469b4a24a2b47cffbe7de604a1488accb8a0100 \ No newline at end of file diff --git a/src/test/data/tt-delin1-out.json b/src/test/data/tt-delin1-out.json deleted file mode 100755 index d33c0c0c9..000000000 --- a/src/test/data/tt-delin1-out.json +++ /dev/null @@ -1,270 +0,0 @@ - { - "txid": "ffdc6bf8bd55f30ad7f8ab460da456ac93461bc23c55166b06cc045cc5a4b823", - "version": 1, - "locktime": 101067, - "vin": [ - { - "txid": "0158cc497b6069a4fd4b100d66af7b0177b3f793f2df67086e3ee59d916a5086", - "vout": 0, - "scriptSig": { - "asm": "304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f1[ALL] 020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032c", - "hex": "47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032c" - }, - "sequence": 4294967294 - }, - { - "txid": "137e1d5a6cde43ae109d7c85d7c81c8dd63d21229d137337efd67da90dcae889", - "vout": 1, - "scriptSig": { - "asm": "3044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "1783ebddba2310e8eedcf6340cb36297b4429f7dfb734ab5beba3967dc40b936", - "vout": 1, - "scriptSig": { - "asm": "3044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a3[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "2af910b3533a9c74a600ebea7b772a64220a98cd686fe37de756648f31cce087", - "vout": 1, - "scriptSig": { - "asm": "304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e201498280555[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "325942e9f6b0b00dac8f8b7435ebfe02a149bf043d2b3c4b1336bbe0ad52f1ba", - "vout": 1, - "scriptSig": { - "asm": "30440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "5836b4d463be44567e77d49d2cf5cf17434e9f1dd3aae5c06c9f1452a19c7f77", - "vout": 1, - "scriptSig": { - "asm": "3045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "5974c60f0c6159d4526727f523c5790b3329bb50c53c760da94a176957e8d0f5", - "vout": 1, - "scriptSig": { - "asm": "3044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c03[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "5dd3a6ec355d76912f0229ff60225857c8771c0d6970ffbc3d3ab670797fbba5", - "vout": 1, - "scriptSig": { - "asm": "3045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc3[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "60ebf040b0dbb10612b32c12e769c3eb5e6e180099d09fdd4fea3bf842b8f31b", - "vout": 1, - "scriptSig": { - "asm": "30440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "626c42575ae3dca9c16c3aabb8a3e3fa88877b40de46853191e9fbe6811d4445", - "vout": 1, - "scriptSig": { - "asm": "304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b86[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "6363e61c6ae116697e9d93150b832e1c9aad6855a1c9b2e02b6df2405c4069bd", - "vout": 1, - "scriptSig": { - "asm": "304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de2[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "677c3fe304db9002ebf50fc503acc946882239b43b480518819b86c3934b736a", - "vout": 1, - "scriptSig": { - "asm": "304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb4[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "78e1054de3f891663b44997e7b88439c615d93dc87df41b6bb0e9d6eaab60dd9", - "vout": 1, - "scriptSig": { - "asm": "3045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab44[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "8de826cd14f24b04849e0d02bbee3f5e4696832aedaf30ddd70614e162cce8da", - "vout": 1, - "scriptSig": { - "asm": "3045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e333[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "9fb6872e42c4c24dde18df0158468f4590b2932b1bde8dab0083ed0d609361cc", - "vout": 1, - "scriptSig": { - "asm": "3045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d563[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "a7126b83f15a0e13f69804eb7726c879d57ea5737ea74329435926e6f7de6430", - "vout": 1, - "scriptSig": { - "asm": "3045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c080[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "a7d1afca74fcfa72b295f73798032877f17c045151ae10024370e5d86d063788", - "vout": 1, - "scriptSig": { - "asm": "304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ab512600d61c458291be20485a2e4795cb80ef09d6f4e5c399b0d63b36531f77", - "vout": 1, - "scriptSig": { - "asm": "3045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f38[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ada1198852eb99216f49bd4d5fa1c3acf04d655cc84d5ccc8edd0e03d4035b90", - "vout": 1, - "scriptSig": { - "asm": "3045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ba81e45ceac100d7becada6b958f119d7c028a053e559b3c2edd2b82a848a7b5", - "vout": 1, - "scriptSig": { - "asm": "304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ce8e1105185ebfadc71fc4534443a1e939cbf7fd848fc4a611afd447f6903863", - "vout": 1, - "scriptSig": { - "asm": "3044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f1326[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "cff85c6505a8cd428dfc8ddb2ae218829a19479588fe2fd1546e3978c0701d6c", - "vout": 1, - "scriptSig": { - "asm": "3045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "e3abcf9bd1ee0778133c8a4b4bed04093b0784fe0bf649b76f55a573840e973b", - "vout": 1, - "scriptSig": { - "asm": "3045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ef9b5e772c8fc0bbcf55d016ccbbb8a3af5db0cd3731265afdd4baf4d6f53cc9", - "vout": 1, - "scriptSig": { - "asm": "3045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e59124[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "f1878858c2bb0f5b78067eedd61d5c7997fc12dc62f679b16a5a57ef9165f3ae", - "vout": 0, - "scriptSig": { - "asm": "3045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f[ALL] 02dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368", - "hex": "483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368" - }, - "sequence": 4294967294 - }, - { - "txid": "fcf2eaa14f49442c94f0be9ad2eeb81d3774283a5a996d5ac0d202f4968a8df9", - "vout": 1, - "scriptSig": { - "asm": "3044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b4[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - } - ], - "vout": [ - { - "value": 0.01687502, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "PTirET8nRhQ1zMEtZa8ThYiGdirjy5S7X2" - ] - } - }, - { - "value": 301.01625, - "n": 1, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 7b771748d7c97469b4a24a2b47cffbe7de604a14 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a9147b771748d7c97469b4a24a2b47cffbe7de604a1488ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "PKqzw9pcMcAUozCSFf8zHHQzg2145Q182C" - ] - } - } - ], - "hex": "010000001a86506a919de53e6e0867dff293f7b377017baf660d104bfda469607b49cc5801000000006a47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032cfeffffff89e8ca0da97dd6ef3773139d22213dd68d1cc8d7857c9d10ae43de6c5a1d7e13010000006a473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff36b940dc6739babeb54a73fb7d9f42b49762b30c34f6dceee81023baddeb8317010000006a473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff87e0cc318f6456e77de36f68cd980a22642a777beaeb00a6749c3a53b310f92a010000006a47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbaf152ade0bb36134b3c2b3d04bf49a102feeb35748b8fac0db0b0f6e9425932010000006a4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff777f9ca152149f6cc0e5aad31d9f4e4317cff52c9dd4777e5644be63d4b43658010000006b483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defefffffff5d0e85769174aa90d763cc550bb29330b79c523f5276752d459610c0fc67459010000006a473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffa5bb7f7970b63a3dbcff70690d1c77c857582260ff29022f91765d35eca6d35d010000006b483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff1bf3b842f83bea4fdd9fd09900186e5eebc369e7122cb31206b1dbb040f0eb60010000006a4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff45441d81e6fbe991318546de407b8788fae3a3b8ab3a6cc1a9dce35a57426c62010000006a47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbd69405c40f26d2be0b2c9a15568ad9a1c2e830b15939d7e6916e16a1ce66363010000006a47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6a734b93c3869b811805483bb439228846c9ac03c50ff5eb0290db04e33f7c67010000006b48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffd90db6aa6e9d0ebbb641df87dc935d619c43887b7e99443b6691f8e34d05e178010000006b483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffdae8cc62e11406d7dd30afed2a8396465e3feebb020d9e84044bf214cd26e88d010000006b483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffcc6193600ded8300ab8dde1b2b93b290458f465801df18de4dc2c4422e87b69f010000006b483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3064def7e62659432943a77e73a57ed579c82677eb0498f6130e5af1836b12a7010000006b483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff8837066dd8e570430210ae5151047cf17728039837f795b272fafc74caafd1a7010000006a47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff771f53363bd6b099c3e5f4d609ef80cb95472e5a4820be9182451cd6002651ab010000006b483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff905b03d4030edd8ecc5c4dc85c654df0acc3a15f4dbd496f2199eb528819a1ad010000006b483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffb5a748a8822bdd2e3c9b553e058a027c9d118f956bdacabed700c1ea5ce481ba010000006a47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff633890f647d4af11a6c48f84fdf7cb39e9a1434453c41fc7adbf5e1805118ece010000006a473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6c1d70c078396e54d12ffe889547199a8218e22adb8dfc8d42cda805655cf8cf010000006b483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3b970e8473a5556fb749f60bfe84073b0904ed4b4b8a3c137807eed19bcfabe3010000006b483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffc93cf5d6f4bad4fd5a263137cdb05dafa3b8bbcc16d055cfbbc08f2c775e9bef010000006b483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffaef36591ef575a6ab179f662dc12fc97795c1dd6ed7e06785b0fbbc2588887f1000000006b483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368fefffffff98d8a96f402d2c05a6d995a3a2874371db8eed29abef0942c44494fa1eaf2fc010000006a473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff02cebf1900000000001976a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88aca8583202070000001976a9147b771748d7c97469b4a24a2b47cffbe7de604a1488accb8a0100" - } diff --git a/src/test/data/tt-delout1-out.hex b/src/test/data/tt-delout1-out.hex deleted file mode 100755 index 0b1b2549b..000000000 --- a/src/test/data/tt-delout1-out.hex +++ /dev/null @@ -1 +0,0 @@ -010000001b86506a919de53e6e0867dff293f7b377017baf660d104bfda469607b49cc5801000000006a47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032cfeffffff4dbf8ba4524a990be7a88a396e6407e40b03385914f9ba8d06447965a2563403010000006b48304502210095043aacee9dc26b00c0f5da7f7ad6747ea166573a4c7157fd35551e4b690ef50220253b782e0a3ff471cfe39b1fbc1ac564a2a7555d2d49112af3ae7874a44c77e201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff89e8ca0da97dd6ef3773139d22213dd68d1cc8d7857c9d10ae43de6c5a1d7e13010000006a473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff36b940dc6739babeb54a73fb7d9f42b49762b30c34f6dceee81023baddeb8317010000006a473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff87e0cc318f6456e77de36f68cd980a22642a777beaeb00a6749c3a53b310f92a010000006a47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbaf152ade0bb36134b3c2b3d04bf49a102feeb35748b8fac0db0b0f6e9425932010000006a4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff777f9ca152149f6cc0e5aad31d9f4e4317cff52c9dd4777e5644be63d4b43658010000006b483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defefffffff5d0e85769174aa90d763cc550bb29330b79c523f5276752d459610c0fc67459010000006a473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffa5bb7f7970b63a3dbcff70690d1c77c857582260ff29022f91765d35eca6d35d010000006b483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff1bf3b842f83bea4fdd9fd09900186e5eebc369e7122cb31206b1dbb040f0eb60010000006a4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff45441d81e6fbe991318546de407b8788fae3a3b8ab3a6cc1a9dce35a57426c62010000006a47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbd69405c40f26d2be0b2c9a15568ad9a1c2e830b15939d7e6916e16a1ce66363010000006a47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6a734b93c3869b811805483bb439228846c9ac03c50ff5eb0290db04e33f7c67010000006b48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffd90db6aa6e9d0ebbb641df87dc935d619c43887b7e99443b6691f8e34d05e178010000006b483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffdae8cc62e11406d7dd30afed2a8396465e3feebb020d9e84044bf214cd26e88d010000006b483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffcc6193600ded8300ab8dde1b2b93b290458f465801df18de4dc2c4422e87b69f010000006b483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3064def7e62659432943a77e73a57ed579c82677eb0498f6130e5af1836b12a7010000006b483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff8837066dd8e570430210ae5151047cf17728039837f795b272fafc74caafd1a7010000006a47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff771f53363bd6b099c3e5f4d609ef80cb95472e5a4820be9182451cd6002651ab010000006b483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff905b03d4030edd8ecc5c4dc85c654df0acc3a15f4dbd496f2199eb528819a1ad010000006b483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffb5a748a8822bdd2e3c9b553e058a027c9d118f956bdacabed700c1ea5ce481ba010000006a47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff633890f647d4af11a6c48f84fdf7cb39e9a1434453c41fc7adbf5e1805118ece010000006a473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6c1d70c078396e54d12ffe889547199a8218e22adb8dfc8d42cda805655cf8cf010000006b483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3b970e8473a5556fb749f60bfe84073b0904ed4b4b8a3c137807eed19bcfabe3010000006b483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffc93cf5d6f4bad4fd5a263137cdb05dafa3b8bbcc16d055cfbbc08f2c775e9bef010000006b483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffaef36591ef575a6ab179f662dc12fc97795c1dd6ed7e06785b0fbbc2588887f1000000006b483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368fefffffff98d8a96f402d2c05a6d995a3a2874371db8eed29abef0942c44494fa1eaf2fc010000006a473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff01cebf1900000000001976a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88accb8a0100 \ No newline at end of file diff --git a/src/test/data/tt-delout1-out.json b/src/test/data/tt-delout1-out.json deleted file mode 100755 index 5bf129ab3..000000000 --- a/src/test/data/tt-delout1-out.json +++ /dev/null @@ -1,266 +0,0 @@ -{ - "txid": "66d795b1f6b86c296763aa2c721b9896bdb9f6e304ed122c05c87f775eca99cb", - "version": 1, - "hex": "010000001b86506a919de53e6e0867dff293f7b377017baf660d104bfda469607b49cc5801000000006a47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032cfeffffff4dbf8ba4524a990be7a88a396e6407e40b03385914f9ba8d06447965a2563403010000006b48304502210095043aacee9dc26b00c0f5da7f7ad6747ea166573a4c7157fd35551e4b690ef50220253b782e0a3ff471cfe39b1fbc1ac564a2a7555d2d49112af3ae7874a44c77e201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff89e8ca0da97dd6ef3773139d22213dd68d1cc8d7857c9d10ae43de6c5a1d7e13010000006a473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff36b940dc6739babeb54a73fb7d9f42b49762b30c34f6dceee81023baddeb8317010000006a473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff87e0cc318f6456e77de36f68cd980a22642a777beaeb00a6749c3a53b310f92a010000006a47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbaf152ade0bb36134b3c2b3d04bf49a102feeb35748b8fac0db0b0f6e9425932010000006a4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff777f9ca152149f6cc0e5aad31d9f4e4317cff52c9dd4777e5644be63d4b43658010000006b483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defefffffff5d0e85769174aa90d763cc550bb29330b79c523f5276752d459610c0fc67459010000006a473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffa5bb7f7970b63a3dbcff70690d1c77c857582260ff29022f91765d35eca6d35d010000006b483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff1bf3b842f83bea4fdd9fd09900186e5eebc369e7122cb31206b1dbb040f0eb60010000006a4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff45441d81e6fbe991318546de407b8788fae3a3b8ab3a6cc1a9dce35a57426c62010000006a47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbd69405c40f26d2be0b2c9a15568ad9a1c2e830b15939d7e6916e16a1ce66363010000006a47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6a734b93c3869b811805483bb439228846c9ac03c50ff5eb0290db04e33f7c67010000006b48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffd90db6aa6e9d0ebbb641df87dc935d619c43887b7e99443b6691f8e34d05e178010000006b483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffdae8cc62e11406d7dd30afed2a8396465e3feebb020d9e84044bf214cd26e88d010000006b483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffcc6193600ded8300ab8dde1b2b93b290458f465801df18de4dc2c4422e87b69f010000006b483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3064def7e62659432943a77e73a57ed579c82677eb0498f6130e5af1836b12a7010000006b483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff8837066dd8e570430210ae5151047cf17728039837f795b272fafc74caafd1a7010000006a47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff771f53363bd6b099c3e5f4d609ef80cb95472e5a4820be9182451cd6002651ab010000006b483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff905b03d4030edd8ecc5c4dc85c654df0acc3a15f4dbd496f2199eb528819a1ad010000006b483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffb5a748a8822bdd2e3c9b553e058a027c9d118f956bdacabed700c1ea5ce481ba010000006a47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff633890f647d4af11a6c48f84fdf7cb39e9a1434453c41fc7adbf5e1805118ece010000006a473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6c1d70c078396e54d12ffe889547199a8218e22adb8dfc8d42cda805655cf8cf010000006b483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3b970e8473a5556fb749f60bfe84073b0904ed4b4b8a3c137807eed19bcfabe3010000006b483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffc93cf5d6f4bad4fd5a263137cdb05dafa3b8bbcc16d055cfbbc08f2c775e9bef010000006b483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffaef36591ef575a6ab179f662dc12fc97795c1dd6ed7e06785b0fbbc2588887f1000000006b483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368fefffffff98d8a96f402d2c05a6d995a3a2874371db8eed29abef0942c44494fa1eaf2fc010000006a473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff01cebf1900000000001976a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88accb8a0100", - "vin": [ - { - "sequence": 4294967294, - "scriptSig": { - "hex": "47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032c", - "asm": "304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f1[ALL] 020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032c" - }, - "txid": "0158cc497b6069a4fd4b100d66af7b0177b3f793f2df67086e3ee59d916a5086", - "vout": 0 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "48304502210095043aacee9dc26b00c0f5da7f7ad6747ea166573a4c7157fd35551e4b690ef50220253b782e0a3ff471cfe39b1fbc1ac564a2a7555d2d49112af3ae7874a44c77e201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "304502210095043aacee9dc26b00c0f5da7f7ad6747ea166573a4c7157fd35551e4b690ef50220253b782e0a3ff471cfe39b1fbc1ac564a2a7555d2d49112af3ae7874a44c77e2[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "033456a2657944068dbaf9145938030be407646e398aa8e70b994a52a48bbf4d", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "137e1d5a6cde43ae109d7c85d7c81c8dd63d21229d137337efd67da90dcae889", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a3[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "1783ebddba2310e8eedcf6340cb36297b4429f7dfb734ab5beba3967dc40b936", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e201498280555[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "2af910b3533a9c74a600ebea7b772a64220a98cd686fe37de756648f31cce087", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "30440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "325942e9f6b0b00dac8f8b7435ebfe02a149bf043d2b3c4b1336bbe0ad52f1ba", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "5836b4d463be44567e77d49d2cf5cf17434e9f1dd3aae5c06c9f1452a19c7f77", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c03[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "5974c60f0c6159d4526727f523c5790b3329bb50c53c760da94a176957e8d0f5", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc3[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "5dd3a6ec355d76912f0229ff60225857c8771c0d6970ffbc3d3ab670797fbba5", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "30440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "60ebf040b0dbb10612b32c12e769c3eb5e6e180099d09fdd4fea3bf842b8f31b", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b86[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "626c42575ae3dca9c16c3aabb8a3e3fa88877b40de46853191e9fbe6811d4445", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de2[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "6363e61c6ae116697e9d93150b832e1c9aad6855a1c9b2e02b6df2405c4069bd", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb4[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "677c3fe304db9002ebf50fc503acc946882239b43b480518819b86c3934b736a", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab44[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "78e1054de3f891663b44997e7b88439c615d93dc87df41b6bb0e9d6eaab60dd9", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e333[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "8de826cd14f24b04849e0d02bbee3f5e4696832aedaf30ddd70614e162cce8da", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d563[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "9fb6872e42c4c24dde18df0158468f4590b2932b1bde8dab0083ed0d609361cc", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c080[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "a7126b83f15a0e13f69804eb7726c879d57ea5737ea74329435926e6f7de6430", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "a7d1afca74fcfa72b295f73798032877f17c045151ae10024370e5d86d063788", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f38[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "ab512600d61c458291be20485a2e4795cb80ef09d6f4e5c399b0d63b36531f77", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "ada1198852eb99216f49bd4d5fa1c3acf04d655cc84d5ccc8edd0e03d4035b90", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "ba81e45ceac100d7becada6b958f119d7c028a053e559b3c2edd2b82a848a7b5", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f1326[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "ce8e1105185ebfadc71fc4534443a1e939cbf7fd848fc4a611afd447f6903863", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "cff85c6505a8cd428dfc8ddb2ae218829a19479588fe2fd1546e3978c0701d6c", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "e3abcf9bd1ee0778133c8a4b4bed04093b0784fe0bf649b76f55a573840e973b", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e59124[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "ef9b5e772c8fc0bbcf55d016ccbbb8a3af5db0cd3731265afdd4baf4d6f53cc9", - "vout": 1 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368", - "asm": "3045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f[ALL] 02dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368" - }, - "txid": "f1878858c2bb0f5b78067eedd61d5c7997fc12dc62f679b16a5a57ef9165f3ae", - "vout": 0 - }, - { - "sequence": 4294967294, - "scriptSig": { - "hex": "473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "asm": "3044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b4[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "txid": "fcf2eaa14f49442c94f0be9ad2eeb81d3774283a5a996d5ac0d202f4968a8df9", - "vout": 1 - } - ], - "locktime": 101067, - "vout": [ - { - "value": 0.01687502, - "scriptPubKey": { - "addresses": [ - "PTirET8nRhQ1zMEtZa8ThYiGdirjy5S7X2" - ], - "reqSigs": 1, - "type": "pubkeyhash", - "hex": "76a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88ac", - "asm": "OP_DUP OP_HASH160 d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f OP_EQUALVERIFY OP_CHECKSIG" - }, - "n": 0 - } - ] -} \ No newline at end of file diff --git a/src/test/data/tt-locktime317000-out.hex b/src/test/data/tt-locktime317000-out.hex deleted file mode 100755 index 2f79f8c8c..000000000 --- a/src/test/data/tt-locktime317000-out.hex +++ /dev/null @@ -1 +0,0 @@ -010000001b86506a919de53e6e0867dff293f7b377017baf660d104bfda469607b49cc5801000000006a47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032cfeffffff4dbf8ba4524a990be7a88a396e6407e40b03385914f9ba8d06447965a2563403010000006b48304502210095043aacee9dc26b00c0f5da7f7ad6747ea166573a4c7157fd35551e4b690ef50220253b782e0a3ff471cfe39b1fbc1ac564a2a7555d2d49112af3ae7874a44c77e201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff89e8ca0da97dd6ef3773139d22213dd68d1cc8d7857c9d10ae43de6c5a1d7e13010000006a473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff36b940dc6739babeb54a73fb7d9f42b49762b30c34f6dceee81023baddeb8317010000006a473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff87e0cc318f6456e77de36f68cd980a22642a777beaeb00a6749c3a53b310f92a010000006a47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbaf152ade0bb36134b3c2b3d04bf49a102feeb35748b8fac0db0b0f6e9425932010000006a4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff777f9ca152149f6cc0e5aad31d9f4e4317cff52c9dd4777e5644be63d4b43658010000006b483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defefffffff5d0e85769174aa90d763cc550bb29330b79c523f5276752d459610c0fc67459010000006a473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffa5bb7f7970b63a3dbcff70690d1c77c857582260ff29022f91765d35eca6d35d010000006b483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff1bf3b842f83bea4fdd9fd09900186e5eebc369e7122cb31206b1dbb040f0eb60010000006a4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff45441d81e6fbe991318546de407b8788fae3a3b8ab3a6cc1a9dce35a57426c62010000006a47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbd69405c40f26d2be0b2c9a15568ad9a1c2e830b15939d7e6916e16a1ce66363010000006a47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6a734b93c3869b811805483bb439228846c9ac03c50ff5eb0290db04e33f7c67010000006b48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffd90db6aa6e9d0ebbb641df87dc935d619c43887b7e99443b6691f8e34d05e178010000006b483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffdae8cc62e11406d7dd30afed2a8396465e3feebb020d9e84044bf214cd26e88d010000006b483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffcc6193600ded8300ab8dde1b2b93b290458f465801df18de4dc2c4422e87b69f010000006b483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3064def7e62659432943a77e73a57ed579c82677eb0498f6130e5af1836b12a7010000006b483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff8837066dd8e570430210ae5151047cf17728039837f795b272fafc74caafd1a7010000006a47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff771f53363bd6b099c3e5f4d609ef80cb95472e5a4820be9182451cd6002651ab010000006b483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff905b03d4030edd8ecc5c4dc85c654df0acc3a15f4dbd496f2199eb528819a1ad010000006b483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffb5a748a8822bdd2e3c9b553e058a027c9d118f956bdacabed700c1ea5ce481ba010000006a47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff633890f647d4af11a6c48f84fdf7cb39e9a1434453c41fc7adbf5e1805118ece010000006a473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6c1d70c078396e54d12ffe889547199a8218e22adb8dfc8d42cda805655cf8cf010000006b483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3b970e8473a5556fb749f60bfe84073b0904ed4b4b8a3c137807eed19bcfabe3010000006b483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffc93cf5d6f4bad4fd5a263137cdb05dafa3b8bbcc16d055cfbbc08f2c775e9bef010000006b483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffaef36591ef575a6ab179f662dc12fc97795c1dd6ed7e06785b0fbbc2588887f1000000006b483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368fefffffff98d8a96f402d2c05a6d995a3a2874371db8eed29abef0942c44494fa1eaf2fc010000006a473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff02cebf1900000000001976a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88aca8583202070000001976a9147b771748d7c97469b4a24a2b47cffbe7de604a1488ac48d60400 \ No newline at end of file diff --git a/src/test/data/tt-locktime317000-out.json b/src/test/data/tt-locktime317000-out.json deleted file mode 100755 index 855aa55b0..000000000 --- a/src/test/data/tt-locktime317000-out.json +++ /dev/null @@ -1,279 +0,0 @@ - { - "txid": "d84e3e85c2b651a7071812ab1be45e7a56a01b9e2005cd8a324e211b3ba6839f", - "version": 1, - "locktime": 317000, - "vin": [ - { - "txid": "0158cc497b6069a4fd4b100d66af7b0177b3f793f2df67086e3ee59d916a5086", - "vout": 0, - "scriptSig": { - "asm": "304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f1[ALL] 020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032c", - "hex": "47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032c" - }, - "sequence": 4294967294 - }, - { - "txid": "033456a2657944068dbaf9145938030be407646e398aa8e70b994a52a48bbf4d", - "vout": 1, - "scriptSig": { - "asm": "304502210095043aacee9dc26b00c0f5da7f7ad6747ea166573a4c7157fd35551e4b690ef50220253b782e0a3ff471cfe39b1fbc1ac564a2a7555d2d49112af3ae7874a44c77e2[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "48304502210095043aacee9dc26b00c0f5da7f7ad6747ea166573a4c7157fd35551e4b690ef50220253b782e0a3ff471cfe39b1fbc1ac564a2a7555d2d49112af3ae7874a44c77e201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "137e1d5a6cde43ae109d7c85d7c81c8dd63d21229d137337efd67da90dcae889", - "vout": 1, - "scriptSig": { - "asm": "3044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "1783ebddba2310e8eedcf6340cb36297b4429f7dfb734ab5beba3967dc40b936", - "vout": 1, - "scriptSig": { - "asm": "3044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a3[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "2af910b3533a9c74a600ebea7b772a64220a98cd686fe37de756648f31cce087", - "vout": 1, - "scriptSig": { - "asm": "304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e201498280555[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "325942e9f6b0b00dac8f8b7435ebfe02a149bf043d2b3c4b1336bbe0ad52f1ba", - "vout": 1, - "scriptSig": { - "asm": "30440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "5836b4d463be44567e77d49d2cf5cf17434e9f1dd3aae5c06c9f1452a19c7f77", - "vout": 1, - "scriptSig": { - "asm": "3045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "5974c60f0c6159d4526727f523c5790b3329bb50c53c760da94a176957e8d0f5", - "vout": 1, - "scriptSig": { - "asm": "3044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c03[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "5dd3a6ec355d76912f0229ff60225857c8771c0d6970ffbc3d3ab670797fbba5", - "vout": 1, - "scriptSig": { - "asm": "3045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc3[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "60ebf040b0dbb10612b32c12e769c3eb5e6e180099d09fdd4fea3bf842b8f31b", - "vout": 1, - "scriptSig": { - "asm": "30440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "626c42575ae3dca9c16c3aabb8a3e3fa88877b40de46853191e9fbe6811d4445", - "vout": 1, - "scriptSig": { - "asm": "304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b86[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "6363e61c6ae116697e9d93150b832e1c9aad6855a1c9b2e02b6df2405c4069bd", - "vout": 1, - "scriptSig": { - "asm": "304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de2[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "677c3fe304db9002ebf50fc503acc946882239b43b480518819b86c3934b736a", - "vout": 1, - "scriptSig": { - "asm": "304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb4[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "78e1054de3f891663b44997e7b88439c615d93dc87df41b6bb0e9d6eaab60dd9", - "vout": 1, - "scriptSig": { - "asm": "3045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab44[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "8de826cd14f24b04849e0d02bbee3f5e4696832aedaf30ddd70614e162cce8da", - "vout": 1, - "scriptSig": { - "asm": "3045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e333[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "9fb6872e42c4c24dde18df0158468f4590b2932b1bde8dab0083ed0d609361cc", - "vout": 1, - "scriptSig": { - "asm": "3045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d563[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "a7126b83f15a0e13f69804eb7726c879d57ea5737ea74329435926e6f7de6430", - "vout": 1, - "scriptSig": { - "asm": "3045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c080[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "a7d1afca74fcfa72b295f73798032877f17c045151ae10024370e5d86d063788", - "vout": 1, - "scriptSig": { - "asm": "304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ab512600d61c458291be20485a2e4795cb80ef09d6f4e5c399b0d63b36531f77", - "vout": 1, - "scriptSig": { - "asm": "3045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f38[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ada1198852eb99216f49bd4d5fa1c3acf04d655cc84d5ccc8edd0e03d4035b90", - "vout": 1, - "scriptSig": { - "asm": "3045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ba81e45ceac100d7becada6b958f119d7c028a053e559b3c2edd2b82a848a7b5", - "vout": 1, - "scriptSig": { - "asm": "304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ce8e1105185ebfadc71fc4534443a1e939cbf7fd848fc4a611afd447f6903863", - "vout": 1, - "scriptSig": { - "asm": "3044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f1326[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "cff85c6505a8cd428dfc8ddb2ae218829a19479588fe2fd1546e3978c0701d6c", - "vout": 1, - "scriptSig": { - "asm": "3045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "e3abcf9bd1ee0778133c8a4b4bed04093b0784fe0bf649b76f55a573840e973b", - "vout": 1, - "scriptSig": { - "asm": "3045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "ef9b5e772c8fc0bbcf55d016ccbbb8a3af5db0cd3731265afdd4baf4d6f53cc9", - "vout": 1, - "scriptSig": { - "asm": "3045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e59124[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - }, - { - "txid": "f1878858c2bb0f5b78067eedd61d5c7997fc12dc62f679b16a5a57ef9165f3ae", - "vout": 0, - "scriptSig": { - "asm": "3045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f[ALL] 02dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368", - "hex": "483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368" - }, - "sequence": 4294967294 - }, - { - "txid": "fcf2eaa14f49442c94f0be9ad2eeb81d3774283a5a996d5ac0d202f4968a8df9", - "vout": 1, - "scriptSig": { - "asm": "3044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b4[ALL] 0212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de", - "hex": "473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097de" - }, - "sequence": 4294967294 - } - ], - "vout": [ - { - "value": 0.01687502, - "n": 0, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "PTirET8nRhQ1zMEtZa8ThYiGdirjy5S7X2" - ] - } - }, - { - "value": 301.01625, - "n": 1, - "scriptPubKey": { - "asm": "OP_DUP OP_HASH160 7b771748d7c97469b4a24a2b47cffbe7de604a14 OP_EQUALVERIFY OP_CHECKSIG", - "hex": "76a9147b771748d7c97469b4a24a2b47cffbe7de604a1488ac", - "reqSigs": 1, - "type": "pubkeyhash", - "addresses": [ - "PKqzw9pcMcAUozCSFf8zHHQzg2145Q182C" - ] - } - } - ], - "hex": "010000001b86506a919de53e6e0867dff293f7b377017baf660d104bfda469607b49cc5801000000006a47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032cfeffffff4dbf8ba4524a990be7a88a396e6407e40b03385914f9ba8d06447965a2563403010000006b48304502210095043aacee9dc26b00c0f5da7f7ad6747ea166573a4c7157fd35551e4b690ef50220253b782e0a3ff471cfe39b1fbc1ac564a2a7555d2d49112af3ae7874a44c77e201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff89e8ca0da97dd6ef3773139d22213dd68d1cc8d7857c9d10ae43de6c5a1d7e13010000006a473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff36b940dc6739babeb54a73fb7d9f42b49762b30c34f6dceee81023baddeb8317010000006a473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff87e0cc318f6456e77de36f68cd980a22642a777beaeb00a6749c3a53b310f92a010000006a47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbaf152ade0bb36134b3c2b3d04bf49a102feeb35748b8fac0db0b0f6e9425932010000006a4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff777f9ca152149f6cc0e5aad31d9f4e4317cff52c9dd4777e5644be63d4b43658010000006b483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defefffffff5d0e85769174aa90d763cc550bb29330b79c523f5276752d459610c0fc67459010000006a473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffa5bb7f7970b63a3dbcff70690d1c77c857582260ff29022f91765d35eca6d35d010000006b483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff1bf3b842f83bea4fdd9fd09900186e5eebc369e7122cb31206b1dbb040f0eb60010000006a4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff45441d81e6fbe991318546de407b8788fae3a3b8ab3a6cc1a9dce35a57426c62010000006a47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbd69405c40f26d2be0b2c9a15568ad9a1c2e830b15939d7e6916e16a1ce66363010000006a47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6a734b93c3869b811805483bb439228846c9ac03c50ff5eb0290db04e33f7c67010000006b48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffd90db6aa6e9d0ebbb641df87dc935d619c43887b7e99443b6691f8e34d05e178010000006b483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffdae8cc62e11406d7dd30afed2a8396465e3feebb020d9e84044bf214cd26e88d010000006b483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffcc6193600ded8300ab8dde1b2b93b290458f465801df18de4dc2c4422e87b69f010000006b483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3064def7e62659432943a77e73a57ed579c82677eb0498f6130e5af1836b12a7010000006b483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff8837066dd8e570430210ae5151047cf17728039837f795b272fafc74caafd1a7010000006a47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff771f53363bd6b099c3e5f4d609ef80cb95472e5a4820be9182451cd6002651ab010000006b483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff905b03d4030edd8ecc5c4dc85c654df0acc3a15f4dbd496f2199eb528819a1ad010000006b483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffb5a748a8822bdd2e3c9b553e058a027c9d118f956bdacabed700c1ea5ce481ba010000006a47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff633890f647d4af11a6c48f84fdf7cb39e9a1434453c41fc7adbf5e1805118ece010000006a473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6c1d70c078396e54d12ffe889547199a8218e22adb8dfc8d42cda805655cf8cf010000006b483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3b970e8473a5556fb749f60bfe84073b0904ed4b4b8a3c137807eed19bcfabe3010000006b483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffc93cf5d6f4bad4fd5a263137cdb05dafa3b8bbcc16d055cfbbc08f2c775e9bef010000006b483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffaef36591ef575a6ab179f662dc12fc97795c1dd6ed7e06785b0fbbc2588887f1000000006b483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368fefffffff98d8a96f402d2c05a6d995a3a2874371db8eed29abef0942c44494fa1eaf2fc010000006a473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff02cebf1900000000001976a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88aca8583202070000001976a9147b771748d7c97469b4a24a2b47cffbe7de604a1488ac48d60400" - } \ No newline at end of file diff --git a/src/test/data/tx394b54bb.hex b/src/test/data/tx394b54bb.hex deleted file mode 100755 index 4ff726e22..000000000 --- a/src/test/data/tx394b54bb.hex +++ /dev/null @@ -1 +0,0 @@ -010000001b86506a919de53e6e0867dff293f7b377017baf660d104bfda469607b49cc5801000000006a47304402204f9d5d0fab2809086ab5e7f484ebed1b01095de31cc9155d1c8c88c9646d25fb02206e079f7a87c1f18d347243878b5be4494b9dd2e786f9d1ff6b0d6386dc1c67f10121020f56d9f8af7f0c22a51c6e1bc688bff5f5e36e49334ddb2910c461b93085032cfeffffff4dbf8ba4524a990be7a88a396e6407e40b03385914f9ba8d06447965a2563403010000006b48304502210095043aacee9dc26b00c0f5da7f7ad6747ea166573a4c7157fd35551e4b690ef50220253b782e0a3ff471cfe39b1fbc1ac564a2a7555d2d49112af3ae7874a44c77e201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff89e8ca0da97dd6ef3773139d22213dd68d1cc8d7857c9d10ae43de6c5a1d7e13010000006a473044022012231c5671a1f8e598674b9f53e8aac7c4038722137bf3ff5934fea0ea4411d402202307366c8c18ffc4406a624fbc3c307a7754d447aff7604d06e7bb739f64f8cc01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff36b940dc6739babeb54a73fb7d9f42b49762b30c34f6dceee81023baddeb8317010000006a473044022030997fb25cad00972022e1544fcc1ce7b41a620490693b9f1876e937723121ad022058df06e31577852af3507e6c0ac2bed0abf9c13a984d4212ec6c3b9dd63f24a301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff87e0cc318f6456e77de36f68cd980a22642a777beaeb00a6749c3a53b310f92a010000006a47304402203d2a067cc32f9d88553857b9b59a1b4811712a5b8e6db65eb8bb699d94295dd202203987a9f49899c49a3dc602db2abe12357d0116d2b288a9f05c2e20149828055501210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbaf152ade0bb36134b3c2b3d04bf49a102feeb35748b8fac0db0b0f6e9425932010000006a4730440220299be710ef742eaf2cf16d8db1e2406c8914878f0a6d9a556e794c35758813bf022071d74081ec8e5e002876b6224ee274bdd2ae859ca3b2288bb1df76c11d53581f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff777f9ca152149f6cc0e5aad31d9f4e4317cff52c9dd4777e5644be63d4b43658010000006b483045022100934ed0b260a7a4e2a93e9228590658f9640505decd5016f5b3489b75861c2afb022045bb3519cb6b61be198a6a24790372d5ac43423e12590c97c1259d1e83c8002b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defefffffff5d0e85769174aa90d763cc550bb29330b79c523f5276752d459610c0fc67459010000006a473044022035c6330c3de8ff776bfb2a73baf210ac027a143c371efadb0c768a5bb1e097e1022044f5c0efc01ddf888d945e5170f226c56055671b6e1274beb60f4bf64ce79c0301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffa5bb7f7970b63a3dbcff70690d1c77c857582260ff29022f91765d35eca6d35d010000006b483045022100c737bde76ede2a8e4a7bed415d51ba6c39dd199cd7a3c315ee8de71ddc9d032902202073196f0ca995588589e3d066fa26ed37a6b02bff0b6a6b70df6be77c49cfc301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff1bf3b842f83bea4fdd9fd09900186e5eebc369e7122cb31206b1dbb040f0eb60010000006a4730440220384548d221d1884830f6c9951f1bafb68df35fcad7bb941cb9d81f70852076e5022022630d1022bcdb8fe9fcd5cc048b72d73e64c877a92d404cafea6a562f81d72f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff45441d81e6fbe991318546de407b8788fae3a3b8ab3a6cc1a9dce35a57426c62010000006a47304402201a35b48d442a0cbd1619b33901c0ed4814eae1c9635a9db282d21a1860fc496402202ae3540da2e73268addce99e2993198c6d7c34eb2a770a2d22fc268886c24b8601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffbd69405c40f26d2be0b2c9a15568ad9a1c2e830b15939d7e6916e16a1ce66363010000006a47304402206ce7d0038e6a8bae7a38a6d996c053d18716da3c71c765e31afa85d6fe334625022065075cf171e57bc8dfe76d8dfa7f1623b3293f21cb3f54d285853b2a9d789de201210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6a734b93c3869b811805483bb439228846c9ac03c50ff5eb0290db04e33f7c67010000006b48304502210093dc7fcbd881a91279eeab1b2cafea8df2fa43e297982e75eac186f4170af68302205110412f370d98cf82f417cd330ce054e54b6f9bd6b99b8936119ab6d7f5dfb401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffd90db6aa6e9d0ebbb641df87dc935d619c43887b7e99443b6691f8e34d05e178010000006b483045022100cc12b9206438ebd0f07a1f5fd6b477ef258dc64b2eb0714bcd7284e08dd00811022071c87fcc1524c05b2886373916da7179c6abf05dd588451c2b7cb84f6848ab4401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffdae8cc62e11406d7dd30afed2a8396465e3feebb020d9e84044bf214cd26e88d010000006b483045022100c8502def84764c63814f366d04e5a09d54ff5b24bfc7c700213bcf0d226eb4a202205020720ccd8ba7b7fa235f735f82fe658c2277aafe8c800dd468422fa240e33301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffcc6193600ded8300ab8dde1b2b93b290458f465801df18de4dc2c4422e87b69f010000006b483045022100cd9fdf5d66a43e728a52f3224e844cd6488146944488d2e5907dd95fb31c961b0220589a0922481373677d8e57e1c1fa18e7582161a7ac522e9cf256cacdc869d56301210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3064def7e62659432943a77e73a57ed579c82677eb0498f6130e5af1836b12a7010000006b483045022100a2533ea9a34466943d3f58d1c38d24b5b33306cf67e7e1e568cb189419ef2758022005e6558e6f77bf79c976594b2394c68574e4451d36c953b13e1ae1301654c08001210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff8837066dd8e570430210ae5151047cf17728039837f795b272fafc74caafd1a7010000006a47304402206516efb998ff4b271c44f421c2b83021cab711991be35de39681752292dc44d10220680e8f8de36011d05ca0b737545cf150df4ac8d71a85a7e0cdf527ad2b87843a01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff771f53363bd6b099c3e5f4d609ef80cb95472e5a4820be9182451cd6002651ab010000006b483045022100af5bb56923cf795d8cc42ae6eb776b4f682827c0b7667223ff9ad473bf891fd8022012d6f68a2a3a6e06e52695b6d945607b784142ec7d9d021ddc1781bba35c0f3801210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff905b03d4030edd8ecc5c4dc85c654df0acc3a15f4dbd496f2199eb528819a1ad010000006b483045022100c9fce623d36f7a724053fc5169ecc8fe6cf66a6390418c401f677b1ed2bf0340022006bb91ec51893d1c7d1cb8183d50b5016970ad656cf4bf0827c473e4160d9f3d01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffb5a748a8822bdd2e3c9b553e058a027c9d118f956bdacabed700c1ea5ce481ba010000006a47304402205712dc86d18bfd84171be17a330f719503abf8d439c51942c5832821a17f410202207c9728f9a038dded7a0bcf2fe9d2bd044a90b2bed6bc9a70c4d66aee30037a7f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff633890f647d4af11a6c48f84fdf7cb39e9a1434453c41fc7adbf5e1805118ece010000006a473044022021b178dca38c6d917f7ea6f3ebe4a14bbb2fccbf5dab7bbbef5c8e19977d0fce02206020d52a580e022f48a3ac2786dcdb5fd8bc7eb9d3908f269ab7551acd9f132601210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff6c1d70c078396e54d12ffe889547199a8218e22adb8dfc8d42cda805655cf8cf010000006b483045022100b181f9c7060977d25352cf37466dba04b722c6daa67571ef24963c70f1aecabb02200b09c8b8d17d962ad21d056a9dcee524a284d6d60b82e0e491ea59658365696b01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff3b970e8473a5556fb749f60bfe84073b0904ed4b4b8a3c137807eed19bcfabe3010000006b483045022100b2253fdeaa84ef86f76bd148fc26a424b5dff07bd59e3533a65d2c9df1b2cbae02200121c0c7101ea9863cae1a85002cebd90f276d5c3be00d4e9786c196e231124f01210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffc93cf5d6f4bad4fd5a263137cdb05dafa3b8bbcc16d055cfbbc08f2c775e9bef010000006b483045022100fa771e63ff9b69602d6a411c7b96908f51b6a86ebc1d46ee5c29d0c64bb536bf02203e5f9300d890714cfdeba2790cd2756f73497d313497687bd224ff14b8e5912401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffffaef36591ef575a6ab179f662dc12fc97795c1dd6ed7e06785b0fbbc2588887f1000000006b483045022100d31631d9b157871e97e0730a76d7aa2f96af7a162c2f676c599523895709d07902206fd6df62978f1290d32e87bc7d8b2594974d18a9ae6d6e79d8c418beb1fa3e3f012102dae431206cba26ab02afeb5c5b0021d9cb0b0cb711d4edd6732b499bff1a6368fefffffff98d8a96f402d2c05a6d995a3a2874371db8eed29abef0942c44494fa1eaf2fc010000006a473044022060e435eec8da330e8a41cebe596c5602a113619a33c68be3a36d1cfc5473fc7602203f4d285a303d66f46c68f69e566cc3e7be47a8edb728275500ea37eefbc388b401210212fa9ae938d2a90f9e17b0916007f3d18b276843e8f82b14203a4dec37f097defeffffff02cebf1900000000001976a914d1ddebf0769fd9fc7ba0d99a4cbb18466ff2554f88aca8583202070000001976a9147b771748d7c97469b4a24a2b47cffbe7de604a1488accb8a0100 diff --git a/src/test/dbwrapper_tests.cpp b/src/test/dbwrapper_tests.cpp index 8e2234f83..c878c6ad0 100755 --- a/src/test/dbwrapper_tests.cpp +++ b/src/test/dbwrapper_tests.cpp @@ -141,6 +141,7 @@ BOOST_AUTO_TEST_CASE(existing_data_no_obfuscate) // Call the destructor to free leveldb LOCK delete dbw; + dbw = nullptr; // Now, set up another wrapper that wants to obfuscate the same directory CDBWrapper odbw(ph, (1 << 10), false, false, true); @@ -182,6 +183,7 @@ BOOST_AUTO_TEST_CASE(existing_data_reindex) // Call the destructor to free leveldb LOCK delete dbw; + dbw = nullptr; // Simulate a -reindex by wiping the existing data store CDBWrapper odbw(ph, (1 << 10), false, true, true); diff --git a/src/test/evo_simplifiedmns_tests.cpp b/src/test/evo_simplifiedmns_tests.cpp index 81750ffa7..338c5036c 100755 --- a/src/test/evo_simplifiedmns_tests.cpp +++ b/src/test/evo_simplifiedmns_tests.cpp @@ -29,7 +29,7 @@ BOOST_AUTO_TEST_CASE(simplifiedmns_merkleroots) CBLSSecretKey sk; sk.SetBuf(skBuf, sizeof(skBuf)); - smle.pubKeyOperator = sk.GetPublicKey(); + smle.pubKeyOperator.Set(sk.GetPublicKey()); smle.keyIDVoting.SetHex(strprintf("%040x", i)); smle.isValid = true; diff --git a/src/test/governance_validators_tests.cpp b/src/test/governance_validators_tests.cpp index 6b49057e5..e31923913 100755 --- a/src/test/governance_validators_tests.cpp +++ b/src/test/governance_validators_tests.cpp @@ -1,6 +1,6 @@ // Copyright (c) 2014-2018 The Dash Core developers -#include "governance-validators.h" +#include "governance/governance-validators.h" #include "utilstrencodings.h" #include "data/proposals_valid.json.h" @@ -28,7 +28,7 @@ std::string CreateEncodedProposalObject(const UniValue& objJSON) UniValue outerArray(UniValue::VARR); outerArray.push_back(innerArray); - + std::string strData = outerArray.write(); std::string strHex = HexStr(strData); return strHex; diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 731137cb3..a0b3a6fd5 100755 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -29,34 +29,6 @@ static const CBitcoinAddress addr2C("PL1uBGNC481hy7qHgVDEwEwxJ7d2a939QL"); static const std::string strAddressBad("Xta1praZQjyELweyMByXyiREw1ZRsjXzVP"); -#ifdef KEY_TESTS_DUMPINFO -void dumpKeyInfo(uint256 privkey) -{ - CKey key; - key.resize(32); - memcpy(&secret[0], &privkey, 32); - std::vector sec; - sec.resize(32); - memcpy(&sec[0], &secret[0], 32); - printf(" * secret (hex): %s\n", HexStr(sec).c_str()); - - for (int nCompressed=0; nCompressed<2; nCompressed++) - { - bool fCompressed = nCompressed == 1; - printf(" * %s:\n", fCompressed ? "compressed" : "uncompressed"); - CBitcoinSecret bsecret; - bsecret.SetSecret(secret, fCompressed); - printf(" * secret (base58): %s\n", bsecret.ToString().c_str()); - CKey key; - key.SetSecret(secret, fCompressed); - std::vector vchPubKey = key.GetPubKey(); - printf(" * pubkey (hex): %s\n", HexStr(vchPubKey).c_str()); - printf(" * address (base58): %s\n", CBitcoinAddress(vchPubKey).ToString().c_str()); - } -} -#endif - - BOOST_FIXTURE_TEST_SUITE(key_tests, BasicTestingSetup) BOOST_AUTO_TEST_CASE(key_test1) diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index 011d160ea..b4f3aef87 100755 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -8,7 +8,7 @@ #include "consensus/merkle.h" #include "consensus/validation.h" #include "validation.h" -#include "masternode-payments.h" +#include "masternode/masternode-payments.h" #include "miner.h" #include "policy/policy.h" #include "pubkey.h" diff --git a/src/test/ratecheck_tests.cpp b/src/test/ratecheck_tests.cpp index 901869838..634144c1e 100755 --- a/src/test/ratecheck_tests.cpp +++ b/src/test/ratecheck_tests.cpp @@ -1,7 +1,7 @@ // Copyright (c) 2014-2017 The Dash Core developers // Copyright (c) 2017-2018 The AXE Core developers -#include "governance.h" +#include "governance/governance.h" #include "test/test_axe.h" diff --git a/src/test/script_tests.cpp b/src/test/script_tests.cpp index 7a101195c..2bbe25fbf 100755 --- a/src/test/script_tests.cpp +++ b/src/test/script_tests.cpp @@ -31,7 +31,7 @@ // Uncomment if you want to output updated JSON tests. // #define UPDATE_JSON_TESTS -static const unsigned int flags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; +static const unsigned int gFlags = SCRIPT_VERIFY_P2SH | SCRIPT_VERIFY_STRICTENC; unsigned int ParseScriptFlags(std::string strFlags); std::string FormatScriptFlags(unsigned int flags); @@ -381,11 +381,6 @@ class TestBuilder { return comment; } - - const CScript& GetScriptPubKey() - { - return creditTx->vout[0].scriptPubKey; - } }; std::string JSONPrettyPrint(const UniValue& univalue) @@ -806,18 +801,18 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG12) CMutableTransaction txTo12 = BuildSpendingTransaction(CScript(), txFrom12); CScript goodsig1 = sign_multisig(scriptPubKey12, key1, txTo12); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey12, gFlags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); txTo12.vout[0].nValue = 2; - BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(goodsig1, scriptPubKey12, gFlags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); CScript goodsig2 = sign_multisig(scriptPubKey12, key2, txTo12); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey12, gFlags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); CScript badsig1 = sign_multisig(scriptPubKey12, key3, txTo12); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, flags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey12, gFlags, MutableTransactionSignatureChecker(&txTo12, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); } @@ -839,54 +834,54 @@ BOOST_AUTO_TEST_CASE(script_CHECKMULTISIG23) std::vector keys; keys.push_back(key1); keys.push_back(key2); CScript goodsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig1, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key3); CScript goodsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig2, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key3); CScript goodsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(VerifyScript(goodsig3, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_OK, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key2); // Can't re-use sig CScript badsig1 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig1, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key2); keys.push_back(key1); // sigs must be in correct order CScript badsig2 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig2, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key3); keys.push_back(key2); // sigs must be in correct order CScript badsig3 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig3, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key4); keys.push_back(key2); // sigs must match pubkeys CScript badsig4 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig4, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); keys.push_back(key1); keys.push_back(key4); // sigs must match pubkeys CScript badsig5 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig5, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_EVAL_FALSE, ScriptErrorString(err)); keys.clear(); // Must have signatures CScript badsig6 = sign_multisig(scriptPubKey23, keys, txTo23); - BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, flags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); + BOOST_CHECK(!VerifyScript(badsig6, scriptPubKey23, gFlags, MutableTransactionSignatureChecker(&txTo23, 0), &err)); BOOST_CHECK_MESSAGE(err == SCRIPT_ERR_INVALID_STACK_OPERATION, ScriptErrorString(err)); } diff --git a/src/test/test_axe.cpp b/src/test/test_axe.cpp index 2eaad5f93..8f97c052d 100755 --- a/src/test/test_axe.cpp +++ b/src/test/test_axe.cpp @@ -2,8 +2,6 @@ // Distributed under the MIT software license, see the accompanying // file COPYING or http://www.opensource.org/licenses/mit-license.php. -#define BOOST_TEST_MODULE Axe Test Suite - #include "test_axe.h" #include "chainparams.h" @@ -21,7 +19,6 @@ #include "rpc/server.h" #include "rpc/register.h" #include "script/sigcache.h" -#include "stacktraces.h" #include "test/testutil.h" @@ -33,11 +30,8 @@ #include #include -#include -#include #include -std::unique_ptr g_connman; FastRandomContext insecure_rand_ctx(true); extern bool fPrintToConsole; @@ -84,11 +78,14 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha pcoinsdbview = new CCoinsViewDB(1 << 23, true); llmq::InitLLMQSystem(*evoDb, nullptr, true); pcoinsTip = new CCoinsViewCache(pcoinsdbview); - BOOST_REQUIRE(InitBlockIndex(chainparams)); + if (!InitBlockIndex(chainparams)) { + throw std::runtime_error("InitBlockIndex failed."); + } { CValidationState state; - bool ok = ActivateBestChain(state, chainparams); - BOOST_REQUIRE(ok); + if (!ActivateBestChain(state, chainparams)) { + throw std::runtime_error("ActivateBestChain failed."); + } } nScriptCheckThreads = 3; for (int i=0; i < nScriptCheckThreads-1; i++) @@ -215,48 +212,3 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn) { return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, nHeight, spendsCoinbase, sigOpCount, lp); } - -void Shutdown(void* parg) -{ - exit(EXIT_SUCCESS); -} - -void StartShutdown() -{ - exit(EXIT_SUCCESS); -} - -bool ShutdownRequested() -{ - return false; -} - -template -void translate_exception(const T &e) -{ - std::cerr << GetPrettyExceptionStr(std::current_exception()) << std::endl; - throw; -} - -template -void register_exception_translator() -{ - boost::unit_test::unit_test_monitor.register_exception_translator(&translate_exception); -} - -struct ExceptionInitializer { - ExceptionInitializer() - { - RegisterPrettyTerminateHander(); - RegisterPrettySignalHandlers(); - - register_exception_translator(); - register_exception_translator(); - register_exception_translator(); - } - ~ExceptionInitializer() - { - } -}; - -BOOST_GLOBAL_FIXTURE( ExceptionInitializer ); diff --git a/src/test/test_axe_main.cpp b/src/test/test_axe_main.cpp new file mode 100644 index 000000000..802aaa83a --- /dev/null +++ b/src/test/test_axe_main.cpp @@ -0,0 +1,58 @@ +// Copyright (c) 2011-2016 The Bitcoin Core developers +// Distributed under the MIT software license, see the accompanying +// file COPYING or http://www.opensource.org/licenses/mit-license.php. + +#define BOOST_TEST_MODULE Bitcoin Test Suite + +#include "net.h" +#include "stacktraces.h" + +#include +#include + +std::unique_ptr g_connman; + +void Shutdown(void* parg) +{ + exit(EXIT_SUCCESS); +} + +void StartShutdown() +{ + exit(EXIT_SUCCESS); +} + +bool ShutdownRequested() +{ + return false; +} + +template +void translate_exception(const T &e) +{ + std::cerr << GetPrettyExceptionStr(std::current_exception()) << std::endl; + throw; +} + +template +void register_exception_translator() +{ + boost::unit_test::unit_test_monitor.register_exception_translator(&translate_exception); +} + +struct ExceptionInitializer { + ExceptionInitializer() + { + RegisterPrettyTerminateHander(); + RegisterPrettySignalHandlers(); + + register_exception_translator(); + register_exception_translator(); + register_exception_translator(); + } + ~ExceptionInitializer() + { + } +}; + +BOOST_GLOBAL_FIXTURE(ExceptionInitializer); diff --git a/src/tinyformat.h b/src/tinyformat.h index db7641302..10d73c2a0 100755 --- a/src/tinyformat.h +++ b/src/tinyformat.h @@ -123,7 +123,7 @@ namespace tinyformat {} namespace tfm = tinyformat; // Error handling; calls assert() by default. -#define TINYFORMAT_ERROR(reasonString) throw std::runtime_error(reasonString) +#define TINYFORMAT_ERROR(reasonString) throw tinyformat::format_error(reasonString) // Define for C++11 variadic templates which make the code shorter & more // general. If you don't define this, C++11 support is autodetected below. @@ -164,6 +164,13 @@ namespace tfm = tinyformat; namespace tinyformat { +class format_error: public std::runtime_error +{ +public: + format_error(const std::string &what): std::runtime_error(what) { + } +}; + //------------------------------------------------------------------------------ namespace detail { diff --git a/src/torcontrol.cpp b/src/torcontrol.cpp index 952149c06..453cb1f17 100755 --- a/src/torcontrol.cpp +++ b/src/torcontrol.cpp @@ -662,26 +662,26 @@ void TorController::reconnect_cb(evutil_socket_t fd, short what, void *arg) } /****** Thread ********/ -struct event_base *base; -boost::thread torControlThread; +static struct event_base *gBase; +static boost::thread torControlThread; static void TorControlThread() { - TorController ctrl(base, GetArg("-torcontrol", DEFAULT_TOR_CONTROL)); + TorController ctrl(gBase, GetArg("-torcontrol", DEFAULT_TOR_CONTROL)); - event_base_dispatch(base); + event_base_dispatch(gBase); } void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler) { - assert(!base); + assert(!gBase); #ifdef WIN32 evthread_use_windows_threads(); #else evthread_use_pthreads(); #endif - base = event_base_new(); - if (!base) { + gBase = event_base_new(); + if (!gBase) { LogPrintf("tor: Unable to create event_base\n"); return; } @@ -691,9 +691,9 @@ void StartTorControl(boost::thread_group& threadGroup, CScheduler& scheduler) void InterruptTorControl() { - if (base) { + if (gBase) { LogPrintf("tor: Thread interrupt\n"); - event_base_loopbreak(base); + event_base_loopbreak(gBase); } } @@ -701,13 +701,13 @@ void StopTorControl() { // timed_join() avoids the wallet not closing during a repair-restart. For a 'normal' wallet exit // it behaves for our cases exactly like the normal join() - if (base) { + if (gBase) { #if BOOST_VERSION >= 105000 torControlThread.try_join_for(boost::chrono::seconds(1)); #else torControlThread.timed_join(boost::posix_time::seconds(1)); #endif - event_base_free(base); - base = 0; + event_base_free(gBase); + gBase = 0; } } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index a14ce6aab..d3d4e8a24 100755 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -8,7 +8,7 @@ #include "clientversion.h" #include "consensus/consensus.h" #include "consensus/validation.h" -#include "instantx.h" +#include "instantsend.h" #include "validation.h" #include "policy/policy.h" #include "policy/fees.h" @@ -459,7 +459,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash); assert(dmn); newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); - if (dmn->pdmnState->pubKeyOperator != proTx.pubKeyOperator) { + if (dmn->pdmnState->pubKeyOperator.Get() != proTx.pubKeyOperator) { newit->isKeyChangeProTx = true; } } else if (tx.nType == TRANSACTION_PROVIDER_UPDATE_REVOKE) { @@ -470,7 +470,7 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, auto dmn = deterministicMNManager->GetListAtChainTip().GetMN(proTx.proTxHash); assert(dmn); newit->validForProTxKey = ::SerializeHash(dmn->pdmnState->pubKeyOperator); - if (dmn->pdmnState->pubKeyOperator != CBLSPublicKey()) { + if (dmn->pdmnState->pubKeyOperator.Get() != CBLSPublicKey()) { newit->isKeyChangeProTx = true; } } @@ -1294,7 +1294,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const { return true; // i.e. failed to find validated ProTx == conflict } // only allow one operator key change in the mempool - if (dmn->pdmnState->pubKeyOperator != proTx.pubKeyOperator) { + if (dmn->pdmnState->pubKeyOperator.Get() != proTx.pubKeyOperator) { if (hasKeyChangeInMempool(proTx.proTxHash)) { return true; } @@ -1316,7 +1316,7 @@ bool CTxMemPool::existsProviderTxConflict(const CTransaction &tx) const { return true; // i.e. failed to find validated ProTx == conflict } // only allow one operator key change in the mempool - if (dmn->pdmnState->pubKeyOperator != CBLSPublicKey()) { + if (dmn->pdmnState->pubKeyOperator.Get() != CBLSPublicKey()) { if (hasKeyChangeInMempool(proTx.proTxHash)) { return true; } diff --git a/src/ui_interface.h b/src/ui_interface.h index 98c882d63..9d5ad977e 100755 --- a/src/ui_interface.h +++ b/src/ui_interface.h @@ -111,7 +111,7 @@ class CClientUIInterface boost::signals2::signal NotifyHeaderTip; /** Masternode list has changed */ - boost::signals2::signal NotifyMasternodeListChanged; + boost::signals2::signal NotifyMasternodeListChanged; /** Additional data sync progress changed */ boost::signals2::signal NotifyAdditionalDataSyncProgressChanged; diff --git a/src/util.h b/src/util.h index 4d87ab58b..cb4c2c697 100755 --- a/src/util.h +++ b/src/util.h @@ -40,7 +40,7 @@ #ifdef ENABLE_AXE_DEBUG #define DBG( x ) x #else -#define DBG( x ) +#define DBG( x ) #endif //Axe only features @@ -103,21 +103,31 @@ std::string SafeStringFormat(const std::string& fmt, const Args&... args) { try { return tinyformat::format(fmt, args...); - } catch (std::runtime_error& e) { - std::string message = tinyformat::format("\n****TINYFORMAT ERROR****\n err=\"%s\"\n fmt=\"%s\"\n", e.what(), fmt); + } catch (std::runtime_error& fmterr) { + std::string message = tinyformat::format("\n****TINYFORMAT ERROR****\n err=\"%s\"\n fmt=\"%s\"\n", fmterr.what(), fmt); fprintf(stderr, "%s", message.c_str()); return message; } } -#define LogPrint(category, ...) do { \ - if (LogAcceptCategory((category))) { \ - LogPrintStr(SafeStringFormat(__VA_ARGS__)); \ +/** Get format string from VA_ARGS for error reporting */ +template std::string FormatStringFromLogArgs(const char *fmt, const Args&... args) { return fmt; } + +#define LogPrintf(...) do { \ + std::string _log_msg_; /* Unlikely name to avoid shadowing variables */ \ + try { \ + _log_msg_ = tfm::format(__VA_ARGS__); \ + } catch (tinyformat::format_error &e) { \ + /* Original format string will have newline so don't add one here */ \ + _log_msg_ = "Error \"" + std::string(e.what()) + "\" while formatting log message: " + FormatStringFromLogArgs(__VA_ARGS__); \ } \ + LogPrintStr(_log_msg_); \ } while(0) -#define LogPrintf(...) do { \ - LogPrintStr(SafeStringFormat(__VA_ARGS__)); \ +#define LogPrint(category, ...) do { \ + if (LogAcceptCategory((category))) { \ + LogPrintf(__VA_ARGS__); \ + } \ } while(0) template diff --git a/src/validation.cpp b/src/validation.cpp index db9974e12..9ec20a362 100755 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -38,8 +38,8 @@ #include "versionbits.h" #include "warnings.h" -#include "instantx.h" -#include "masternode-payments.h" +#include "instantsend.h" +#include "masternode/masternode-payments.h" #include "evo/specialtx.h" #include "evo/providertx.h" @@ -883,8 +883,8 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C // This transaction should only count for fee estimation if the // node is not behind, and the transaction is not dependent on any other - // transactions in the mempool. - bool validForFeeEstimation = IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx); + // transactions in the mempool. Also ignore 0-fee txes. + bool validForFeeEstimation = (nFees != 0) && IsCurrentForFeeEstimation() && pool.HasNoInputsOf(tx); // Store transaction in memory pool.addUnchecked(hash, entry, setAncestors, validForFeeEstimation); @@ -1612,6 +1612,7 @@ static DisconnectResult DisconnectBlock(const CBlock& block, CValidationState& s if (fDIP0003Active && !fHasBestBlock) { // Nodes that upgraded after DIP3 activation will have to reindex to ensure evodb consistency AbortNode("Found EvoDB inconsistency, you must reindex to continue"); + return DISCONNECT_FAILED; } bool fClean = true; @@ -1911,7 +1912,7 @@ static bool ConnectBlock(const CBlock& block, CValidationState& state, CBlockInd if (fDIP0003Active && !fHasBestBlock) { // Nodes that upgraded after DIP3 activation will have to reindex to ensure evodb consistency - AbortNode("Found EvoDB inconsistency, you must reindex to continue"); + return AbortNode(state, "Found EvoDB inconsistency, you must reindex to continue"); } } @@ -2385,6 +2386,7 @@ bool static FlushStateToDisk(CValidationState &state, FlushStateMode mode, int n } int64_t nMempoolSizeMax = GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000; int64_t cacheSize = pcoinsTip->DynamicMemoryUsage() * DB_PEAK_USAGE_FACTOR; + cacheSize += evoDb->GetMemoryUsage() * DB_PEAK_USAGE_FACTOR; int64_t nTotalSpace = nCoinCacheUsage + std::max(nMempoolSizeMax - nMempoolUsage, 0); // The cache is large and we're within 10% and 10 MiB of the limit, but we have time now (not in the middle of a block processing). bool fCacheLarge = mode == FLUSH_STATE_PERIODIC && cacheSize > std::max((9 * nTotalSpace) / 10, nTotalSpace - MAX_BLOCK_COINSDB_USAGE * 1024 * 1024); @@ -2522,6 +2524,7 @@ void static UpdateTip(CBlockIndex *pindexNew, const CChainParams& chainParams) { log(chainActive.Tip()->nChainWork.getdouble())/log(2.0), (unsigned long)chainActive.Tip()->nChainTx, DateTimeStrFormat("%Y-%m-%d %H:%M:%S", chainActive.Tip()->GetBlockTime()), GuessVerificationProgress(chainParams.TxData(), chainActive.Tip()), pcoinsTip->DynamicMemoryUsage() * (1.0 / (1<<20)), pcoinsTip->GetCacheSize()); + strMessage += strprintf(" evodb_cache=%.1fMiB", evoDb->GetMemoryUsage() * (1.0 / (1<<20))); if (!warningMessages.empty()) strMessage += strprintf(" warning='%s'", boost::algorithm::join(warningMessages, ", ")); LogPrintf("%s\n", strMessage); diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index 9605c1cf8..4d85d445e 100755 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -604,11 +604,11 @@ bool CDB::PeriodicFlush(std::string strFile) { // Don't do this if any databases are in use int nRefCount = 0; - std::map::iterator mi = bitdb.mapFileUseCount.begin(); - while (mi != bitdb.mapFileUseCount.end()) + std::map::iterator mit = bitdb.mapFileUseCount.begin(); + while (mit != bitdb.mapFileUseCount.end()) { - nRefCount += (*mi).second; - mi++; + nRefCount += (*mit).second; + mit++; } if (nRefCount == 0) diff --git a/src/wallet/rpcdump.cpp b/src/wallet/rpcdump.cpp index 17b7358ef..63a92b609 100755 --- a/src/wallet/rpcdump.cpp +++ b/src/wallet/rpcdump.cpp @@ -958,7 +958,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(redeemScript) && !pwallet->AddWatchOnly(redeemScript, timestamp)) { + if (!pwallet->AddWatchOnly(redeemScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -975,7 +975,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(redeemDestination) && !pwallet->AddWatchOnly(redeemDestination, timestamp)) { + if (!pwallet->AddWatchOnly(redeemDestination, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -1068,7 +1068,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(pubKeyScript) && !pwallet->AddWatchOnly(pubKeyScript, timestamp)) { + if (!pwallet->AddWatchOnly(pubKeyScript, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -1086,7 +1086,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(scriptRawPubKey) && !pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) { + if (!pwallet->AddWatchOnly(scriptRawPubKey, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } @@ -1160,7 +1160,7 @@ UniValue ProcessImport(CWallet * const pwallet, const UniValue& data, const int6 pwallet->MarkDirty(); - if (!pwallet->HaveWatchOnly(script) && !pwallet->AddWatchOnly(script, timestamp)) { + if (!pwallet->AddWatchOnly(script, timestamp)) { throw JSONRPCError(RPC_WALLET_ERROR, "Error adding address to wallet"); } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 0a151a6c8..5628e22d6 100755 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -10,7 +10,7 @@ #include "consensus/validation.h" #include "core_io.h" #include "init.h" -#include "instantx.h" +#include "instantsend.h" #include "net.h" #include "rpc/server.h" #include "timedata.h" @@ -20,7 +20,7 @@ #include "wallet.h" #include "walletdb.h" #include "keepass.h" -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #include "llmq/quorums_chainlocks.h" #include "llmq/quorums_instantsend.h" @@ -1903,7 +1903,7 @@ UniValue gettransaction(const JSONRPCRequest& request) " \"fee\": x.xxx, (numeric) The amount of the fee in " + CURRENCY_UNIT + ". This is negative and only available for the \n" " 'send' category of transactions.\n" " \"abandoned\": xxx (bool) 'true' if the transaction has been abandoned (inputs are respendable). Only available for the \n" - " 'send' category of transactions.\n" + " 'send' category of transactions.\n" " }\n" " ,...\n" " ],\n" @@ -2473,7 +2473,7 @@ UniValue setprivatesendrounds(const JSONRPCRequest& request) "setprivatesendrounds rounds\n" "\nSet the number of rounds for PrivateSend mixing.\n" "\nArguments:\n" - "1. rounds (numeric, required) The default number of rounds is " + std::to_string(DEFAULT_PRIVATESEND_ROUNDS) + + "1. rounds (numeric, required) The default number of rounds is " + std::to_string(DEFAULT_PRIVATESEND_ROUNDS) + " Cannot be more than " + std::to_string(MAX_PRIVATESEND_ROUNDS) + " nor less than " + std::to_string(MIN_PRIVATESEND_ROUNDS) + "\nExamples:\n" + HelpExampleCli("setprivatesendrounds", "4") diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index b96857592..7917e1ff9 100755 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -28,10 +28,10 @@ #include "ui_interface.h" #include "utilmoneystr.h" -#include "governance.h" -#include "instantx.h" +#include "governance/governance.h" +#include "instantsend.h" #include "keepass.h" -#include "privatesend-client.h" +#include "privatesend/privatesend-client.h" #include "spork.h" #include "evo/providertx.h" @@ -3481,8 +3481,6 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT if (nCoinType == ONLY_DENOMINATED) { nFeeRet += nChange; wtxNew.mapValue["DS"] = "1"; - // recheck skipped denominations during next mixing - privateSendClient.ClearSkippedDenominations(); } else { // Fill a vout to ourself @@ -3763,6 +3761,7 @@ bool CWallet::CommitTransaction(CWalletTx& wtxNew, CReserveKey& reservekey, CCon coin.BindWallet(this); NotifyTransactionChanged(this, txin.prevout.hash, CT_UPDATED); updated_hahes.insert(txin.prevout.hash); + privateSendClient.RemoveSkippedDenom(coin.tx->vout[txin.prevout.n].nValue); } } @@ -4011,7 +4010,7 @@ bool CWallet::SetDefaultKey(const CPubKey &vchPubKey) /** * Mark old keypool keys as used, - * and generate all new keys + * and generate all new keys */ bool CWallet::NewKeyPool() { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c2e882f26..91894bcdb 100755 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -20,7 +20,7 @@ #include "wallet/walletdb.h" #include "wallet/rpcwallet.h" -#include "privatesend.h" +#include "privatesend/privatesend.h" #include #include @@ -284,7 +284,7 @@ class CMerkleTx bool IsCoinBase() const { return tx->IsCoinBase(); } }; -/** +/** * A transaction with a bunch of additional info that only the owner cares about. * It includes any unrecorded transactions needed to link it back to the block chain. */ @@ -665,7 +665,7 @@ class CAccountingEntry }; -/** +/** * A CWallet is an extension of a keystore, which also maintains a set of transactions and balances, * and provides the ability to create new transactions. */ @@ -803,6 +803,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface nLastResend = 0; nTimeFirstKey = 0; fBroadcastTransactions = false; + nRelockTime = 0; fAnonymizableTallyCached = false; fAnonymizableTallyCachedNonDenom = false; vecAnonymizableTallyCached.clear(); @@ -936,7 +937,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface void GetKeyBirthTimes(std::map &mapKeyBirth) const; unsigned int ComputeTimeSmart(const CWalletTx& wtx) const; - /** + /** * Increment the next transaction order id * @return next transaction order id */ @@ -1074,7 +1075,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface LOCK(cs_wallet); mapRequestCount[hash] = 0; }; - + unsigned int GetKeyPoolSize() { AssertLockHeld(cs_wallet); // set{Ex,In}ternalKeyPool @@ -1100,8 +1101,8 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface //! Verify the wallet database and perform salvage if required static bool Verify(); - - /** + + /** * Address book entry changed. * @note called with lock cs_wallet held. */ @@ -1110,7 +1111,7 @@ class CWallet : public CCryptoKeyStore, public CValidationInterface const std::string &purpose, ChangeType status)> NotifyAddressBookChanged; - /** + /** * Wallet transaction added, removed or updated. * @note called with lock cs_wallet held. */ @@ -1207,7 +1208,7 @@ class CReserveKey : public CReserveScript }; -/** +/** * Account information. * Stored in wallet with key "acc"+string account name. */ diff --git a/src/zmq/zmqconfig.h b/src/zmq/zmqconfig.h index a065fc7b2..59f6b41f3 100755 --- a/src/zmq/zmqconfig.h +++ b/src/zmq/zmqconfig.h @@ -19,10 +19,10 @@ #include "primitives/block.h" #include "primitives/transaction.h" -#include "governance-object.h" -#include "governance-vote.h" +#include "governance/governance-object.h" +#include "governance/governance-vote.h" -#include "instantx.h" +#include "instantsend.h" void zmqError(const char *str); diff --git a/test/README.md b/test/README.md new file mode 100644 index 000000000..e4d511413 --- /dev/null +++ b/test/README.md @@ -0,0 +1,97 @@ +This directory contains integration tests that test axed and its +utilities in their entirety. It does not contain unit tests, which +can be found in [/src/test](/src/test), [/src/wallet/test](/src/wallet/test), +etc. + +There are currently two sets of tests in this directory: + +- [functional](/test/functional) which test the functionality of +axed and axe-qt by interacting with them through the RPC and P2P +interfaces. +- [util](test/util) which tests the axe utilities, currently only +axe-tx. + +The util tests are run as part of `make check` target. The functional +tests are run by the travis continuous build process whenever a pull +request is opened. Both sets of tests can also be run locally. + +Functional Test dependencies +============================ +The ZMQ functional test requires a python ZMQ library. To install it: + +- on Unix, run `sudo apt-get install python3-zmq` +- on mac OS, run `pip3 install pyzmq` + +Running tests locally +===================== + +Functional tests +---------------- + +You can run any single test by calling + + test/functional/test_runner.py + +Or you can run any combination of tests by calling + + test/functional/test_runner.py ... + +Run the regression test suite with + + test/functional/test_runner.py + +Run all possible tests with + + test/functional/test_runner.py --extended + +By default, tests will be run in parallel. To specify how many jobs to run, +append `--jobs=n` (default n=4). + +If you want to create a basic coverage report for the RPC test suite, append `--coverage`. + +Possible options, which apply to each individual test run: + +``` + -h, --help show this help message and exit + --nocleanup Leave axeds and test.* datadir on exit or error + --noshutdown Don't stop axeds after the test execution + --srcdir=SRCDIR Source directory containing axed/axe-cli + (default: ../../src) + --tmpdir=TMPDIR Root directory for datadirs + --tracerpc Print out all RPC calls as they are made + --coveragedir=COVERAGEDIR + Write tested RPC commands into this directory +``` + +If you set the environment variable `PYTHON_DEBUG=1` you will get some debug +output (example: `PYTHON_DEBUG=1 test/functional/test_runner.py wallet`). + +A 200-block -regtest blockchain and wallets for four nodes +is created the first time a regression test is run and +is stored in the cache/ directory. Each node has 25 mature +blocks (25*500=12500 AXE) in its wallet. + +After the first run, the cache/ blockchain and wallets are +copied into a temporary directory and used as the initial +test state. + +If you get into a bad state, you should be able +to recover with: + +```bash +rm -rf cache +killall axed +``` + +Util tests +---------- + +Util tests can be run locally by running `test/util/bitcoin-util-test.py`. +Use the `-v` option for verbose output. + +Writing functional tests +======================== + +You are encouraged to write functional tests for new or existing features. +Further information about the functional test framework and individual +tests is found in [test/functional](/test/functional). diff --git a/qa/rpc-tests/.gitignore b/test/functional/.gitignore old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/.gitignore rename to test/functional/.gitignore diff --git a/qa/rpc-tests/README.md b/test/functional/README.md old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/README.md rename to test/functional/README.md diff --git a/qa/rpc-tests/abandonconflict.py b/test/functional/abandonconflict.py similarity index 100% rename from qa/rpc-tests/abandonconflict.py rename to test/functional/abandonconflict.py diff --git a/qa/rpc-tests/addressindex.py b/test/functional/addressindex.py similarity index 100% rename from qa/rpc-tests/addressindex.py rename to test/functional/addressindex.py diff --git a/qa/rpc-tests/assumevalid.py b/test/functional/assumevalid.py similarity index 100% rename from qa/rpc-tests/assumevalid.py rename to test/functional/assumevalid.py diff --git a/qa/rpc-tests/autois-mempool.py b/test/functional/autois-mempool.py similarity index 100% rename from qa/rpc-tests/autois-mempool.py rename to test/functional/autois-mempool.py diff --git a/qa/rpc-tests/bip65-cltv-p2p.py b/test/functional/bip65-cltv-p2p.py similarity index 100% rename from qa/rpc-tests/bip65-cltv-p2p.py rename to test/functional/bip65-cltv-p2p.py diff --git a/qa/rpc-tests/bip65-cltv.py b/test/functional/bip65-cltv.py similarity index 92% rename from qa/rpc-tests/bip65-cltv.py rename to test/functional/bip65-cltv.py index c9d02a98f..7f13bb995 100755 --- a/qa/rpc-tests/bip65-cltv.py +++ b/test/functional/bip65-cltv.py @@ -69,12 +69,8 @@ def run_test(self): if (self.nodes[0].getblockcount() != cnt + 1051): raise AssertionError("Failed to mine a version=4 block") - # Mine 1 old-version blocks - try: - self.nodes[1].generate(1) - raise AssertionError("Succeeded to mine a version=3 block after 950 version=4 blocks") - except JSONRPCException: - pass + # Mine 1 old-version blocks. This should fail + assert_raises_jsonrpc(-1,"CreateNewBlock: TestBlockValidity failed: bad-version(0x00000003)", self.nodes[1].generate, 1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1051): raise AssertionError("Accepted a version=3 block after 950 version=4 blocks") diff --git a/qa/rpc-tests/bip68-112-113-p2p.py b/test/functional/bip68-112-113-p2p.py similarity index 100% rename from qa/rpc-tests/bip68-112-113-p2p.py rename to test/functional/bip68-112-113-p2p.py diff --git a/qa/rpc-tests/bip68-sequence.py b/test/functional/bip68-sequence.py similarity index 92% rename from qa/rpc-tests/bip68-sequence.py rename to test/functional/bip68-sequence.py index c6d11ac9a..5a628a2fa 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/test/functional/bip68-sequence.py @@ -90,12 +90,7 @@ def test_disable_flag(self): tx2.vout = [CTxOut(int(value-self.relayfee*COIN), CScript([b'a']))] tx2.rehash() - try: - self.nodes[0].sendrawtransaction(ToHex(tx2)) - except JSONRPCException as exp: - assert_equal(exp.error["message"], NOT_FINAL_ERROR) - else: - assert(False) + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx2)) # Setting the version back down to 1 should disable the sequence lock, # so this should be accepted. @@ -190,14 +185,12 @@ def test_sequence_lock_confirmed_inputs(self): tx.vout.append(CTxOut(int(value-self.relayfee*tx_size*COIN/1000), CScript([b'a']))) rawtx = self.nodes[0].signrawtransaction(ToHex(tx))["hex"] - try: - self.nodes[0].sendrawtransaction(rawtx) - except JSONRPCException as exp: - assert(not should_pass and using_sequence_locks) - assert_equal(exp.error["message"], NOT_FINAL_ERROR) + if (using_sequence_locks and not should_pass): + # This transaction should be rejected + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, rawtx) else: - assert(should_pass or not using_sequence_locks) - # Recalculate utxos if we successfully sent the transaction + # This raw transaction should be accepted + self.nodes[0].sendrawtransaction(rawtx) utxos = self.nodes[0].listunspent() # Test that sequence locks on unconfirmed inputs must have nSequence @@ -239,14 +232,13 @@ def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock): tx.vout = [CTxOut(int(orig_tx.vout[0].nValue - relayfee*COIN), CScript([b'a']))] tx.rehash() - try: - node.sendrawtransaction(ToHex(tx)) - except JSONRPCException as exp: - assert_equal(exp.error["message"], NOT_FINAL_ERROR) - assert(orig_tx.hash in node.getrawmempool()) + if (orig_tx.hash in node.getrawmempool()): + # sendrawtransaction should fail if the tx is in the mempool + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, node.sendrawtransaction, ToHex(tx)) else: - # orig_tx must not be in mempool - assert(orig_tx.hash not in node.getrawmempool()) + # sendrawtransaction should succeed if the tx is not in the mempool + node.sendrawtransaction(ToHex(tx)) + return tx test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=True) @@ -295,12 +287,7 @@ def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock): tx5.vout[0].nValue += int(utxos[0]["amount"]*COIN) raw_tx5 = self.nodes[0].signrawtransaction(ToHex(tx5))["hex"] - try: - self.nodes[0].sendrawtransaction(raw_tx5) - except JSONRPCException as exp: - assert_equal(exp.error["message"], NOT_FINAL_ERROR) - else: - assert(False) + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, raw_tx5) # Test mempool-BIP68 consistency after reorg # @@ -373,12 +360,7 @@ def test_bip68_not_consensus(self): tx3.vout = [CTxOut(int(tx2.vout[0].nValue - self.relayfee*COIN), CScript([b'a']))] tx3.rehash() - try: - self.nodes[0].sendrawtransaction(ToHex(tx3)) - except JSONRPCException as exp: - assert_equal(exp.error["message"], NOT_FINAL_ERROR) - else: - assert(False) + assert_raises_jsonrpc(-26, NOT_FINAL_ERROR, self.nodes[0].sendrawtransaction, ToHex(tx3)) # make a block that violates bip68; ensure that the tip updates tip = int(self.nodes[0].getbestblockhash(), 16) diff --git a/qa/rpc-tests/bip9-softforks.py b/test/functional/bip9-softforks.py similarity index 100% rename from qa/rpc-tests/bip9-softforks.py rename to test/functional/bip9-softforks.py diff --git a/qa/rpc-tests/bipdersig-p2p.py b/test/functional/bipdersig-p2p.py similarity index 100% rename from qa/rpc-tests/bipdersig-p2p.py rename to test/functional/bipdersig-p2p.py diff --git a/qa/rpc-tests/bipdersig.py b/test/functional/bipdersig.py similarity index 92% rename from qa/rpc-tests/bipdersig.py rename to test/functional/bipdersig.py index fa54bc274..371cc41bb 100755 --- a/qa/rpc-tests/bipdersig.py +++ b/test/functional/bipdersig.py @@ -68,12 +68,8 @@ def run_test(self): if (self.nodes[0].getblockcount() != cnt + 1051): raise AssertionError("Failed to mine a version=3 block") - # Mine 1 old-version blocks - try: - self.nodes[1].generate(1) - raise AssertionError("Succeeded to mine a version=2 block after 950 version=3 blocks") - except JSONRPCException: - pass + # Mine 1 old-version blocks. This should fail + assert_raises_jsonrpc(-1, "CreateNewBlock: TestBlockValidity failed: bad-version(0x00000002)", self.nodes[1].generate, 1) self.sync_all() if (self.nodes[0].getblockcount() != cnt + 1051): raise AssertionError("Accepted a version=2 block after 950 version=3 blocks") diff --git a/qa/rpc-tests/blockchain.py b/test/functional/blockchain.py similarity index 95% rename from qa/rpc-tests/blockchain.py rename to test/functional/blockchain.py index 4896468e0..3472841c1 100755 --- a/qa/rpc-tests/blockchain.py +++ b/test/functional/blockchain.py @@ -14,10 +14,9 @@ from decimal import Decimal from test_framework.test_framework import BitcoinTestFramework -from test_framework.authproxy import JSONRPCException from test_framework.util import ( assert_equal, - assert_raises, + assert_raises_jsonrpc, assert_is_hex_string, assert_is_hash_string, start_nodes, @@ -82,8 +81,7 @@ def _test_gettxoutsetinfo(self): def _test_getblockheader(self): node = self.nodes[0] - assert_raises( - JSONRPCException, lambda: node.getblockheader('nonsense')) + assert_raises_jsonrpc(-5, "Block not found", node.getblockheader, "nonsense") besthash = node.getbestblockhash() secondbesthash = node.getblockhash(199) diff --git a/test/functional/combine_logs.py b/test/functional/combine_logs.py new file mode 100755 index 000000000..ec70e2b4e --- /dev/null +++ b/test/functional/combine_logs.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python3 +"""Combine logs from multiple bitcoin nodes as well as the test_framework log. + +This streams the combined log output to stdout. Use combine_logs.py > outputfile +to write to an outputfile.""" + +import argparse +from collections import defaultdict, namedtuple +import heapq +import itertools +import os +import re +import sys + +# Matches on the date format at the start of the log event +TIMESTAMP_PATTERN = re.compile(r"^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{6}") + +LogEvent = namedtuple('LogEvent', ['timestamp', 'source', 'event']) + +def main(): + """Main function. Parses args, reads the log files and renders them as text or html.""" + + parser = argparse.ArgumentParser(usage='%(prog)s [options] ', description=__doc__) + parser.add_argument('-c', '--color', dest='color', action='store_true', help='outputs the combined log with events colored by source (requires posix terminal colors. Use less -r for viewing)') + parser.add_argument('--html', dest='html', action='store_true', help='outputs the combined log as html. Requires jinja2. pip install jinja2') + args, unknown_args = parser.parse_known_args() + + if args.color and os.name != 'posix': + print("Color output requires posix terminal colors.") + sys.exit(1) + + if args.html and args.color: + print("Only one out of --color or --html should be specified") + sys.exit(1) + + # There should only be one unknown argument - the path of the temporary test directory + if len(unknown_args) != 1: + print("Unexpected arguments" + str(unknown_args)) + sys.exit(1) + + log_events = read_logs(unknown_args[0]) + + print_logs(log_events, color=args.color, html=args.html) + +def read_logs(tmp_dir): + """Reads log files. + + Delegates to generator function get_log_events() to provide individual log events + for each of the input log files.""" + + files = [("test", "%s/test_framework.log" % tmp_dir)] + for i in itertools.count(): + logfile = "{}/node{}/regtest/debug.log".format(tmp_dir, i) + if not os.path.isfile(logfile): + break + files.append(("node%d" % i, logfile)) + + return heapq.merge(*[get_log_events(source, f) for source, f in files]) + +def get_log_events(source, logfile): + """Generator function that returns individual log events. + + Log events may be split over multiple lines. We use the timestamp + regex match as the marker for a new log event.""" + try: + with open(logfile, 'r') as infile: + event = '' + timestamp = '' + for line in infile: + # skip blank lines + if line == '\n': + continue + # if this line has a timestamp, it's the start of a new log event. + time_match = TIMESTAMP_PATTERN.match(line) + if time_match: + if event: + yield LogEvent(timestamp=timestamp, source=source, event=event.rstrip()) + event = line + timestamp = time_match.group() + # if it doesn't have a timestamp, it's a continuation line of the previous log. + else: + event += "\n" + line + # Flush the final event + yield LogEvent(timestamp=timestamp, source=source, event=event.rstrip()) + except FileNotFoundError: + print("File %s could not be opened. Continuing without it." % logfile, file=sys.stderr) + +def print_logs(log_events, color=False, html=False): + """Renders the iterator of log events into text or html.""" + if not html: + colors = defaultdict(lambda: '') + if color: + colors["test"] = "\033[0;36m" # CYAN + colors["node0"] = "\033[0;34m" # BLUE + colors["node1"] = "\033[0;32m" # GREEN + colors["node2"] = "\033[0;31m" # RED + colors["node3"] = "\033[0;33m" # YELLOW + colors["reset"] = "\033[0m" # Reset font color + + for event in log_events: + print("{0} {1: <5} {2} {3}".format(colors[event.source.rstrip()], event.source, event.event, colors["reset"])) + + else: + try: + import jinja2 + except ImportError: + print("jinja2 not found. Try `pip install jinja2`") + sys.exit(1) + print(jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(os.path.abspath(__file__)))) + .get_template('combined_log_template.html') + .render(title="Combined Logs from testcase", log_events=[event._asdict() for event in log_events])) + +if __name__ == '__main__': + main() diff --git a/test/functional/combined_log_template.html b/test/functional/combined_log_template.html new file mode 100644 index 000000000..c0b854b08 --- /dev/null +++ b/test/functional/combined_log_template.html @@ -0,0 +1,40 @@ + + + {{ title }} + + + +
    +{% for event in log_events %} +
  • {{ event.source }} {{ event.timestamp }} {{event.event}}
  • +{% endfor %} +
+ + diff --git a/qa/pull-tester/tests_config.ini.in b/test/functional/config.ini.in old mode 100755 new mode 100644 similarity index 95% rename from qa/pull-tester/tests_config.ini.in rename to test/functional/config.ini.in index e3e457d0b..29586c555 --- a/qa/pull-tester/tests_config.ini.in +++ b/test/functional/config.ini.in @@ -3,7 +3,7 @@ # file COPYING or http://www.opensource.org/licenses/mit-license.php. # These environment variables are set by the build process and read by -# rpc-tests.py +# test/functional/test_runner.py [environment] SRCDIR=@abs_top_srcdir@ diff --git a/qa/rpc-tests/create_cache.py b/test/functional/create_cache.py similarity index 89% rename from qa/rpc-tests/create_cache.py rename to test/functional/create_cache.py index 13eac92bb..39c4c0f47 100755 --- a/qa/rpc-tests/create_cache.py +++ b/test/functional/create_cache.py @@ -5,7 +5,7 @@ """Create a blockchain cache. Creating a cache of the blockchain speeds up test execution when running -multiple qa tests. This helper script is executed by rpc-tests when multiple +multiple functional tests. This helper script is executed by test_runner when multiple tests are being run in parallel. """ diff --git a/qa/rpc-tests/decodescript.py b/test/functional/decodescript.py similarity index 100% rename from qa/rpc-tests/decodescript.py rename to test/functional/decodescript.py diff --git a/qa/rpc-tests/dip3-deterministicmns.py b/test/functional/dip3-deterministicmns.py similarity index 100% rename from qa/rpc-tests/dip3-deterministicmns.py rename to test/functional/dip3-deterministicmns.py diff --git a/qa/rpc-tests/dip4-coinbasemerkleroots.py b/test/functional/dip4-coinbasemerkleroots.py similarity index 100% rename from qa/rpc-tests/dip4-coinbasemerkleroots.py rename to test/functional/dip4-coinbasemerkleroots.py diff --git a/qa/rpc-tests/disablewallet.py b/test/functional/disablewallet.py similarity index 65% rename from qa/rpc-tests/disablewallet.py rename to test/functional/disablewallet.py index 633e70125..58bf373f0 100755 --- a/qa/rpc-tests/disablewallet.py +++ b/test/functional/disablewallet.py @@ -31,19 +31,10 @@ def run_test (self): x = self.nodes[0].validateaddress('ycwedq2f3sz2Yf9JqZsBCQPxp18WU3Hp4J') assert(x['isvalid'] == True) - # Checking mining to an address without a wallet - try: - self.nodes[0].generatetoaddress(1, 'ycwedq2f3sz2Yf9JqZsBCQPxp18WU3Hp4J') - except JSONRPCException as e: - assert("Invalid address" not in e.error['message']) - assert("ProcessNewBlock, block not accepted" not in e.error['message']) - assert("Couldn't create new block" not in e.error['message']) - - try: - self.nodes[0].generatetoaddress(1, '7TSBtVu959hGEGPKyHjJz9k55RpWrPffXz') - raise AssertionError("Must not mine to invalid address!") - except JSONRPCException as e: - assert("Invalid address" in e.error['message']) + # Checking mining to an address without a wallet. Generating to a valid address should succeed + # but generating to an invalid address will fail. + self.nodes[0].generatetoaddress(1, 'ycwedq2f3sz2Yf9JqZsBCQPxp18WU3Hp4J') + assert_raises_jsonrpc(-5, "Invalid address", self.nodes[0].generatetoaddress, 1, '7TSBtVu959hGEGPKyHjJz9k55RpWrPffXz') if __name__ == '__main__': DisableWalletTest ().main () diff --git a/qa/rpc-tests/forknotify.py b/test/functional/forknotify.py similarity index 100% rename from qa/rpc-tests/forknotify.py rename to test/functional/forknotify.py diff --git a/qa/rpc-tests/fundrawtransaction-hd.py b/test/functional/fundrawtransaction-hd.py similarity index 100% rename from qa/rpc-tests/fundrawtransaction-hd.py rename to test/functional/fundrawtransaction-hd.py diff --git a/qa/rpc-tests/fundrawtransaction.py b/test/functional/fundrawtransaction.py similarity index 100% rename from qa/rpc-tests/fundrawtransaction.py rename to test/functional/fundrawtransaction.py diff --git a/qa/rpc-tests/getblocktemplate_longpoll.py b/test/functional/getblocktemplate_longpoll.py similarity index 100% rename from qa/rpc-tests/getblocktemplate_longpoll.py rename to test/functional/getblocktemplate_longpoll.py diff --git a/qa/rpc-tests/getblocktemplate_proposals.py b/test/functional/getblocktemplate_proposals.py similarity index 96% rename from qa/rpc-tests/getblocktemplate_proposals.py rename to test/functional/getblocktemplate_proposals.py index 8442c545d..057b51afe 100755 --- a/qa/rpc-tests/getblocktemplate_proposals.py +++ b/test/functional/getblocktemplate_proposals.py @@ -106,7 +106,7 @@ def run_test(self): # Test 3: Truncated final tx lastbyte = txlist[-1].pop() - assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a') + assert_raises_jsonrpc(-22, "Block decode failed", assert_template, node, tmpl, txlist, 'n/a') txlist[-1].append(lastbyte) # Test 4: Add an invalid tx to the end (duplicate of gen tx) @@ -127,7 +127,7 @@ def run_test(self): # Test 7: Bad tx count txlist.append(b'') - assert_raises(JSONRPCException, assert_template, node, tmpl, txlist, 'n/a') + assert_raises_jsonrpc(-22, 'Block decode failed', assert_template, node, tmpl, txlist, 'n/a') txlist.pop() # Test 8: Bad bits diff --git a/qa/rpc-tests/getchaintips.py b/test/functional/getchaintips.py similarity index 100% rename from qa/rpc-tests/getchaintips.py rename to test/functional/getchaintips.py diff --git a/qa/rpc-tests/httpbasics.py b/test/functional/httpbasics.py similarity index 100% rename from qa/rpc-tests/httpbasics.py rename to test/functional/httpbasics.py diff --git a/qa/rpc-tests/import-rescan.py b/test/functional/import-rescan.py similarity index 100% rename from qa/rpc-tests/import-rescan.py rename to test/functional/import-rescan.py diff --git a/qa/rpc-tests/importmulti.py b/test/functional/importmulti.py similarity index 96% rename from qa/rpc-tests/importmulti.py rename to test/functional/importmulti.py index 298b6e9b8..aa03c6780 100755 --- a/qa/rpc-tests/importmulti.py +++ b/test/functional/importmulti.py @@ -314,6 +314,7 @@ def run_test (self): self.nodes[1].generate(100) transactionid = self.nodes[1].sendtoaddress(multi_sig_script['address'], 10.00) self.nodes[1].generate(1) + timestamp = self.nodes[1].getblock(self.nodes[1].getbestblockhash())['mediantime'] transaction = self.nodes[1].gettransaction(transactionid) self.log.info("Should import a p2sh with respective redeem script and private keys") @@ -409,6 +410,24 @@ def run_test (self): assert_equal(address_assert['ismine'], False) assert_equal('timestamp' in address_assert, False) + + # Importing existing watch only address with new timestamp should replace saved timestamp. + assert_greater_than(timestamp, watchonly_timestamp) + self.log.info("Should replace previously saved watch only timestamp.") + result = self.nodes[1].importmulti([{ + "scriptPubKey": { + "address": watchonly_address, + }, + "timestamp": "now", + }]) + assert_equal(result[0]['success'], True) + address_assert = self.nodes[1].validateaddress(watchonly_address) + assert_equal(address_assert['iswatchonly'], True) + assert_equal(address_assert['ismine'], False) + assert_equal(address_assert['timestamp'], timestamp) + watchonly_timestamp = timestamp + + # restart nodes to check for proper serialization/deserialization of watch only address stop_nodes(self.nodes) self.nodes = start_nodes(2, self.options.tmpdir) diff --git a/qa/rpc-tests/importprunedfunds.py b/test/functional/importprunedfunds.py similarity index 100% rename from qa/rpc-tests/importprunedfunds.py rename to test/functional/importprunedfunds.py diff --git a/qa/rpc-tests/invalidateblock.py b/test/functional/invalidateblock.py similarity index 100% rename from qa/rpc-tests/invalidateblock.py rename to test/functional/invalidateblock.py diff --git a/qa/rpc-tests/invalidblockrequest.py b/test/functional/invalidblockrequest.py similarity index 100% rename from qa/rpc-tests/invalidblockrequest.py rename to test/functional/invalidblockrequest.py diff --git a/qa/rpc-tests/invalidtxrequest.py b/test/functional/invalidtxrequest.py similarity index 100% rename from qa/rpc-tests/invalidtxrequest.py rename to test/functional/invalidtxrequest.py diff --git a/qa/rpc-tests/keypool-hd.py b/test/functional/keypool-hd.py similarity index 100% rename from qa/rpc-tests/keypool-hd.py rename to test/functional/keypool-hd.py diff --git a/qa/rpc-tests/keypool.py b/test/functional/keypool.py similarity index 74% rename from qa/rpc-tests/keypool.py rename to test/functional/keypool.py index b4caf79e2..2fdc39dbf 100755 --- a/qa/rpc-tests/keypool.py +++ b/test/functional/keypool.py @@ -25,11 +25,7 @@ def run_test(self): # Keep creating keys addr = nodes[0].getnewaddress() - try: - addr = nodes[0].getnewaddress() - raise AssertionError('Keypool should be exhausted after one address') - except JSONRPCException as e: - assert(e.error['code']==-12) + assert_raises_jsonrpc(-12, "Error: Keypool ran out, please call keypoolrefill first", nodes[0].getnewaddress) # put three new keys in the keypool nodes[0].walletpassphrase('test', 12000) @@ -44,11 +40,7 @@ def run_test(self): # assert that three unique addresses were returned assert(len(addr) == 3) # the next one should fail - try: - addr = nodes[0].getrawchangeaddress() - raise AssertionError('Keypool should be exhausted after three addresses') - except JSONRPCException as e: - assert(e.error['code']==-12) + assert_raises_jsonrpc(-12, "Keypool ran out", nodes[0].getrawchangeaddress) # refill keypool with three new addresses nodes[0].walletpassphrase('test', 1) @@ -61,11 +53,7 @@ def run_test(self): nodes[0].generate(1) nodes[0].generate(1) nodes[0].generate(1) - try: - nodes[0].generate(1) - raise AssertionError('Keypool should be exhausted after three addesses') - except JSONRPCException as e: - assert(e.error['code']==-12) + assert_raises_jsonrpc(-12, "Keypool ran out", nodes[0].generate, 1) def setup_network(self): self.nodes = start_nodes(1, self.options.tmpdir, [['-usehd=0']]) diff --git a/qa/rpc-tests/listsinceblock.py b/test/functional/listsinceblock.py similarity index 100% rename from qa/rpc-tests/listsinceblock.py rename to test/functional/listsinceblock.py diff --git a/qa/rpc-tests/listtransactions.py b/test/functional/listtransactions.py similarity index 100% rename from qa/rpc-tests/listtransactions.py rename to test/functional/listtransactions.py diff --git a/qa/rpc-tests/llmq-chainlocks.py b/test/functional/llmq-chainlocks.py similarity index 100% rename from qa/rpc-tests/llmq-chainlocks.py rename to test/functional/llmq-chainlocks.py diff --git a/qa/rpc-tests/llmq-dkgerrors.py b/test/functional/llmq-dkgerrors.py similarity index 100% rename from qa/rpc-tests/llmq-dkgerrors.py rename to test/functional/llmq-dkgerrors.py diff --git a/qa/rpc-tests/llmq-is-cl-conflicts.py b/test/functional/llmq-is-cl-conflicts.py similarity index 100% rename from qa/rpc-tests/llmq-is-cl-conflicts.py rename to test/functional/llmq-is-cl-conflicts.py diff --git a/qa/rpc-tests/llmq-signing.py b/test/functional/llmq-signing.py similarity index 100% rename from qa/rpc-tests/llmq-signing.py rename to test/functional/llmq-signing.py diff --git a/qa/rpc-tests/llmq-simplepose.py b/test/functional/llmq-simplepose.py similarity index 100% rename from qa/rpc-tests/llmq-simplepose.py rename to test/functional/llmq-simplepose.py diff --git a/qa/rpc-tests/maxblocksinflight.py b/test/functional/maxblocksinflight.py similarity index 100% rename from qa/rpc-tests/maxblocksinflight.py rename to test/functional/maxblocksinflight.py diff --git a/qa/rpc-tests/maxuploadtarget.py b/test/functional/maxuploadtarget.py similarity index 100% rename from qa/rpc-tests/maxuploadtarget.py rename to test/functional/maxuploadtarget.py diff --git a/qa/rpc-tests/mempool_limit.py b/test/functional/mempool_limit.py similarity index 100% rename from qa/rpc-tests/mempool_limit.py rename to test/functional/mempool_limit.py diff --git a/qa/rpc-tests/mempool_packages.py b/test/functional/mempool_packages.py similarity index 90% rename from qa/rpc-tests/mempool_packages.py rename to test/functional/mempool_packages.py index d475aabdf..feec8a7fd 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/test/functional/mempool_packages.py @@ -124,10 +124,7 @@ def run_test(self): assert_equal(mempool[x]['descendantfees'], descendant_fees * COIN + 1000) # Adding one more transaction on to the chain should fail. - try: - self.chain_transaction(self.nodes[0], txid, vout, value, fee, 1) - except JSONRPCException as e: - self.log.info("too-long-ancestor-chain successfully rejected") + assert_raises_jsonrpc(-26, "too-long-mempool-chain", self.chain_transaction, self.nodes[0], txid, vout, value, fee, 1) # Check that prioritising a tx before it's added to the mempool works # First clear the mempool by mining a block. @@ -167,19 +164,19 @@ def run_test(self): for i in range(10): transaction_package.append({'txid': txid, 'vout': i, 'amount': sent_value}) - for i in range(MAX_DESCENDANTS): + # Sign and send up to MAX_DESCENDANT transactions chained off the parent tx + for i in range(MAX_DESCENDANTS - 1): utxo = transaction_package.pop(0) - try: - (txid, sent_value) = self.chain_transaction(self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) - for j in range(10): - transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) - if i == MAX_DESCENDANTS - 2: - mempool = self.nodes[0].getrawmempool(True) - assert_equal(mempool[parent_transaction]['descendantcount'], MAX_DESCENDANTS) - except JSONRPCException as e: - self.log.info(e.error['message']) - assert_equal(i, MAX_DESCENDANTS - 1) - self.log.info("tx that would create too large descendant package successfully rejected") + (txid, sent_value) = self.chain_transaction(self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) + for j in range(10): + transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) + + mempool = self.nodes[0].getrawmempool(True) + assert_equal(mempool[parent_transaction]['descendantcount'], MAX_DESCENDANTS) + + # Sending one more chained transaction will fail + utxo = transaction_package.pop(0) + assert_raises_jsonrpc(-26, "too-long-mempool-chain", self.chain_transaction, self.nodes[0], utxo['txid'], utxo['vout'], utxo['amount'], fee, 10) # TODO: check that node1's mempool is as expected diff --git a/qa/rpc-tests/mempool_reorg.py b/test/functional/mempool_reorg.py similarity index 83% rename from qa/rpc-tests/mempool_reorg.py rename to test/functional/mempool_reorg.py index 9b64610d6..07992e838 100755 --- a/qa/rpc-tests/mempool_reorg.py +++ b/test/functional/mempool_reorg.py @@ -30,9 +30,10 @@ def setup_network(self): self.sync_all() def run_test(self): - start_count = self.nodes[0].getblockcount() + # Start with a 200 block chain + assert_equal(self.nodes[0].getblockcount(), 200) - # Mine three blocks. After this, nodes[0] blocks + # Mine four blocks. After this, nodes[0] blocks # 101, 102, and 103 are spend-able. new_blocks = self.nodes[1].generate(4) self.sync_all() @@ -52,19 +53,21 @@ def run_test(self): spend_102_raw = create_tx(self.nodes[0], coinbase_txids[2], node0_address, 499.9) spend_103_raw = create_tx(self.nodes[0], coinbase_txids[3], node0_address, 499.9) - # Create a block-height-locked transaction which will be invalid after reorg + # Create a transaction which is time-locked to two blocks in the future timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 499.9}) # Set the time lock timelock_tx = timelock_tx.replace("ffffffff", "11111191", 1) timelock_tx = timelock_tx[:-8] + hex(self.nodes[0].getblockcount() + 2)[2:] + "000000" timelock_tx = self.nodes[0].signrawtransaction(timelock_tx)["hex"] - assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) + # This will raise an exception because the timelock transaction is too immature to spend + assert_raises_jsonrpc(-26, "non-final", self.nodes[0].sendrawtransaction, timelock_tx) # Broadcast and mine spend_102 and 103: spend_102_id = self.nodes[0].sendrawtransaction(spend_102_raw) spend_103_id = self.nodes[0].sendrawtransaction(spend_103_raw) self.nodes[0].generate(1) - assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, timelock_tx) + # Time-locked transaction is still too immature to spend + assert_raises_jsonrpc(-26,'non-final', self.nodes[0].sendrawtransaction, timelock_tx) # Create 102_1 and 103_1: spend_102_1_raw = create_tx(self.nodes[0], spend_102_id, node1_address, 499.8) @@ -73,6 +76,7 @@ def run_test(self): # Broadcast and mine 103_1: spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw) last_block = self.nodes[0].generate(1) + # Time-locked transaction can now be spent timelock_tx_id = self.nodes[0].sendrawtransaction(timelock_tx) # ... now put spend_101 and spend_102_1 in memory pools: @@ -85,6 +89,8 @@ def run_test(self): for node in self.nodes: node.invalidateblock(last_block[0]) + # Time-locked transaction is now too immature and has been removed from the mempool + # spend_103_1 has been re-orged out of the chain and is back in the mempool assert_equal(set(self.nodes[0].getrawmempool()), {spend_101_id, spend_102_1_id, spend_103_1_id}) # Use invalidateblock to re-org back and make all those coinbase spends diff --git a/qa/rpc-tests/mempool_resurrect_test.py b/test/functional/mempool_resurrect_test.py similarity index 100% rename from qa/rpc-tests/mempool_resurrect_test.py rename to test/functional/mempool_resurrect_test.py diff --git a/qa/rpc-tests/mempool_spendcoinbase.py b/test/functional/mempool_spendcoinbase.py similarity index 95% rename from qa/rpc-tests/mempool_spendcoinbase.py rename to test/functional/mempool_spendcoinbase.py index 88c4a44cc..1dbf8ae25 100755 --- a/qa/rpc-tests/mempool_spendcoinbase.py +++ b/test/functional/mempool_spendcoinbase.py @@ -45,7 +45,7 @@ def run_test(self): spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0]) # coinbase at height 102 should be too immature to spend - assert_raises(JSONRPCException, self.nodes[0].sendrawtransaction, spends_raw[1]) + assert_raises_jsonrpc(-26,"bad-txns-premature-spend-of-coinbase", self.nodes[0].sendrawtransaction, spends_raw[1]) # mempool should have just spend_101: assert_equal(self.nodes[0].getrawmempool(), [ spend_101_id ]) diff --git a/qa/rpc-tests/merkle_blocks.py b/test/functional/merkle_blocks.py similarity index 100% rename from qa/rpc-tests/merkle_blocks.py rename to test/functional/merkle_blocks.py diff --git a/qa/rpc-tests/multi_rpc.py b/test/functional/multi_rpc.py similarity index 100% rename from qa/rpc-tests/multi_rpc.py rename to test/functional/multi_rpc.py diff --git a/qa/rpc-tests/multikeysporks.py b/test/functional/multikeysporks.py similarity index 100% rename from qa/rpc-tests/multikeysporks.py rename to test/functional/multikeysporks.py diff --git a/qa/rpc-tests/nodehandling.py b/test/functional/nodehandling.py similarity index 100% rename from qa/rpc-tests/nodehandling.py rename to test/functional/nodehandling.py diff --git a/qa/rpc-tests/nulldummy.py b/test/functional/nulldummy.py similarity index 87% rename from qa/rpc-tests/nulldummy.py rename to test/functional/nulldummy.py index 22d1f63e0..3ad8a3235 100755 --- a/qa/rpc-tests/nulldummy.py +++ b/test/functional/nulldummy.py @@ -63,29 +63,29 @@ def run_test(self): self.log.info("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]") test1txs = [self.create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, 49)] - txid1 = self.tx_submit(self.nodes[0], test1txs[0]) + txid1 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[0].serialize()), True) test1txs.append(self.create_transaction(self.nodes[0], txid1, self.ms_address, 48)) - txid2 = self.tx_submit(self.nodes[0], test1txs[1]) + txid2 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[1].serialize()), True) self.block_submit(self.nodes[0], test1txs, True) self.log.info("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation") test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 47) trueDummy(test2tx) - txid4 = self.tx_submit(self.nodes[0], test2tx, NULLDUMMY_ERROR) + assert_raises_jsonrpc(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test2tx.serialize()), True) self.log.info("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]") self.block_submit(self.nodes[0], [test2tx], True) self.log.info("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation") - test4tx = self.create_transaction(self.nodes[0], txid4, self.address, 46) + test4tx = self.create_transaction(self.nodes[0], test2tx.hash, self.address, 46) test6txs=[CTransaction(test4tx)] trueDummy(test4tx) - self.tx_submit(self.nodes[0], test4tx, NULLDUMMY_ERROR) + assert_raises_jsonrpc(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test4tx.serialize()), True) self.block_submit(self.nodes[0], [test4tx]) self.log.info("Test 6: NULLDUMMY compliant transactions should be accepted to mempool and in block after activation [432]") for i in test6txs: - self.tx_submit(self.nodes[0], i) + self.nodes[0].sendrawtransaction(bytes_to_hex_str(i.serialize()), True) self.block_submit(self.nodes[0], test6txs, True) @@ -100,17 +100,6 @@ def create_transaction(self, node, txid, to_address, amount): return tx - def tx_submit(self, node, tx, msg = ""): - tx.rehash() - try: - node.sendrawtransaction(bytes_to_hex_str(tx.serialize()), True) - except JSONRPCException as exp: - assert_equal(exp.error["message"], msg) - else: - assert_equal('', msg) - return tx.hash - - def block_submit(self, node, txs, accept = False): dip4_activated = self.lastblockheight + 1 >= 432 block = create_block(self.tip, create_coinbase(self.lastblockheight + 1, dip4_activated=dip4_activated), self.lastblocktime + 1) diff --git a/qa/rpc-tests/p2p-acceptblock.py b/test/functional/p2p-acceptblock.py similarity index 100% rename from qa/rpc-tests/p2p-acceptblock.py rename to test/functional/p2p-acceptblock.py diff --git a/qa/rpc-tests/p2p-autoinstantsend.py b/test/functional/p2p-autoinstantsend.py similarity index 100% rename from qa/rpc-tests/p2p-autoinstantsend.py rename to test/functional/p2p-autoinstantsend.py diff --git a/qa/rpc-tests/p2p-compactblocks.py b/test/functional/p2p-compactblocks.py similarity index 100% rename from qa/rpc-tests/p2p-compactblocks.py rename to test/functional/p2p-compactblocks.py diff --git a/qa/rpc-tests/p2p-fingerprint.py b/test/functional/p2p-fingerprint.py similarity index 100% rename from qa/rpc-tests/p2p-fingerprint.py rename to test/functional/p2p-fingerprint.py diff --git a/qa/rpc-tests/p2p-fullblocktest.py b/test/functional/p2p-fullblocktest.py similarity index 100% rename from qa/rpc-tests/p2p-fullblocktest.py rename to test/functional/p2p-fullblocktest.py diff --git a/qa/rpc-tests/p2p-instantsend.py b/test/functional/p2p-instantsend.py similarity index 100% rename from qa/rpc-tests/p2p-instantsend.py rename to test/functional/p2p-instantsend.py diff --git a/qa/rpc-tests/p2p-leaktests.py b/test/functional/p2p-leaktests.py similarity index 100% rename from qa/rpc-tests/p2p-leaktests.py rename to test/functional/p2p-leaktests.py diff --git a/qa/rpc-tests/p2p-mempool.py b/test/functional/p2p-mempool.py similarity index 100% rename from qa/rpc-tests/p2p-mempool.py rename to test/functional/p2p-mempool.py diff --git a/qa/rpc-tests/p2p-timeouts.py b/test/functional/p2p-timeouts.py similarity index 100% rename from qa/rpc-tests/p2p-timeouts.py rename to test/functional/p2p-timeouts.py diff --git a/qa/rpc-tests/p2p-versionbits-warning.py b/test/functional/p2p-versionbits-warning.py similarity index 100% rename from qa/rpc-tests/p2p-versionbits-warning.py rename to test/functional/p2p-versionbits-warning.py diff --git a/qa/rpc-tests/preciousblock.py b/test/functional/preciousblock.py similarity index 100% rename from qa/rpc-tests/preciousblock.py rename to test/functional/preciousblock.py diff --git a/qa/rpc-tests/prioritise_transaction.py b/test/functional/prioritise_transaction.py similarity index 95% rename from qa/rpc-tests/prioritise_transaction.py rename to test/functional/prioritise_transaction.py index c503f3e12..0da13e5eb 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/test/functional/prioritise_transaction.py @@ -109,13 +109,9 @@ def run_test(self): tx_hex = self.nodes[0].signrawtransaction(raw_tx)["hex"] tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"] - try: - self.nodes[0].sendrawtransaction(tx_hex) - except JSONRPCException as exp: - assert_equal(exp.error['code'], -26) # insufficient fee - assert(tx_id not in self.nodes[0].getrawmempool()) - else: - assert(False) + # This will raise an exception due to min relay fee not being met + assert_raises_jsonrpc(-26, "66: min relay fee not met", self.nodes[0].sendrawtransaction, tx_hex) + assert(tx_id not in self.nodes[0].getrawmempool()) # This is a less than 1000-byte transaction, so just set the fee # to be the minimum for a 1000 byte transaction and check that it is diff --git a/qa/rpc-tests/proxy_test.py b/test/functional/proxy_test.py similarity index 99% rename from qa/rpc-tests/proxy_test.py rename to test/functional/proxy_test.py index 6b2a8ed1c..748e3e69f 100755 --- a/qa/rpc-tests/proxy_test.py +++ b/test/functional/proxy_test.py @@ -49,6 +49,7 @@ def __init__(self): self.num_nodes = 4 self.setup_clean_chain = False + def setup_nodes(self): self.have_ipv6 = test_ipv6_local() # Create two proxies on different ports # ... one unauthenticated @@ -69,7 +70,7 @@ def __init__(self): self.conf3.unauth = True self.conf3.auth = True else: - print("Warning: testing without local IPv6 support") + self.log.warning("Testing without local IPv6 support") self.serv1 = Socks5Server(self.conf1) self.serv1.start() @@ -79,7 +80,6 @@ def __init__(self): self.serv3 = Socks5Server(self.conf3) self.serv3.start() - def setup_nodes(self): # Note: proxies are not used to connect to local nodes # this is because the proxy to use is based on CService.GetNetwork(), which return NET_UNROUTABLE for localhost args = [ diff --git a/qa/rpc-tests/pruning.py b/test/functional/pruning.py similarity index 100% rename from qa/rpc-tests/pruning.py rename to test/functional/pruning.py diff --git a/qa/rpc-tests/rawtransactions.py b/test/functional/rawtransactions.py similarity index 100% rename from qa/rpc-tests/rawtransactions.py rename to test/functional/rawtransactions.py diff --git a/qa/rpc-tests/receivedby.py b/test/functional/receivedby.py similarity index 100% rename from qa/rpc-tests/receivedby.py rename to test/functional/receivedby.py diff --git a/qa/rpc-tests/reindex.py b/test/functional/reindex.py similarity index 100% rename from qa/rpc-tests/reindex.py rename to test/functional/reindex.py diff --git a/qa/rpc-tests/rest.py b/test/functional/rest.py similarity index 100% rename from qa/rpc-tests/rest.py rename to test/functional/rest.py diff --git a/qa/rpc-tests/rpcbind_test.py b/test/functional/rpcbind_test.py similarity index 95% rename from qa/rpc-tests/rpcbind_test.py rename to test/functional/rpcbind_test.py index 220bf4ddd..8720a345c 100755 --- a/qa/rpc-tests/rpcbind_test.py +++ b/test/functional/rpcbind_test.py @@ -92,11 +92,7 @@ def run_test(self): # Check that with invalid rpcallowip, we are denied self.run_allowip_test([non_loopback_ip], non_loopback_ip, defaultport) - try: - self.run_allowip_test(['1.1.1.1'], non_loopback_ip, defaultport) - assert(not 'Connection not denied by rpcallowip as expected') - except JSONRPCException: - pass + assert_raises_jsonrpc(-342, "non-JSON HTTP response with '403 Forbidden' from server", self.run_allowip_test, ['1.1.1.1'], non_loopback_ip, defaultport) if __name__ == '__main__': RPCBindTest().main() diff --git a/qa/rpc-tests/rpcnamedargs.py b/test/functional/rpcnamedargs.py similarity index 100% rename from qa/rpc-tests/rpcnamedargs.py rename to test/functional/rpcnamedargs.py diff --git a/qa/rpc-tests/sendheaders.py b/test/functional/sendheaders.py similarity index 100% rename from qa/rpc-tests/sendheaders.py rename to test/functional/sendheaders.py diff --git a/qa/rpc-tests/signmessages.py b/test/functional/signmessages.py similarity index 100% rename from qa/rpc-tests/signmessages.py rename to test/functional/signmessages.py diff --git a/qa/rpc-tests/signrawtransactions.py b/test/functional/signrawtransactions.py similarity index 100% rename from qa/rpc-tests/signrawtransactions.py rename to test/functional/signrawtransactions.py diff --git a/qa/rpc-tests/smartfees.py b/test/functional/smartfees.py similarity index 100% rename from qa/rpc-tests/smartfees.py rename to test/functional/smartfees.py diff --git a/qa/rpc-tests/spentindex.py b/test/functional/spentindex.py similarity index 100% rename from qa/rpc-tests/spentindex.py rename to test/functional/spentindex.py diff --git a/qa/rpc-tests/sporks.py b/test/functional/sporks.py similarity index 100% rename from qa/rpc-tests/sporks.py rename to test/functional/sporks.py diff --git a/qa/rpc-tests/test_framework/__init__.py b/test/functional/test_framework/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/__init__.py rename to test/functional/test_framework/__init__.py diff --git a/qa/rpc-tests/test_framework/authproxy.py b/test/functional/test_framework/authproxy.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/authproxy.py rename to test/functional/test_framework/authproxy.py diff --git a/qa/rpc-tests/test_framework/bignum.py b/test/functional/test_framework/bignum.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/bignum.py rename to test/functional/test_framework/bignum.py diff --git a/qa/rpc-tests/test_framework/blockstore.py b/test/functional/test_framework/blockstore.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/blockstore.py rename to test/functional/test_framework/blockstore.py diff --git a/qa/rpc-tests/test_framework/blocktools.py b/test/functional/test_framework/blocktools.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/blocktools.py rename to test/functional/test_framework/blocktools.py diff --git a/qa/rpc-tests/test_framework/comptool.py b/test/functional/test_framework/comptool.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/comptool.py rename to test/functional/test_framework/comptool.py diff --git a/qa/rpc-tests/test_framework/coverage.py b/test/functional/test_framework/coverage.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/coverage.py rename to test/functional/test_framework/coverage.py diff --git a/qa/rpc-tests/test_framework/key.py b/test/functional/test_framework/key.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/key.py rename to test/functional/test_framework/key.py diff --git a/qa/rpc-tests/test_framework/mininode.py b/test/functional/test_framework/mininode.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/mininode.py rename to test/functional/test_framework/mininode.py diff --git a/qa/rpc-tests/test_framework/netutil.py b/test/functional/test_framework/netutil.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/netutil.py rename to test/functional/test_framework/netutil.py diff --git a/qa/rpc-tests/test_framework/script.py b/test/functional/test_framework/script.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/script.py rename to test/functional/test_framework/script.py diff --git a/qa/rpc-tests/test_framework/siphash.py b/test/functional/test_framework/siphash.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/siphash.py rename to test/functional/test_framework/siphash.py diff --git a/qa/rpc-tests/test_framework/socks5.py b/test/functional/test_framework/socks5.py old mode 100755 new mode 100644 similarity index 96% rename from qa/rpc-tests/test_framework/socks5.py rename to test/functional/test_framework/socks5.py index 450bf3775..dd7624d45 --- a/qa/rpc-tests/test_framework/socks5.py +++ b/test/functional/test_framework/socks5.py @@ -6,6 +6,9 @@ import socket, threading, queue import traceback, sys +import logging + +logger = logging.getLogger("TestFramework.socks5") ### Protocol constants class Command: @@ -112,10 +115,10 @@ def handle(self): cmdin = Socks5Command(cmd, atyp, addr, port, username, password) self.serv.queue.put(cmdin) - print('Proxy: ', cmdin) + logger.info('Proxy: %s', cmdin) # Fall through to disconnect except Exception as e: - traceback.print_exc(file=sys.stderr) + logger.exception("socks5 request handling failed.") self.serv.queue.put(e) finally: self.conn.close() diff --git a/qa/rpc-tests/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py old mode 100755 new mode 100644 similarity index 99% rename from qa/rpc-tests/test_framework/test_framework.py rename to test/functional/test_framework/test_framework.py index 717c1254e..6bc638f90 --- a/qa/rpc-tests/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -10,6 +10,7 @@ import sys import shutil import tempfile +import time import traceback from concurrent.futures import ThreadPoolExecutor from time import time, sleep @@ -222,6 +223,7 @@ def _start_logging(self): ch.setLevel(ll) # Format logs the same as bitcoind's debug.log with microprecision (so log files can be concatenated and sorted) formatter = logging.Formatter(fmt = '%(asctime)s.%(msecs)03d000 %(name)s (%(levelname)s): %(message)s', datefmt='%Y-%m-%d %H:%M:%S') + formatter.converter = time.gmtime fh.setFormatter(formatter) ch.setFormatter(formatter) # add the handlers to the logger diff --git a/qa/rpc-tests/test_framework/util.py b/test/functional/test_framework/util.py old mode 100755 new mode 100644 similarity index 100% rename from qa/rpc-tests/test_framework/util.py rename to test/functional/test_framework/util.py diff --git a/qa/pull-tester/rpc-tests.py b/test/functional/test_runner.py similarity index 92% rename from qa/pull-tester/rpc-tests.py rename to test/functional/test_runner.py index 2dcd8e798..0b92f1b2f 100755 --- a/qa/pull-tester/rpc-tests.py +++ b/test/functional/test_runner.py @@ -2,16 +2,15 @@ # Copyright (c) 2014-2016 The Bitcoin Core developers # Distributed under the MIT software license, see the accompanying # file COPYING or http://www.opensource.org/licenses/mit-license.php. -""" -rpc-tests.py - run regression test suite +"""Run regression test suite. This module calls down into individual test cases via subprocess. It will forward all unrecognized arguments onto the individual test scripts. -RPC tests are disabled on Windows by default. Use --force to run them anyway. +Functional tests are disabled on Windows by default. Use --force to run them anyway. For a description of arguments recognized by test scripts, see -`qa/pull-tester/test_framework/test_framework.py:BitcoinTestFramework.main`. +`test/functional/test_framework/test_framework.py:BitcoinTestFramework.main`. """ @@ -102,7 +101,7 @@ ZMQ_SCRIPTS = [ # ZMQ test can only be run if Axe Core was built with zmq-enabled. - # call rpc_tests.py with -nozmq to explicitly exclude these tests. + # call test_runner.py with -nozmq to explicitly exclude these tests. "zmq_test.py"] EXTENDED_SCRIPTS = [ @@ -140,7 +139,7 @@ def main(): # Parse arguments and pass through unrecognised args parser = argparse.ArgumentParser(add_help=False, - usage='%(prog)s [rpc-test.py options] [script options] [scripts]', + usage='%(prog)s [test_runner.py options] [script options] [scripts]', description=__doc__, epilog=''' Help text and arguments for individual test script:''', @@ -160,7 +159,7 @@ def main(): # Read config generated by configure. config = configparser.ConfigParser() - config.read_file(open(os.path.dirname(__file__) + "/tests_config.ini")) + config.read_file(open(os.path.dirname(__file__) + "/config.ini")) enable_wallet = config["components"].getboolean("ENABLE_WALLET") enable_utils = config["components"].getboolean("ENABLE_UTILS") @@ -174,7 +173,7 @@ def main(): sys.exit(0) if not (enable_wallet and enable_utils and enable_bitcoind): - print("No rpc tests to run. Wallet, utils, and bitcoind must all be enabled") + print("No functional tests to run. Wallet, utils, and bitcoind must all be enabled") print("Rerun `configure` with -enable-wallet, -with-utils and -with-daemon and rerun make") sys.exit(0) @@ -184,7 +183,7 @@ def main(): import zmq except ImportError: print("ERROR: \"import zmq\" failed. Use -nozmq to run without the ZMQ tests." - "To run zmq tests, see dependency info in /qa/README.md.") + "To run zmq tests, see dependency info in /test/README.md.") raise # Build list of tests @@ -213,13 +212,13 @@ def main(): if not test_list: print("No valid test scripts specified. Check that your test is in one " - "of the test lists in rpc-tests.py, or run rpc-tests.py with no arguments to run all tests") + "of the test lists in test_runner.py, or run test_runner.py with no arguments to run all tests") sys.exit(0) if args.help: - # Print help for rpc-tests.py, then print help of the first script and exit. + # Print help for test_runner.py, then print help of the first script and exit. parser.print_help() - subprocess.check_call((config["environment"]["SRCDIR"] + '/qa/rpc-tests/' + test_list[0]).split() + ['-h']) + subprocess.check_call((config["environment"]["SRCDIR"] + '/test/functional/' + test_list[0]).split() + ['-h']) sys.exit(0) run_tests(test_list, config["environment"]["SRCDIR"], config["environment"]["BUILDDIR"], config["environment"]["EXEEXT"], args.jobs, args.coverage, passon_args) @@ -235,10 +234,10 @@ def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=Fal if "BITCOIND" not in os.environ: os.environ["BITCOIND"] = build_dir + '/src/axed' + exeext - tests_dir = src_dir + '/qa/rpc-tests/' + tests_dir = src_dir + '/test/functional/' flags = ["--srcdir={}/src".format(build_dir)] + args - flags.append("--cachedir=%s/qa/cache" % build_dir) + flags.append("--cachedir=%s/test/cache" % build_dir) if enable_coverage: coverage = RPCCoverage() @@ -256,7 +255,7 @@ def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=Fal time_sum = 0 time0 = time.time() - job_queue = RPCTestHandler(jobs, tests_dir, test_list, flags) + job_queue = TestHandler(jobs, tests_dir, test_list, flags) max_len_name = len(max(test_list, key=len)) results = BOLD[1] + "%s | %s | %s\n\n" % ("TEST".ljust(max_len_name), "PASSED", "DURATION") + BOLD[0] @@ -284,7 +283,7 @@ def run_tests(test_list, src_dir, build_dir, exeext, jobs=1, enable_coverage=Fal sys.exit(not all_passed) -class RPCTestHandler: +class TestHandler: """ Trigger the testscrips passed in via the list. """ @@ -338,7 +337,7 @@ def get_next(self): class RPCCoverage(object): """ - Coverage reporting utilities for pull-tester. + Coverage reporting utilities for test_runner. Coverage calculation works by having each test script subprocess write coverage files into a particular directory. These files contain the RPC @@ -348,7 +347,7 @@ class RPCCoverage(object): After all tests complete, the commands run are combined and diff'd against the complete list to calculate uncovered RPC commands. - See also: qa/rpc-tests/test_framework/coverage.py + See also: test/functional/test_framework/coverage.py """ def __init__(self): @@ -376,7 +375,7 @@ def _get_uncovered_rpc_commands(self): Return a set of currently untested RPC commands. """ - # This is shared from `qa/rpc-tests/test-framework/coverage.py` + # This is shared from `test/functional/test-framework/coverage.py` reference_filename = 'rpc_interface.txt' coverage_file_prefix = 'coverage.' diff --git a/qa/rpc-tests/timestampindex.py b/test/functional/timestampindex.py similarity index 100% rename from qa/rpc-tests/timestampindex.py rename to test/functional/timestampindex.py diff --git a/qa/rpc-tests/txindex.py b/test/functional/txindex.py similarity index 100% rename from qa/rpc-tests/txindex.py rename to test/functional/txindex.py diff --git a/qa/rpc-tests/txn_clone.py b/test/functional/txn_clone.py similarity index 100% rename from qa/rpc-tests/txn_clone.py rename to test/functional/txn_clone.py diff --git a/qa/rpc-tests/txn_doublespend.py b/test/functional/txn_doublespend.py similarity index 100% rename from qa/rpc-tests/txn_doublespend.py rename to test/functional/txn_doublespend.py diff --git a/qa/rpc-tests/wallet-accounts.py b/test/functional/wallet-accounts.py similarity index 100% rename from qa/rpc-tests/wallet-accounts.py rename to test/functional/wallet-accounts.py diff --git a/qa/rpc-tests/wallet-dump.py b/test/functional/wallet-dump.py similarity index 99% rename from qa/rpc-tests/wallet-dump.py rename to test/functional/wallet-dump.py index 96b237c2a..8ff662059 100755 --- a/qa/rpc-tests/wallet-dump.py +++ b/test/functional/wallet-dump.py @@ -100,7 +100,7 @@ def run_test (self): self.nodes[0].encryptwallet('test') bitcoind_processes[0].wait() self.nodes[0] = start_node(0, self.options.tmpdir, self.extra_args[0]) - self.nodes[0].walletpassphrase('test', 10) + self.nodes[0].walletpassphrase('test', 30) # Should be a no-op: self.nodes[0].keypoolrefill() self.nodes[0].dumpwallet(tmpdir + "/node0/wallet.encrypted.dump") diff --git a/qa/rpc-tests/wallet-hd.py b/test/functional/wallet-hd.py similarity index 100% rename from qa/rpc-tests/wallet-hd.py rename to test/functional/wallet-hd.py diff --git a/qa/rpc-tests/wallet.py b/test/functional/wallet.py similarity index 95% rename from qa/rpc-tests/wallet.py rename to test/functional/wallet.py index b8e360e75..37f528f98 100755 --- a/qa/rpc-tests/wallet.py +++ b/test/functional/wallet.py @@ -72,7 +72,7 @@ def run_test (self): unspent_0 = self.nodes[2].listunspent()[0] unspent_0 = {"txid": unspent_0["txid"], "vout": unspent_0["vout"]} self.nodes[2].lockunspent(False, [unspent_0]) - assert_raises_message(JSONRPCException, "Insufficient funds", self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 200) + assert_raises_jsonrpc(-4, "Insufficient funds", self.nodes[2].sendtoaddress, self.nodes[2].getnewaddress(), 200) assert_equal([unspent_0], self.nodes[2].listlockunspent()) self.nodes[2].lockunspent(True, [unspent_0]) assert_equal(len(self.nodes[2].listlockunspent()), 0) @@ -255,19 +255,11 @@ def run_test (self): txObj = self.nodes[0].gettransaction(txId) assert_equal(txObj['amount'], Decimal('-0.0001')) - try: - txId = self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), "1f-4") - except JSONRPCException as e: - assert("Invalid amount" in e.error['message']) - else: - raise AssertionError("Must not parse invalid amounts") + # This will raise an exception because the amount type is wrong + assert_raises_jsonrpc(-3, "Invalid amount", self.nodes[0].sendtoaddress, self.nodes[2].getnewaddress(), "1f-4") - - try: - self.nodes[0].generate("2") - raise AssertionError("Must not accept strings as numeric") - except JSONRPCException as e: - assert("not an integer" in e.error['message']) + # This will raise an exception since generate does not accept a string + assert_raises_jsonrpc(-1, "not an integer", self.nodes[0].generate, "2") # Import address and private key to check correct behavior of spendable unspents # 1. Send some coins to generate new UTXO @@ -398,7 +390,7 @@ def run_test (self): node0_balance = self.nodes[0].getbalance() # With walletrejectlongchains we will not create the tx and store it in our wallet. - assert_raises_message(JSONRPCException, "mempool chain", self.nodes[0].sendtoaddress, sending_addr, node0_balance - Decimal('0.01')) + assert_raises_jsonrpc(-4, "Transaction has too long of a mempool chain", self.nodes[0].sendtoaddress, sending_addr, node0_balance - Decimal('0.01')) # Verify nothing new in wallet assert_equal(total_txs, len(self.nodes[0].listtransactions("*",99999))) diff --git a/qa/rpc-tests/walletbackup.py b/test/functional/walletbackup.py similarity index 100% rename from qa/rpc-tests/walletbackup.py rename to test/functional/walletbackup.py diff --git a/qa/rpc-tests/zapwallettxes.py b/test/functional/zapwallettxes.py similarity index 100% rename from qa/rpc-tests/zapwallettxes.py rename to test/functional/zapwallettxes.py diff --git a/qa/rpc-tests/zmq_test.py b/test/functional/zmq_test.py similarity index 100% rename from qa/rpc-tests/zmq_test.py rename to test/functional/zmq_test.py diff --git a/src/test/bctest.py b/test/util/bctest.py old mode 100755 new mode 100644 similarity index 96% rename from src/test/bctest.py rename to test/util/bctest.py index c07ef6e3e..b17cf77ae --- a/src/test/bctest.py +++ b/test/util/bctest.py @@ -23,14 +23,14 @@ def parse_output(a, fmt): else: raise NotImplementedError("Don't know how to compare %s" % fmt) -def bctest(testDir, testObj, exeext): +def bctest(testDir, testObj, buildenv): """Runs a single test, comparing output and RC to expected output and RC. Raises an error if input can't be read, executable fails, or output/RC are not as expected. Error is caught by bctester() and reported. """ # Get the exec names and arguments - execprog = testObj['exec'] + exeext + execprog = buildenv.BUILDDIR + "/src/" + testObj['exec'] + buildenv.exeext execargs = testObj['args'] execrun = [execprog] + execargs @@ -124,7 +124,7 @@ def bctester(testDir, input_basename, buildenv): for testObj in input_data: try: - bctest(testDir, testObj, buildenv.exeext) + bctest(testDir, testObj, buildenv) logging.info("PASSED: " + testObj["description"]) except: logging.info("FAILED: " + testObj["description"]) diff --git a/test/util/bitcoin-util-test.py b/test/util/bitcoin-util-test.py new file mode 100644 index 000000000..e09a25159 --- /dev/null +++ b/test/util/bitcoin-util-test.py @@ -0,0 +1,36 @@ +#!/usr/bin/env python +# Copyright 2014 BitPay Inc. +# Copyright 2016 The Bitcoin Core developers +# Distributed under the MIT software license, see the accompanying +# file COPYING or http://www.opensource.org/licenses/mit-license.php. +from __future__ import division,print_function,unicode_literals +import os +import sys +import argparse +import logging + +help_text="""Test framework for bitcoin utils. + +Runs automatically during `make check`. + +Can also be run manually.""" + +if __name__ == '__main__': + sys.path.append(os.path.dirname(os.path.abspath(__file__))) + import buildenv + import bctest + + parser = argparse.ArgumentParser(description=help_text) + parser.add_argument('-v', '--verbose', action='store_true') + args = parser.parse_args() + verbose = args.verbose + + if verbose: + level = logging.DEBUG + else: + level = logging.ERROR + formatter = '%(asctime)s - %(levelname)s - %(message)s' + # Add the format/level to the logger + logging.basicConfig(format = formatter, level=level) + + bctest.bctester(buildenv.SRCDIR + "/test/util/data", "bitcoin-util-test.json", buildenv) diff --git a/test/util/buildenv.py.in b/test/util/buildenv.py.in new file mode 100644 index 000000000..33030b034 --- /dev/null +++ b/test/util/buildenv.py.in @@ -0,0 +1,4 @@ +#!/usr/bin/env python +exeext="@EXEEXT@" +SRCDIR="@abs_top_srcdir@" +BUILDDIR="@abs_top_builddir@" diff --git a/src/test/data/bitcoin-util-test.json b/test/util/data/bitcoin-util-test.json old mode 100755 new mode 100644 similarity index 98% rename from src/test/data/bitcoin-util-test.json rename to test/util/data/bitcoin-util-test.json index f9ba597e5..c17d511bd --- a/src/test/data/bitcoin-util-test.json +++ b/test/util/data/bitcoin-util-test.json @@ -87,7 +87,7 @@ { "exec": "./axe-tx", "args": ["-create", - "outaddr=1:Xdak8YsJz8tm1iHFmycfTyKeUvHgfbdpyw:garbage"], + "outaddr=1:PEtyWpDbdeSbu93uA4dH25maE1d8j4U6rR:garbage"], "return_code": 1, "error_txt": "error: TX output missing or too many separators", "description": "Malformed outaddr argument (too many separators). Expected to fail." @@ -114,7 +114,7 @@ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18", "in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1", - "outaddr=0.18:Xdak8YsJz8tm1iHFmycfTyKeUvHgfbdpyw", + "outaddr=0.18:PEtyWpDbdeSbu93uA4dH25maE1d8j4U6rR", "outaddr=4:XxppMBDQ6SiJrKcBrAy4WkkNdrxDBfzFdZ"], "output_cmp": "txcreate1.hex", "description": "Creates a new transaction with three inputs and two outputs" @@ -126,7 +126,7 @@ "in=5897de6bd6027a475eadd57019d4e6872c396d0716c4875a5f1a6fcfdf385c1f:0", "in=bf829c6bcf84579331337659d31f89dfd138f7f7785802d5501c92333145ca7c:18", "in=22a6f904655d53ae2ff70e701a0bbd90aa3975c0f40bfc6cc996a9049e31cdfc:1", - "outaddr=0.18:Xdak8YsJz8tm1iHFmycfTyKeUvHgfbdpyw", + "outaddr=0.18:PEtyWpDbdeSbu93uA4dH25maE1d8j4U6rR", "outaddr=4:XxppMBDQ6SiJrKcBrAy4WkkNdrxDBfzFdZ"], "output_cmp": "txcreate1.json", "description": "Creates a new transaction with three inputs and two outputs (output in json)" diff --git a/src/test/data/blanktxv1.hex b/test/util/data/blanktxv1.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/blanktxv1.hex rename to test/util/data/blanktxv1.hex diff --git a/src/test/data/blanktxv1.json b/test/util/data/blanktxv1.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/blanktxv1.json rename to test/util/data/blanktxv1.json diff --git a/src/test/data/blanktxv2.hex b/test/util/data/blanktxv2.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/blanktxv2.hex rename to test/util/data/blanktxv2.hex diff --git a/src/test/data/blanktxv2.json b/test/util/data/blanktxv2.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/blanktxv2.json rename to test/util/data/blanktxv2.json diff --git a/test/util/data/tt-delin1-out.hex b/test/util/data/tt-delin1-out.hex new file mode 100644 index 000000000..42ad840f4 --- /dev/null +++ b/test/util/data/tt-delin1-out.hex @@ -0,0 +1 @@ +0100000014fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac00000000 diff --git a/test/util/data/tt-delin1-out.json b/test/util/data/tt-delin1-out.json new file mode 100644 index 000000000..cb2dbd212 --- /dev/null +++ b/test/util/data/tt-delin1-out.json @@ -0,0 +1,216 @@ +{ + "txid": "81b2035be1da1abe745c6141174a73d151009ec17b3d5ebffa2e177408c50dfd", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "27871a1a27d833e99cd392a502a647beaaeda6da535417501c76312d52235cfd", + "vout": 332, + "scriptSig": { + "asm": "3046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "752f7f69b915637dc1c2f7aed1466ad676f6f3e24cf922809705f664e97ab3c1", + "vout": 1, + "scriptSig": { + "asm": "3044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "b0ac9cca2e69cd02410e31b1f4402a25758e71abd1ab06c265ef9077dc05d0ed", + "vout": 209, + "scriptSig": { + "asm": "304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a135eafb595eaf4c1ea59ccb111cdc0eae1b2c979b226a1e5aa8b76fe2d628df", + "vout": 0, + "scriptSig": { + "asm": "3045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "a5d6bf53ba21140b8a4d554feb00fe8bb9a62430ff9e4624aa2f58a120232aae", + "vout": 1, + "scriptSig": { + "asm": "3046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "1b299cf14f1a22e81ea56d71b7affbd7cf386807bf2b4d4b79a18a54125accb3", + "vout": 0, + "scriptSig": { + "asm": "3045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "071df1cdcb3f0070f9d6af7b0274f02d0be2324a274727cfd288383167531485", + "vout": 21, + "scriptSig": { + "asm": "3045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b012e500eb7adf7a13ed332dd6ece849f94f7a62bb3eac5babab356d1fc19282", + "vout": 9, + "scriptSig": { + "asm": "304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "58840fee9c833f2f2d40575842f30f4b8d2553094d06ad88b03d06869acf3d88", + "vout": 30, + "scriptSig": { + "asm": "30440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "e69f9cd16946e570a665245354428a3f507ea69f4568b581e4af98edb3db9766", + "vout": 114, + "scriptSig": { + "asm": "304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "595d1257f654ed2cbe5a65421e8aefd2b4d70b5b6c89a03f1d7e518221fc3f02", + "vout": 103, + "scriptSig": { + "asm": "3046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "06fc818f9555a261248ecd7aad0993eafb5a82ceb2b5c87c3ddfb06671c7f816", + "vout": 1, + "scriptSig": { + "asm": "3045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec7669018[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "fb416c8155d6bb1d43f9395466ca90a638a7c2dd3ff617aadf3a7ac8f3967b19", + "vout": 0, + "scriptSig": { + "asm": "304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "3940b9683bd6104ad24c978e640ba4095993cafdb27d2ed91baa27ee61a2d920", + "vout": 221, + "scriptSig": { + "asm": "3045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "711b5714d3b5136147c02194cd95bde94a4648c4263ca6f972d86cd1d579f150", + "vout": 1, + "scriptSig": { + "asm": "3045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba9074[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "6364b5c5efe018430789e7fb4e338209546cae5d9c5f5e300aac68155d861b55", + "vout": 27, + "scriptSig": { + "asm": "304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "0bb57f6e38012c86d4c5a28c904f2675082859147921a707d48961015a3e5057", + "vout": 1095, + "scriptSig": { + "asm": "304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "9b34274814a2540bb062107117f8f3e75ef85d953e9372d8261a3e9dfbc1163f", + "vout": 37, + "scriptSig": { + "asm": "3045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b86b5cc0d8a7374d94e277850b0a249cb26a7b42ddf014f28a49b8859da64241", + "vout": 20, + "scriptSig": { + "asm": "304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "3d0a2353eeec44d3c10aed259038db321912122cd4150048f7bfa4c0ecfee236", + "vout": 242, + "scriptSig": { + "asm": "3046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.3782, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "XooH6vpTCuVowS9vmJowNaNGcJQ3cQT7rs" + ] + } + }, + { + "value": 0.01000001, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "XkaMatRZjFxq1QbgUvdmqGzGRaPqSLvvS6" + ] + } + } + ], + "hex": "0100000014fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac00000000" +} diff --git a/test/util/data/tt-delout1-out.hex b/test/util/data/tt-delout1-out.hex new file mode 100644 index 000000000..cc60c3fac --- /dev/null +++ b/test/util/data/tt-delout1-out.hex @@ -0,0 +1 @@ +0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0160f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac00000000 diff --git a/test/util/data/tt-delout1-out.json b/test/util/data/tt-delout1-out.json new file mode 100644 index 000000000..ca2de5fc6 --- /dev/null +++ b/test/util/data/tt-delout1-out.json @@ -0,0 +1,212 @@ +{ + "txid": "c46ccd75b5050e942b2e86a3648f843f525fe6fc000bf0534ba5973063354493", + "version": 1, + "locktime": 0, + "vin": [ + { + "txid": "27871a1a27d833e99cd392a502a647beaaeda6da535417501c76312d52235cfd", + "vout": 332, + "scriptSig": { + "asm": "3046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a72ec96bd0d022d1b0c2f9078cdd46b3725b8eecdd001e17b21e3ababad14ecb", + "vout": 0, + "scriptSig": { + "asm": "3046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba[ALL] 03e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505", + "hex": "493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505" + }, + "sequence": 4294967295 + }, + { + "txid": "752f7f69b915637dc1c2f7aed1466ad676f6f3e24cf922809705f664e97ab3c1", + "vout": 1, + "scriptSig": { + "asm": "3044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "b0ac9cca2e69cd02410e31b1f4402a25758e71abd1ab06c265ef9077dc05d0ed", + "vout": 209, + "scriptSig": { + "asm": "304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a135eafb595eaf4c1ea59ccb111cdc0eae1b2c979b226a1e5aa8b76fe2d628df", + "vout": 0, + "scriptSig": { + "asm": "3045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "a5d6bf53ba21140b8a4d554feb00fe8bb9a62430ff9e4624aa2f58a120232aae", + "vout": 1, + "scriptSig": { + "asm": "3046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "1b299cf14f1a22e81ea56d71b7affbd7cf386807bf2b4d4b79a18a54125accb3", + "vout": 0, + "scriptSig": { + "asm": "3045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "071df1cdcb3f0070f9d6af7b0274f02d0be2324a274727cfd288383167531485", + "vout": 21, + "scriptSig": { + "asm": "3045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b012e500eb7adf7a13ed332dd6ece849f94f7a62bb3eac5babab356d1fc19282", + "vout": 9, + "scriptSig": { + "asm": "304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "58840fee9c833f2f2d40575842f30f4b8d2553094d06ad88b03d06869acf3d88", + "vout": 30, + "scriptSig": { + "asm": "30440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "e69f9cd16946e570a665245354428a3f507ea69f4568b581e4af98edb3db9766", + "vout": 114, + "scriptSig": { + "asm": "304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "595d1257f654ed2cbe5a65421e8aefd2b4d70b5b6c89a03f1d7e518221fc3f02", + "vout": 103, + "scriptSig": { + "asm": "3046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "06fc818f9555a261248ecd7aad0993eafb5a82ceb2b5c87c3ddfb06671c7f816", + "vout": 1, + "scriptSig": { + "asm": "3045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec7669018[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "fb416c8155d6bb1d43f9395466ca90a638a7c2dd3ff617aadf3a7ac8f3967b19", + "vout": 0, + "scriptSig": { + "asm": "304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "3940b9683bd6104ad24c978e640ba4095993cafdb27d2ed91baa27ee61a2d920", + "vout": 221, + "scriptSig": { + "asm": "3045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "711b5714d3b5136147c02194cd95bde94a4648c4263ca6f972d86cd1d579f150", + "vout": 1, + "scriptSig": { + "asm": "3045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba9074[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "6364b5c5efe018430789e7fb4e338209546cae5d9c5f5e300aac68155d861b55", + "vout": 27, + "scriptSig": { + "asm": "304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "0bb57f6e38012c86d4c5a28c904f2675082859147921a707d48961015a3e5057", + "vout": 1095, + "scriptSig": { + "asm": "304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "9b34274814a2540bb062107117f8f3e75ef85d953e9372d8261a3e9dfbc1163f", + "vout": 37, + "scriptSig": { + "asm": "3045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b86b5cc0d8a7374d94e277850b0a249cb26a7b42ddf014f28a49b8859da64241", + "vout": 20, + "scriptSig": { + "asm": "304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "3d0a2353eeec44d3c10aed259038db321912122cd4150048f7bfa4c0ecfee236", + "vout": 242, + "scriptSig": { + "asm": "3046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.3782, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "XooH6vpTCuVowS9vmJowNaNGcJQ3cQT7rs" + ] + } + } + ], + "hex": "0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0160f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac00000000" +} diff --git a/test/util/data/tt-locktime317000-out.hex b/test/util/data/tt-locktime317000-out.hex new file mode 100644 index 000000000..287f420a4 --- /dev/null +++ b/test/util/data/tt-locktime317000-out.hex @@ -0,0 +1 @@ +0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac48d60400 diff --git a/test/util/data/tt-locktime317000-out.json b/test/util/data/tt-locktime317000-out.json new file mode 100644 index 000000000..70c9cf3b7 --- /dev/null +++ b/test/util/data/tt-locktime317000-out.json @@ -0,0 +1,225 @@ +{ + "txid": "aded538f642c17e15f4d3306b8be7e1a4d1ae0c4616d641ab51ea09ba65e5cb5", + "version": 1, + "locktime": 317000, + "vin": [ + { + "txid": "27871a1a27d833e99cd392a502a647beaaeda6da535417501c76312d52235cfd", + "vout": 332, + "scriptSig": { + "asm": "3046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a72ec96bd0d022d1b0c2f9078cdd46b3725b8eecdd001e17b21e3ababad14ecb", + "vout": 0, + "scriptSig": { + "asm": "3046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba[ALL] 03e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505", + "hex": "493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505" + }, + "sequence": 4294967295 + }, + { + "txid": "752f7f69b915637dc1c2f7aed1466ad676f6f3e24cf922809705f664e97ab3c1", + "vout": 1, + "scriptSig": { + "asm": "3044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "b0ac9cca2e69cd02410e31b1f4402a25758e71abd1ab06c265ef9077dc05d0ed", + "vout": 209, + "scriptSig": { + "asm": "304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "a135eafb595eaf4c1ea59ccb111cdc0eae1b2c979b226a1e5aa8b76fe2d628df", + "vout": 0, + "scriptSig": { + "asm": "3045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "a5d6bf53ba21140b8a4d554feb00fe8bb9a62430ff9e4624aa2f58a120232aae", + "vout": 1, + "scriptSig": { + "asm": "3046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "1b299cf14f1a22e81ea56d71b7affbd7cf386807bf2b4d4b79a18a54125accb3", + "vout": 0, + "scriptSig": { + "asm": "3045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967[ALL] 03a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52", + "hex": "483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52" + }, + "sequence": 4294967295 + }, + { + "txid": "071df1cdcb3f0070f9d6af7b0274f02d0be2324a274727cfd288383167531485", + "vout": 21, + "scriptSig": { + "asm": "3045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b012e500eb7adf7a13ed332dd6ece849f94f7a62bb3eac5babab356d1fc19282", + "vout": 9, + "scriptSig": { + "asm": "304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "58840fee9c833f2f2d40575842f30f4b8d2553094d06ad88b03d06869acf3d88", + "vout": 30, + "scriptSig": { + "asm": "30440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "e69f9cd16946e570a665245354428a3f507ea69f4568b581e4af98edb3db9766", + "vout": 114, + "scriptSig": { + "asm": "304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "595d1257f654ed2cbe5a65421e8aefd2b4d70b5b6c89a03f1d7e518221fc3f02", + "vout": 103, + "scriptSig": { + "asm": "3046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "06fc818f9555a261248ecd7aad0993eafb5a82ceb2b5c87c3ddfb06671c7f816", + "vout": 1, + "scriptSig": { + "asm": "3045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec7669018[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "fb416c8155d6bb1d43f9395466ca90a638a7c2dd3ff617aadf3a7ac8f3967b19", + "vout": 0, + "scriptSig": { + "asm": "304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a[ALL] 027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34", + "hex": "49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34" + }, + "sequence": 4294967295 + }, + { + "txid": "3940b9683bd6104ad24c978e640ba4095993cafdb27d2ed91baa27ee61a2d920", + "vout": 221, + "scriptSig": { + "asm": "3045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + }, + { + "txid": "711b5714d3b5136147c02194cd95bde94a4648c4263ca6f972d86cd1d579f150", + "vout": 1, + "scriptSig": { + "asm": "3045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba9074[ALL] 0234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd", + "hex": "483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cd" + }, + "sequence": 4294967295 + }, + { + "txid": "6364b5c5efe018430789e7fb4e338209546cae5d9c5f5e300aac68155d861b55", + "vout": 27, + "scriptSig": { + "asm": "304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "0bb57f6e38012c86d4c5a28c904f2675082859147921a707d48961015a3e5057", + "vout": 1095, + "scriptSig": { + "asm": "304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "9b34274814a2540bb062107117f8f3e75ef85d953e9372d8261a3e9dfbc1163f", + "vout": 37, + "scriptSig": { + "asm": "3045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "b86b5cc0d8a7374d94e277850b0a249cb26a7b42ddf014f28a49b8859da64241", + "vout": 20, + "scriptSig": { + "asm": "304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321[ALL] 03f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c", + "hex": "48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64c" + }, + "sequence": 4294967295 + }, + { + "txid": "3d0a2353eeec44d3c10aed259038db321912122cd4150048f7bfa4c0ecfee236", + "vout": 242, + "scriptSig": { + "asm": "3046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68[ALL] 03091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc", + "hex": "493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adc" + }, + "sequence": 4294967295 + } + ], + "vout": [ + { + "value": 1.3782, + "n": 0, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 8fd139bb39ced713f231c58a4d07bf6954d1c201 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "XooH6vpTCuVowS9vmJowNaNGcJQ3cQT7rs" + ] + } + }, + { + "value": 0.01000001, + "n": 1, + "scriptPubKey": { + "asm": "OP_DUP OP_HASH160 6c772e9cf96371bba3da8cb733da70a2fcf20078 OP_EQUALVERIFY OP_CHECKSIG", + "hex": "76a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac", + "reqSigs": 1, + "type": "pubkeyhash", + "addresses": [ + "XkaMatRZjFxq1QbgUvdmqGzGRaPqSLvvS6" + ] + } + } + ], + "hex": "0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac48d60400" +} diff --git a/test/util/data/tx394b54bb.hex b/test/util/data/tx394b54bb.hex new file mode 100644 index 000000000..33f26cb4d --- /dev/null +++ b/test/util/data/tx394b54bb.hex @@ -0,0 +1 @@ +0100000015fd5c23522d31761c50175453daa6edaabe47a602a592d39ce933d8271a1a87274c0100006c493046022100b4251ecd63778a3dde0155abe4cd162947620ae9ee45a874353551092325b116022100db307baf4ff3781ec520bd18f387948cedd15dc27bafe17c894b0fe6ffffcafa012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffcb4ed1baba3a1eb2171e00ddec8e5b72b346dd8c07f9c2b0d122d0d06bc92ea7000000006c493046022100a9b617843b68c284715d3e02fd120479cd0d96a6c43bf01e697fb0a460a21a3a022100ba0a12fbe8b993d4e7911fa3467615765dbe421ddf5c51b57a9c1ee19dcc00ba012103e633b4fa4ceb705c2da712390767199be8ef2448b3095dc01652e11b2b751505ffffffffc1b37ae964f605978022f94ce2f3f676d66a46d1aef7c2c17d6315b9697f2f75010000006a473044022079bd62ee09621a3be96b760c39e8ef78170101d46313923c6b07ae60a95c90670220238e51ea29fc70b04b65508450523caedbb11cb4dd5aa608c81487de798925ba0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffffedd005dc7790ef65c206abd1ab718e75252a40f4b1310e4102cd692eca9cacb0d10000006b48304502207722d6f9038673c86a1019b1c4de2d687ae246477cd4ca7002762be0299de385022100e594a11e3a313942595f7666dcf7078bcb14f1330f4206b95c917e7ec0e82fac012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffdf28d6e26fb7a85a1e6a229b972c1bae0edc1c11cb9ca51e4caf5e59fbea35a1000000006b483045022100a63a4788027b79b65c6f9d9e054f68cf3b4eed19efd82a2d53f70dcbe64683390220526f243671425b2bd05745fcf2729361f985cfe84ea80c7cfc817b93d8134374012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffffae2a2320a1582faa24469eff3024a6b98bfe00eb4f554d8a0b1421ba53bfd6a5010000006c493046022100b200ac6db16842f76dab9abe807ce423c992805879bc50abd46ed8275a59d9cf022100c0d518e85dd345b3c29dd4dc47b9a420d3ce817b18720e94966d2fe23413a408012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffffb3cc5a12548aa1794b4d2bbf076838cfd7fbafb7716da51ee8221a4ff19c291b000000006b483045022100ededc441c3103a6f2bd6cab7639421af0f6ec5e60503bce1e603cf34f00aee1c02205cb75f3f519a13fb348783b21db3085cb5ec7552c59e394fdbc3e1feea43f967012103a621f08be22d1bbdcbe4e527ee4927006aa555fc65e2aafa767d4ea2fe9dfa52ffffffff85145367313888d2cf2747274a32e20b2df074027bafd6f970003fcbcdf11d07150000006b483045022100d9eed5413d2a4b4b98625aa6e3169edc4fb4663e7862316d69224454e70cd8ca022061e506521d5ced51dd0ea36496e75904d756a4c4f9fb111568555075d5f68d9a012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff8292c11f6d35abab5bac3ebb627a4ff949e8ecd62d33ed137adf7aeb00e512b0090000006b48304502207e84b27139c4c19c828cb1e30c349bba88e4d9b59be97286960793b5ddc0a2af0221008cdc7a951e7f31c20953ed5635fbabf228e80b7047f32faaa0313e7693005177012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff883dcf9a86063db088ad064d0953258d4b0ff3425857402d2f3f839cee0f84581e0000006a4730440220426540dfed9c4ab5812e5f06df705b8bcf307dd7d20f7fa6512298b2a6314f420220064055096e3ca62f6c7352c66a5447767c53f946acdf35025ab3807ddb2fa404012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff6697dbb3ed98afe481b568459fa67e503f8a4254532465a670e54669d19c9fe6720000006a47304402200a5e673996f2fc88e21cc8613611f08a650bc0370338803591d85d0ec5663764022040b6664a0d1ec83a7f01975b8fde5232992b8ca58bf48af6725d2f92a936ab2e012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff023ffc2182517e1d3fa0896c5b0bd7b4d2ef8a1e42655abe2ced54f657125d59670000006c493046022100d93b30219c5735f673be5c3b4688366d96f545561c74cb62c6958c00f6960806022100ec8200adcb028f2184fa2a4f6faac7f8bb57cb4503bb7584ac11051fece31b3d012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff16f8c77166b0df3d7cc8b5b2ce825afbea9309ad7acd8e2461a255958f81fc06010000006b483045022100a13934e68d3f5b22b130c4cb33f4da468cffc52323a47fbfbe06b64858162246022047081e0a70ff770e64a2e2d31e5d520d9102268b57a47009a72fe73ec766901801210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff197b96f3c87a3adfaa17f63fddc2a738a690ca665439f9431dbbd655816c41fb000000006c49304602210097f1f35d5bdc1a3a60390a1b015b8e7c4f916aa3847aafd969e04975e15bbe70022100a9052eb25517d481f1fda1b129eb1b534da50ea1a51f3ee012dca3601c11b86a0121027a759be8df971a6a04fafcb4f6babf75dc811c5cdaa0734cddbe9b942ce75b34ffffffff20d9a261ee27aa1bd92e7db2fdca935909a40b648e974cd24a10d63b68b94039dd0000006b483045022012b3138c591bf7154b6fef457f2c4a3c7162225003788ac0024a99355865ff13022100b71b125ae1ffb2e1d1571f580cd3ebc8cd049a2d7a8a41f138ba94aeb982106f012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff50f179d5d16cd872f9a63c26c448464ae9bd95cd9421c0476113b5d314571b71010000006b483045022100f834ccc8b22ee72712a3e5e6ef4acb8b2fb791b5385b70e2cd4332674d6667f4022024fbda0a997e0c253503f217501f508a4d56edce2c813ecdd9ad796dbeba907401210234b9d9413f247bb78cd3293b7b65a2c38018ba5621ea9ee737f3a6a3523fb4cdffffffff551b865d1568ac0a305e5f9c5dae6c540982334efbe789074318e0efc5b564631b0000006b48304502203b2fd1e39ae0e469d7a15768f262661b0de41470daf0fe8c4fd0c26542a0870002210081c57e331f9a2d214457d953e3542904727ee412c63028113635d7224da3dccc012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff57503e5a016189d407a721791459280875264f908ca2c5d4862c01386e7fb50b470400006b48304502206947a9c54f0664ece4430fd4ae999891dc50bb6126bc36b6a15a3189f29d25e9022100a86cfc4e2fdd9e39a20e305cfd1b76509c67b3e313e0f118229105caa0e823c9012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff3f16c1fb9d3e1a26d872933e955df85ee7f3f817711062b00b54a2144827349b250000006b483045022100c7128fe10b2d38744ae8177776054c29fc8ec13f07207723e70766ab7164847402201d2cf09009b9596de74c0183d1ab832e5edddb7a9965880bb400097e850850f8012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff4142a69d85b8498af214f0dd427b6ab29c240a0b8577e2944d37a7d8c05c6bb8140000006b48304502203b89a71628a28cc3703d170ca3be77786cff6b867e38a18b719705f8a326578f022100b2a9879e1acf621faa6466c207746a7f3eb4c8514c1482969aba3f2a957f1321012103f1575d6124ac78be398c25b31146d08313c6072d23a4d7df5ac6a9f87346c64cffffffff36e2feecc0a4bff7480015d42c12121932db389025ed0ac1d344ecee53230a3df20000006c493046022100ef794a8ef7fd6752d2a183c18866ff6e8dc0f5bd889a63e2c21cf303a6302461022100c1b09662d9e92988c3f9fcf17d1bcc79b5403647095d7212b9f8a1278a532d68012103091137f3ef23f4acfc19a5953a68b2074fae942ad3563ef28c33b0cac9a93adcffffffff0260f73608000000001976a9148fd139bb39ced713f231c58a4d07bf6954d1c20188ac41420f00000000001976a9146c772e9cf96371bba3da8cb733da70a2fcf2007888ac00000000 diff --git a/src/test/data/txcreate1.hex b/test/util/data/txcreate1.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreate1.hex rename to test/util/data/txcreate1.hex diff --git a/src/test/data/txcreate1.json b/test/util/data/txcreate1.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreate1.json rename to test/util/data/txcreate1.json diff --git a/src/test/data/txcreate2.hex b/test/util/data/txcreate2.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreate2.hex rename to test/util/data/txcreate2.hex diff --git a/src/test/data/txcreate2.json b/test/util/data/txcreate2.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreate2.json rename to test/util/data/txcreate2.json diff --git a/src/test/data/txcreatedata1.hex b/test/util/data/txcreatedata1.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatedata1.hex rename to test/util/data/txcreatedata1.hex diff --git a/src/test/data/txcreatedata1.json b/test/util/data/txcreatedata1.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatedata1.json rename to test/util/data/txcreatedata1.json diff --git a/src/test/data/txcreatedata2.hex b/test/util/data/txcreatedata2.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatedata2.hex rename to test/util/data/txcreatedata2.hex diff --git a/src/test/data/txcreatedata2.json b/test/util/data/txcreatedata2.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatedata2.json rename to test/util/data/txcreatedata2.json diff --git a/src/test/data/txcreatedata_seq0.hex b/test/util/data/txcreatedata_seq0.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatedata_seq0.hex rename to test/util/data/txcreatedata_seq0.hex diff --git a/src/test/data/txcreatedata_seq0.json b/test/util/data/txcreatedata_seq0.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatedata_seq0.json rename to test/util/data/txcreatedata_seq0.json diff --git a/src/test/data/txcreatedata_seq1.hex b/test/util/data/txcreatedata_seq1.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatedata_seq1.hex rename to test/util/data/txcreatedata_seq1.hex diff --git a/src/test/data/txcreatedata_seq1.json b/test/util/data/txcreatedata_seq1.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatedata_seq1.json rename to test/util/data/txcreatedata_seq1.json diff --git a/src/test/data/txcreatemultisig1.hex b/test/util/data/txcreatemultisig1.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatemultisig1.hex rename to test/util/data/txcreatemultisig1.hex diff --git a/src/test/data/txcreatemultisig1.json b/test/util/data/txcreatemultisig1.json old mode 100755 new mode 100644 similarity index 90% rename from src/test/data/txcreatemultisig1.json rename to test/util/data/txcreatemultisig1.json index c2e143842..4165be47a --- a/src/test/data/txcreatemultisig1.json +++ b/test/util/data/txcreatemultisig1.json @@ -14,8 +14,8 @@ "reqSigs": 2, "type": "multisig", "addresses": [ - "PPPSB1WwJBX5996uvggSP7qbaqHTMvKjPP", - "PP8597iKBDrxP4e3ynZHkBByn65GDgZysa", + "PPPSB1WwJBX5996uvggSP7qbaqHTMvKjPP", + "PP8597iKBDrxP4e3ynZHkBByn65GDgZysa", "PBw5ju12eT3jGw8eL7vh9JhR4eagRCFwqz" ] } diff --git a/src/test/data/txcreatemultisig2.hex b/test/util/data/txcreatemultisig2.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatemultisig2.hex rename to test/util/data/txcreatemultisig2.hex diff --git a/src/test/data/txcreatemultisig2.json b/test/util/data/txcreatemultisig2.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatemultisig2.json rename to test/util/data/txcreatemultisig2.json diff --git a/src/test/data/txcreateoutpubkey1.hex b/test/util/data/txcreateoutpubkey1.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreateoutpubkey1.hex rename to test/util/data/txcreateoutpubkey1.hex diff --git a/src/test/data/txcreateoutpubkey1.json b/test/util/data/txcreateoutpubkey1.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreateoutpubkey1.json rename to test/util/data/txcreateoutpubkey1.json diff --git a/src/test/data/txcreatescript1.hex b/test/util/data/txcreatescript1.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatescript1.hex rename to test/util/data/txcreatescript1.hex diff --git a/src/test/data/txcreatescript1.json b/test/util/data/txcreatescript1.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatescript1.json rename to test/util/data/txcreatescript1.json diff --git a/src/test/data/txcreatescript2.hex b/test/util/data/txcreatescript2.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatescript2.hex rename to test/util/data/txcreatescript2.hex diff --git a/src/test/data/txcreatescript2.json b/test/util/data/txcreatescript2.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatescript2.json rename to test/util/data/txcreatescript2.json diff --git a/src/test/data/txcreatesignv1.hex b/test/util/data/txcreatesignv1.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatesignv1.hex rename to test/util/data/txcreatesignv1.hex diff --git a/src/test/data/txcreatesignv1.json b/test/util/data/txcreatesignv1.json old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatesignv1.json rename to test/util/data/txcreatesignv1.json diff --git a/src/test/data/txcreatesignv2.hex b/test/util/data/txcreatesignv2.hex old mode 100755 new mode 100644 similarity index 100% rename from src/test/data/txcreatesignv2.hex rename to test/util/data/txcreatesignv2.hex