Compare commits

..

6 commits

Author SHA1 Message Date
Anthony Fieroni
afe3eec551 Rebase + more fixes
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
2019-09-27 19:49:15 +03:00
Anthony Fieroni
eb810178e5 Fix rpc tests
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
2019-09-27 14:18:39 +03:00
Anthony Fieroni
30f8402629 Fix amount in tests
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
2019-09-27 14:18:39 +03:00
Anthony Fieroni
50f32d0e66 Fix pow, max block size, still need some adjust
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
2019-09-27 14:18:39 +03:00
Anthony Fieroni
6697207ac1 Partial fix, still need investigation in wallet and block generator tests
Signed-off-by: Anthony Fieroni <bvbfan@abv.bg>
2019-09-27 14:18:39 +03:00
Brannon King
92a3df1571 in progress on making py tests run 2019-09-27 14:18:39 +03:00
132 changed files with 1477 additions and 5144 deletions

View file

@ -1,8 +1,8 @@
<!-- This issue tracker is only for technical issues related to lbrycrd (the LBRY blockchain).
<!-- This issue tracker is only for technical issues related to Bitcoin Core.
General questions and/or support requests are best directed to the community chat at https://chat.lbry.org.
General bitcoin questions and/or support requests are best directed to the Bitcoin StackExchange at https://bitcoin.stackexchange.com.
For reporting security issues, please email security@lbry.com.
For reporting security issues, please read instructions at https://bitcoincore.org/en/contact/.
If the node is "stuck" during sync or giving "block checksum mismatch" errors, please ensure your hardware is stable by running memtest and observe CPU temperature with a load-test tool such as linpack before creating an issue! -->
@ -13,7 +13,7 @@ If the node is "stuck" during sync or giving "block checksum mismatch" errors, p
<!--- How reliably can you reproduce the issue, what are the steps to do so? -->
<!-- What version of lbrycrd are you using, where did you get it (website, self-compiled, etc)? -->
<!-- What version of Bitcoin Core are you using, where did you get it (website, self-compiled, etc)? -->
<!-- What type of machine are you observing the error on (OS/CPU and disk type)? -->

View file

@ -7,6 +7,7 @@ cache:
stages:
- build
- test
- quality
jobs:
include:
@ -14,7 +15,7 @@ jobs:
- &build-template
stage: build
name: linux
env: NAME=linux DOCKER_IMAGE=lbry/build_lbrycrd_gcc EXT=
env: NAME=linux EXT=
os: linux
dist: xenial
language: minimal
@ -22,9 +23,8 @@ jobs:
- docker
install:
- mkdir -p ${HOME}/ccache
- docker pull $DOCKER_IMAGE
- docker pull $DOCKER_BUILD_IMAGE
script:
- echo "build..."
- docker run -v "$(pwd):/lbrycrd" -v "${HOME}/ccache:/ccache" -w /lbrycrd -e CCACHE_DIR=/ccache ${DOCKER_IMAGE} packaging/build_${NAME}_64bit.sh
before_deploy:
- mkdir -p dist
@ -48,11 +48,11 @@ jobs:
- <<: *build-template
name: windows
env: NAME=windows DOCKER_IMAGE=lbry/build_lbrycrd EXT=.exe
env: NAME=windows EXT=.exe
- <<: *build-template
name: osx
env: NAME=darwin DOCKER_IMAGE=lbry/build_lbrycrd EXT=
env: NAME=darwin EXT=
before_install:
- mkdir -p ./depends/SDKs && pushd depends/SDKs && curl -C - ${MAC_OS_SDK} | tar --skip-old-files -xJ && popd
@ -63,7 +63,7 @@ jobs:
dist: xenial
language: minimal
git:
clone: false
depth: 3
install:
- mkdir -p testrun && cd testrun
- curl http://build.lbry.io/lbrycrd/${TRAVIS_BRANCH}/lbrycrd-${NAME}-test.zip -o temp.zip
@ -78,11 +78,20 @@ jobs:
services:
- docker
script:
- docker pull lbry/wine
- docker run -v "$(pwd):/test" -e "WINEDEBUG=-all" -e "TRIEHASH_FUZZER_BLOCKS=1000" -it lbry/wine wine "/test/test_lbrycrd.exe"
- docker pull $DOCKER_WINE_IMAGE
- docker run -v "$(pwd):/test" -e "WINEDEBUG=-all" -e "TRIEHASH_FUZZER_BLOCKS=1000" -it $DOCKER_WINE_IMAGE wine "/test/test_lbrycrd.exe"
- <<: *test-template
os: osx
osx_image: xcode8.3
env: NAME=darwin
- stage: quality
name: "check format"
os: linux
dist: xenial
language: minimal
install:
- sudo apt-get install -y clang-format-3.9
script: git diff -U0 origin/master -- '*.h' '*.cpp' | ./contrib/devtools/clang-format-diff.py -p1

113
README.md
View file

@ -1,35 +1,14 @@
# LBRYcrd - The LBRY blockchain
[![Build Status](https://travis-ci.org/lbryio/lbrycrd.svg?branch=master)](https://travis-ci.org/lbryio/lbrycrd)
[![MIT licensed](https://img.shields.io/dub/l/vibe-d.svg?style=flat)](https://github.com/lbryio/lbry-desktop/blob/master/LICENSE)
LBRYcrd uses a blockchain similar to bitcoin's to implement an index and payment system for content on the LBRY network. It is a fork of [bitcoin core](https://github.com/bitcoin/bitcoin). In addition to the libraries used by bitcoin, LBRYcrd also uses [icu4c](https://github.com/unicode-org/icu/tree/master/icu4c).
LBRYcrd uses a blockchain similar to bitcoin's to implement an index and payment system for content on the LBRY network. It is a fork of bitcoin core. In addition to the libraries used by bitcoin, LBRYcrd also uses icu4c.
Please read the [lbry.tech overview](https://lbry.tech/overview) for a general understanding of the LBRY pieces. From there you could read the [LBRY spec](https://spec.lbry.com/) for specifics on the data in the blockchain.
## Table of Contents
1. [Installation](#installation)
2. [Usage](#usage)
1. [Examples](#examples)
2. [Data directory](#data-directory)
3. [Running from Source](#running-from-source)
1. [Ubuntu with pulled static dependencies](#ubuntu-with-pulled-static-dependencies)
2. [Ubuntu with local shared dependencies](#ubuntu-with-local-shared-dependencies)
3. [MacOS (cross-compiled)](<#macos-(cross-compiled)>)
4. [MacOS with local shared dependencies](#macos-with-local-shared-dependencies)
5. [Windows (cross-compiled)](<#windows-(cross-compiled)>)
6. [Use with CLion](#use-with-clion)
4. [Contributing](#contributing)
- [Testnet](#testnet)
5. [Mailing List](#mailing-list)
6. [License](#license)
7. [Security](#security)
8. [Contact](#contact)
Please read the [lbry.tech overview](https://lbry.tech/overview) for a general understanding of the LBRY pieces. From there you could read the [LBRY spec](https://spec.lbry.com/) for specifics on the data in the blockchain.
## Installation
Latest binaries are available from https://github.com/lbryio/lbrycrd/releases. There is no installation procedure; the CLI binaries will run as-is and will have any uncommon dependencies statically linked into the binary. The QT GUI is not supported. LBRYcrd is distributed as a collection of executable files; traditional installers are not provided.
Latest binaries are available from https://github.com/lbryio/lbrycrd/releases. There is no installation procedure; the CLI binaries will run as-is and will have any uncommon dependencies statically linked into the binary. The QT GUI is not supported. LBRYcrd is distributed as a collection of executable files; traditional installers are not provided.
## Usage
@ -37,7 +16,7 @@ The `lbrycrdd` executable will start a LBRYcrd node and connect you to the LBRYc
to interact with lbrycrdd through the command line. Command-line help for both executables are available through
the "--help" flag (e.g. `lbrycrdd --help`). Examples:
#### Examples
#### Examples:
Run `./lbrycrdd -server -daemon` to start lbrycrdd in the background.
@ -46,8 +25,7 @@ Run `./lbrycrd-cli -getinfo` to check for some basic information about your LBRY
Run `./lbrycrd-cli help` to get a list of all commands that you can run. To get help on specific commands run `./lbrycrd-cli [command_name] help`
Test locally:
```sh
```
./lbrycrdd -server -regtest -txindex # run this in its own window
./lbrycrd-cli -regtest generate 120 # mine 20 spendable coins
./lbrycrd-cli -regtest claimname my_name deadbeef 1 # hold a name claim with 1 coin
@ -57,26 +35,24 @@ Test locally:
./lbrycrd-cli -regtest stop # kill lbrycrdd
rm -fr ~/.lbrycrd/regtest/ # destroy regtest data
```
For further understanding of a "regtest" setup, see the local stack setup instructions here: https://lbry.tech/resources/regtest-setup
The CLI help is also browsable online at https://lbry.tech/api/blockchain
#### Data directory
#### Data directory:
Lbrycrdd will use the below default data directories (changeable with -datadir):
```sh
```
Windows: %APPDATA%\lbrycrd
Mac: ~/Library/Application Support/lbrycrd
Unix: ~/.lbrycrd
```
The data directory contains various things such as your default wallet (wallet.dat), debug logs (debug.log), and blockchain data. You can optionally create a configuration file lbrycrd.conf in the default data directory which will be used by default when running lbrycrdd.
For a list of configuration parameters, run `./lbrycrdd --help`. Below is a sample lbrycrd.conf to enable JSON RPC server on lbrycrdd.
```sh
```
rpcuser=lbry
rpcpassword=xyz123456790
daemon=1
@ -85,19 +61,15 @@ txindex=1
```
## Running from Source
The easiest way to compile is to utilize the Docker image that contains the necessary compilers: lbry/build_lbrycrd. This will allow you to reproduce the build as made on our build servers. In this sample we map a local lbrycrd folder and a local ccache folder inside the image:
```sh
The easiest way to compile is to utilize the Docker image that contains the necessary compilers: lbry/build_lbrycrd. This will allow you to reproduce the build as made on our build servers. I this sample we map a local lbrycrd folder and a local ccache folder inside the image:
```
git clone https://github.com/lbryio/lbrycrd.git
cd lbrycrd
docker run -v "$(pwd):/lbrycrd" --rm -v "${HOME}/ccache:/ccache" -w /lbrycrd -e CCACHE_DIR=/ccache lbry/build_lbrycrd packaging/build_linux_64bit.sh
```
Some examples of compiling directly:
#### Ubuntu with pulled static dependencies
```sh
#### Ubuntu with pulled static dependencies:
```
sudo apt install build-essential git libtool autotools-dev automake pkg-config bsdmainutils curl ca-certificates
git clone https://github.com/lbryio/lbrycrd.git
cd lbrycrd
@ -105,20 +77,16 @@ cd lbrycrd
./src/test/test_lbrycrd
```
Other Linux distros would be similar. The build shell script is fairly trivial; take a peek at its contents.
#### Ubuntu with local shared dependencies
#### Ubuntu with local shared dependencies:
Note: using untested dependencies may lead to conflicting results.
```sh
```
sudo add-apt-repository ppa:bitcoin/bitcoin
sudo apt-get update
sudo apt-get install libdb4.8-dev libdb4.8++-dev libicu-dev libssl-dev libevent-dev \
sudo apt-get install libdb4.8-dev libdb4.8++-dev libicu-dev libssl-dev libevent-dev \
build-essential git libtool autotools-dev automake pkg-config bsdmainutils curl ca-certificates \
libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev
# optionally include libminiupnpc-dev libzmq3-dev
git clone https://github.com/lbryio/lbrycrd.git
@ -129,13 +97,11 @@ make -j$(nproc)
./src/lbrycrdd -server ...
```
#### MacOS (cross-compiled)
```sh
#### MacOS (cross-compiled):
```
sudo apt-get install clang llvm git libtool autotools-dev automake pkg-config bsdmainutils curl ca-certificates \
libboost-system-dev libboost-filesystem-dev libboost-chrono-dev libboost-test-dev libboost-thread-dev
git clone https://github.com/lbryio/lbrycrd.git
cd lbrycrd
# download MacOS SDK from your favorite source
@ -144,12 +110,9 @@ tar ... extract SDK to depends/SDKs/MacOSX10.11.sdk
./packaging/build_darwin_64bit.sh
```
Look in packaging/build_darwin_64bit.sh for further understanding.
#### MacOS with local shared dependencies
```sh
#### MacOS with local shared dependencies:
```
brew install boost berkeley-db@4 icu4c libevent
# fix conflict with gawk pulled first:
brew reinstall readline
@ -164,17 +127,14 @@ CONFIG_SITE=$(pwd)/depends/x86_64-apple-darwin15.6.0/share/config.site ./configu
make -j$(sysctl -n hw.ncpu)
```
#### Windows (cross-compiled)
#### Windows (cross-compiled):
Compiling on MS Windows (outside of WSL) is not supported. The Windows build is cross-compiled from Linux like so:
```sh
```
sudo apt-get install build-essential git libtool autotools-dev automake pkg-config bsdmainutils curl ca-certificates \
g++-mingw-w64-x86-64 mingw-w64-x86-64-dev
update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix
git clone https://github.com/lbryio/lbrycrd.git
cd lbrycrd
./packaging/build_windows_64bit.sh
@ -183,16 +143,13 @@ cd lbrycrd
If you encounter any errors, please check `doc/build-*.md` for further instructions. If you're still stuck, [create an issue](https://github.com/lbryio/lbrycrd/issues/new) with the output of that command, your system info, and any other information you think might be helpful. The scripts in the packaging folder are simple and will grant extra light on the build process as needed.
#### Use with CLion
#### Use with CLion:
CLion has not traditionally supported Autotools projects, although some progress on that is now in the works. We do include a cmake build file for compiling lbrycrd. See contrib/cmake. Alas, CLion doesn't support external projects in cmake, so that particular approach is also insufficient. CLion does support "compile_commands.json" projects. Fortunately, this can be easily generated for lbrycrd like so:
```sh
```
pip install --user compiledb
./autogen.sh && ./configure --enable-static=no --enable-shared --with-pic --without-gui CXXFLAGS="-O0 -g" CFLAGS="-O0 -g" # or whatever normal lbrycrd config
compiledb make -j10
```
Then open the newly generated compile_commands.json file as a project in CLion. Debugging is supported if you compiled with `-g`. To enable that you will need to create a target in CLion by going to File -> Settings -> Build -> Custom Build Targets. Add an empty target with your choice of name. From there you can go to "Edit Configurations", typically found in a drop-down at the top of the editor. Add a Custom Build Application, select your new target, select the compiled file (i.e. test_lbrycrd or lbrycrdd, etc), and then add any necessary command line parameters. Ensure that there is nothing in the "Before launch" section.
## Contributing
@ -210,8 +167,8 @@ regularly to indicate new official, stable release versions.
Testing and code review is the bottleneck for development; we get more pull
requests than we can review and test on short notice. Please be patient and help out by testing
other people's pull requests, and remember this is a security-critical project where any mistake might cost people
lots of money. Developers are strongly encouraged to write [unit tests](/src/test/README.md) for new code and to
submit new unit tests for old code. Unit tests are compiled by default and can be run with `src/test/test_lbrycrd`
lots of money. Developers are strongly encouraged to write [unit tests](/doc/unit-tests.md) for new code and to
submit new unit tests for old code. Unit tests are compiled by default and can be run with `src/test/test_lbrycrd`.
The Travis CI system makes sure that every pull request is built, and that unit and sanity tests are automatically run. See https://travis-ci.org/lbryio/lbrycrd
@ -219,11 +176,7 @@ The Travis CI system makes sure that every pull request is built, and that unit
Testnet is maintained for testing purposes and can be accessed using the command `./lbrycrdd -testnet`. If you would like to obtain testnet credits, please contact brannon@lbry.com or grin@lbry.com .
It is easy to solo mine on testnet. (It's easy on mainnet too, but much harder to win.) For instructions see [SGMiner](https://github.com/lbryio/sgminer-gm) and [Mining Contributions](https://github.com/lbryio/lbrycrd/tree/master/contrib/mining)
## Mailing List
We maintain a mailing list for notifications of upgrades, security issues, and soft/hard forks. To join, visit [https://lbry.com/forklist](https://lbry.com/forklist).
It is easy to solo mine on testnet. (It's easy on mainnet too, but much harder to win.) For instructions see https://github.com/lbryio/sgminer-gm and https://github.com/lbryio/lbrycrd/tree/master/contrib/mining
## License
@ -231,9 +184,11 @@ This project is MIT licensed. For the full license, see [LICENSE](LICENSE).
## Security
We take security seriously. Please contact [security@lbry.com](mailto:security@lbry.com) regarding any security issues.
Our PGP key is [here](https://lbry.com/faq/pgp-key) if you need it.
We take security seriously. Please contact security@lbry.com regarding any security issues.
Our PGP key is [here](https://keybase.io/lbry/key.asc) if you need it.
## Contact
The primary contact for this project is [@BrannonKing](https://github.com/BrannonKing) (brannon@lbry.com)

View file

@ -7,7 +7,7 @@ export LC_ALL=C
set -e
srcdir="$(dirname $0)"
cd "$srcdir"
if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="$(which glibtoolize 2>/dev/null)"; then
if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then
LIBTOOLIZE="${GLIBTOOLIZE}"
export LIBTOOLIZE
fi

View file

@ -3,9 +3,9 @@ AC_PREREQ([2.60])
define(_CLIENT_VERSION_MAJOR, 0)
define(_CLIENT_VERSION_MINOR, 17)
define(_CLIENT_VERSION_REVISION, 3)
define(_CLIENT_VERSION_BUILD, 3)
define(_CLIENT_VERSION_BUILD, 0)
define(_CLIENT_VERSION_IS_RELEASE, true)
define(_COPYRIGHT_YEAR, 2021)
define(_COPYRIGHT_YEAR, 2019)
define(_COPYRIGHT_HOLDERS,[The %s developers])
define(_COPYRIGHT_HOLDERS_SUBSTITUTION,[[LBRYcrd Core]])
AC_INIT([LBRYcrd Core],[_CLIENT_VERSION_MAJOR._CLIENT_VERSION_MINOR._CLIENT_VERSION_REVISION],[https://github.com/lbryio/lbrycrd/issues],[lbrycrd],[https://lbry.com/])

View file

@ -36,13 +36,13 @@ if [ -z "${CODESIGN_ALLOCATE}" ]; then
fi
find ${TEMPDIR} -name "*.sign" | while read i; do
SIZE=$(stat -c %s "${i}")
TARGET_FILE="$(echo "${i}" | sed 's/\.sign$//')"
SIZE=`stat -c %s "${i}"`
TARGET_FILE="`echo "${i}" | sed 's/\.sign$//'`"
echo "Allocating space for the signature of size ${SIZE} in ${TARGET_FILE}"
${CODESIGN_ALLOCATE} -i "${TARGET_FILE}" -a ${ARCH} ${SIZE} -o "${i}.tmp"
OFFSET=$(${PAGESTUFF} "${i}.tmp" -p | tail -2 | grep offset | sed 's/[^0-9]*//g')
OFFSET=`${PAGESTUFF} "${i}.tmp" -p | tail -2 | grep offset | sed 's/[^0-9]*//g'`
if [ -z ${QUIET} ]; then
echo "Attaching signature at offset ${OFFSET}"
fi

View file

@ -27,19 +27,19 @@ ${CODESIGN} -f --file-list ${TEMPLIST} "$@" "${BUNDLE}"
grep -v CodeResources < "${TEMPLIST}" | while read i; do
TARGETFILE="${BUNDLE}/`echo "${i}" | sed "s|.*${BUNDLE}/||"`"
SIZE=$(pagestuff "$i" -p | tail -2 | grep size | sed 's/[^0-9]*//g')
OFFSET=$(pagestuff "$i" -p | tail -2 | grep offset | sed 's/[^0-9]*//g')
SIZE=`pagestuff "$i" -p | tail -2 | grep size | sed 's/[^0-9]*//g'`
OFFSET=`pagestuff "$i" -p | tail -2 | grep offset | sed 's/[^0-9]*//g'`
SIGNFILE="${TEMPDIR}/${OUTROOT}/${TARGETFILE}.sign"
DIRNAME="$(dirname "${SIGNFILE}")"
DIRNAME="`dirname "${SIGNFILE}"`"
mkdir -p "${DIRNAME}"
echo "Adding detached signature for: ${TARGETFILE}. Size: ${SIZE}. Offset: ${OFFSET}"
dd if="$i" of="${SIGNFILE}" bs=1 skip=${OFFSET} count=${SIZE} 2>/dev/null
done
grep CodeResources < "${TEMPLIST}" | while read i; do
TARGETFILE="${BUNDLE}/$(echo "${i}" | sed "s|.*${BUNDLE}/||")"
TARGETFILE="${BUNDLE}/`echo "${i}" | sed "s|.*${BUNDLE}/||"`"
RESOURCE="${TEMPDIR}/${OUTROOT}/${TARGETFILE}"
DIRNAME="$(dirname "${RESOURCE}")"
DIRNAME="`dirname "${RESOURCE}"`"
mkdir -p "${DIRNAME}"
echo "Adding resource for: \"${TARGETFILE}\""
cp "${i}" "${RESOURCE}"

View file

@ -36,7 +36,7 @@ insert into coins(name, symbol, symbol2, algo, enable, auto_ready, rpcuser, rpcp
values('Local LBRY Instance', 'LBC', 'LBC', 'lbry', 1, 1, 'ruser', 'rpswd', '127.0.0.1', 19245, 1, 'utf-8', 0, 1, 0, 0, 0);
exit
```
Use port 19245 for testnet, port 9245 for main. Set usesegwit to 1 after the segwit fork is enabled on December 11, 2019.
Use port 19245 for testnet, port 9245 for main.
#### 3. Run the stratum server:
```
docker run --network host -d lbry/yiimp_stratum
@ -47,11 +47,10 @@ docker run --network host -it lbry/yiimp_stratum bash
cat config/lbry.conf
./stratum config/lbry
```
When testing with an ASIC you may need to modify the TCP server address in said lbry.conf file to be an external IP address.
#### 4. Connect sgminer to it:
```
sgminer -k lbry -o stratum+tcp://127.0.0.1:3334/ -D -T -O mn824Su1wX7ip8WcNYzXwwWqvBvkeWGRo6:x
```
The username there is the account to receive payments from the pool. The password is unused. Tested with https://github.com/lbryio/sgminer-gm.
You can use whatever miner you prefer.
You can use whatever miner you prefer.

View file

@ -23,7 +23,7 @@ TIMESERVER=http://timestamp.comodoca.com
CERTFILE="win-codesign.cert"
mkdir -p "${OUTSUBDIR}"
basename -a $(ls -1 "${SRCDIR}"/*-unsigned.exe) | while read UNSIGNED; do
basename -a `ls -1 "${SRCDIR}"/*-unsigned.exe` | while read UNSIGNED; do
echo Signing "${UNSIGNED}"
"${OSSLSIGNCODE}" sign -certs "${CERTFILE}" -t "${TIMESERVER}" -in "${SRCDIR}/${UNSIGNED}" -out "${WORKDIR}/${UNSIGNED}" "$@"
"${OSSLSIGNCODE}" extract-signature -pem -in "${WORKDIR}/${UNSIGNED}" -out "${OUTSUBDIR}/${UNSIGNED}.pem" && rm "${WORKDIR}/${UNSIGNED}"

View file

@ -131,7 +131,7 @@ $(host_prefix)/share/config.site : config.site.in $(host_prefix)/.stamp_$(final_
-e 's|@build_os@|$(build_os)|' \
-e 's|@host_os@|$(host_os)|' \
-e 's|@CFLAGS@|$(strip $(host_CFLAGS) $(host_$(release_type)_CFLAGS))|' \
-e 's|@CXXFLAGS@|$(strip -pipe $(host_$(release_type)_CXXFLAGS))|' \
-e 's|@CXXFLAGS@|$(strip $(host_CXXFLAGS) $(host_$(release_type)_CXXFLAGS))|' \
-e 's|@CPPFLAGS@|$(strip $(host_CPPFLAGS) $(host_$(release_type)_CPPFLAGS))|' \
-e 's|@LDFLAGS@|$(strip $(host_LDFLAGS) $(host_$(release_type)_LDFLAGS))|' \
-e 's|@allow_host_packages@|$(ALLOW_HOST_PACKAGES)|' \

File diff suppressed because it is too large Load diff

View file

@ -7,13 +7,12 @@ darwin_CC=clang -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) -isysroo
darwin_CXX=clang++ -target $(host) -mmacosx-version-min=$(OSX_MIN_VERSION) -isysroot $(OSX_SDK) -mlinker-version=$(LD64_VERSION) -stdlib=libc++ -B $(host_prefix)/native/bin
darwin_CFLAGS=-pipe
darwin_CXXFLAGS=$(darwin_CFLAGS) -std=c++11
darwin_CXXFLAGS=$(darwin_CFLAGS)
darwin_release_CFLAGS=-O2 -g
darwin_release_CFLAGS=-O2
darwin_release_CXXFLAGS=$(darwin_release_CFLAGS)
darwin_debug_CFLAGS=-Og -g
darwin_debug_CXXFLAGS=-O0 -g
darwin_native_toolchain=native_cctools
darwin_debug_CFLAGS=-Og
darwin_debug_CXXFLAGS=$(darwin_debug_CFLAGS)
darwin_native_toolchain=native_cctools

View file

@ -1,14 +1,11 @@
linux_CFLAGS=-pipe
linux_CXXFLAGS=$(linux_CFLAGS) -std=c++11
linux_CXXFLAGS=$(linux_CFLAGS)
linux_release_CFLAGS=-O3 -g
ifeq (1,$(shell ldd --version | head -1 | awk '{print $$NF < 2.28}'))
linux_release_CFLAGS+= -include $(BASEDIR)/glibc_version_header/force_link_glibc_2.19.h
endif
linux_release_CFLAGS=-O2
linux_release_CXXFLAGS=$(linux_release_CFLAGS)
linux_debug_CFLAGS=-O1 -g
linux_debug_CXXFLAGS=-O0 -g
linux_debug_CFLAGS=-Og
linux_debug_CXXFLAGS=$(linux_debug_CFLAGS)
linux_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC

View file

@ -1,11 +1,10 @@
mingw32_CFLAGS=-pipe
mingw32_CXXFLAGS=$(mingw32_CFLAGS) -std=c++11
mingw32_CXXFLAGS=$(mingw32_CFLAGS)
mingw32_release_CFLAGS=-O2 -g
mingw32_release_CFLAGS=-O2
mingw32_release_CXXFLAGS=$(mingw32_release_CFLAGS)
mingw32_debug_CFLAGS=-O1 -g
mingw32_debug_CXXFLAGS=-O0 -g
mingw32_debug_CFLAGS=-O1
mingw32_debug_CXXFLAGS=$(mingw32_debug_CFLAGS)
mingw32_debug_CPPFLAGS=-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC

View file

@ -1,6 +1,6 @@
package=bdb
$(package)_version=4.8.30
$(package)_download_path=https://download.oracle.com/berkeley-db
$(package)_download_path=http://download.oracle.com/berkeley-db
$(package)_file_name=db-$($(package)_version).NC.tar.gz
$(package)_sha256_hash=12edc0df75bf9abd7f82f821795bcee50f42cb2e5f76a6a281b85732798364ef
$(package)_build_subdir=build_unix
@ -9,7 +9,7 @@ define $(package)_set_vars
$(package)_config_opts=--disable-shared --enable-cxx --disable-replication
$(package)_config_opts_mingw32=--enable-mingw
$(package)_config_opts_linux=--with-pic
$(package)_cppflags_mingw32=-DUNICODE -D_UNICODE
$(package)_cxxflags=-std=c++11
endef
define $(package)_preprocess_cmds
@ -29,4 +29,3 @@ endef
define $(package)_stage_cmds
$(MAKE) DESTDIR=$($(package)_staging_dir) install_lib install_include
endef

View file

@ -1,6 +1,6 @@
package=boost
$(package)_version=1_69_0
$(package)_download_path=https://boostorg.jfrog.io/artifactory/main/release/1.69.0/source/
$(package)_download_path=https://dl.bintray.com/boostorg/release/1.69.0/source/
$(package)_file_name=$(package)_$($(package)_version).tar.bz2
$(package)_sha256_hash=8f32d4617390d1c2d16f26a27ab60d97807b35440d45891fa340fc2648b04406
$(package)_dependencies=icu

View file

@ -22,6 +22,7 @@ define $(package)_preprocess_cmds
PKG_CONFIG_SYSROOT_DIR=/ \
PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig \
PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig \
sed -i.old 's/^GEN_DEPS.cc.*/& $(CXXFLAGS)/' source/config/mh-mingw* && \
mkdir -p build && cd build && \
../source/runConfigureICU Linux $($(package)_standard_opts) CXXFLAGS=-std=c++11 && \
$(MAKE) && cd ..
@ -31,8 +32,6 @@ define $(package)_config_cmds
PKG_CONFIG_SYSROOT_DIR=/ \
PKG_CONFIG_LIBDIR=$(host_prefix)/lib/pkgconfig \
PKG_CONFIG_PATH=$(host_prefix)/share/pkgconfig \
sed -i.old 's|^GEN_DEPS.c=.*|& $($(package)_cflags)|' config/mh-mingw* && \
sed -i.old 's|^GEN_DEPS.cc=.*|& $($(package)_cxxflags)|' config/mh-mingw* && \
$($(package)_autoconf)
endef

View file

@ -27,5 +27,4 @@ define $(package)_stage_cmds
endef
define $(package)_postprocess_cmds
rm lib/*.la
endef

View file

@ -1,6 +1,6 @@
package=miniupnpc
$(package)_version=2.0.20180203
$(package)_download_path=https://miniupnp.tuxfamily.org/files/
$(package)_download_path=http://miniupnp.free.fr/files
$(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=90dda8c7563ca6cd4a83e23b3c66dbbea89603a1675bfdb852897c2c9cc220b7

View file

@ -5,7 +5,7 @@ $(package)_file_name=$(package)-$($(package)_version).tar.gz
$(package)_sha256_hash=8f9faeaebad088e772f4ef5e38252d472be4d878c6b3a2718c10a4fcebe7a41c
define $(package)_set_vars
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc) $($(package)_cflags) $($(package)_cppflags)"
$(package)_config_env=AR="$($(package)_ar)" RANLIB="$($(package)_ranlib)" CC="$($(package)_cc)"
$(package)_config_opts=--prefix=$(host_prefix) --openssldir=$(host_prefix)/etc/openssl
$(package)_config_opts+=no-camellia
$(package)_config_opts+=no-capieng
@ -42,6 +42,7 @@ $(package)_config_opts+=no-weak-ssl-ciphers
$(package)_config_opts+=no-whirlpool
$(package)_config_opts+=no-zlib
$(package)_config_opts+=no-zlib-dynamic
$(package)_config_opts+=$($(package)_cflags) $($(package)_cppflags)
$(package)_config_opts_linux=-fPIC -Wa,--noexecstack
$(package)_config_opts_x86_64_linux=linux-x86_64
$(package)_config_opts_i686_linux=linux-generic32

View file

@ -4,6 +4,7 @@ $(package)_download_path=$(native_$(package)_download_path)
$(package)_file_name=$(native_$(package)_file_name)
$(package)_sha256_hash=$(native_$(package)_sha256_hash)
$(package)_dependencies=native_$(package)
$(package)_cxxflags=-std=c++11
define $(package)_set_vars
$(package)_config_opts=--disable-shared --with-protoc=$(build_prefix)/bin/protoc

View file

@ -6,10 +6,9 @@ $(package)_sha256_hash=bcbabe1e2c7d0eec4ed612e10b94b112dd5f06fcefa994a0c79a45d83
$(package)_patches=0001-fix-build-with-older-mingw64.patch 0002-disable-pthread_set_name_np.patch
define $(package)_set_vars
$(package)_config_opts=--without-docs --disable-shared --without-libsodium --disable-curve --disable-curve-keygen --disable-perf --disable-Werror --disable-drafts
$(package)_config_opts += --without-libsodium --without-libgssapi_krb5 --without-pgm --without-norm --without-vmci
$(package)_config_opts += --disable-libunwind --disable-radix-tree --without-gcov
$(package)_config_opts=--without-docs --disable-shared --without-libsodium --disable-curve --disable-curve-keygen --disable-perf --disable-Werror
$(package)_config_opts_linux=--with-pic
$(package)_cxxflags=-std=c++11
endef
define $(package)_preprocess_cmds
@ -32,5 +31,5 @@ endef
define $(package)_postprocess_cmds
sed -i.old "s/ -lstdc++//" lib/pkgconfig/libzmq.pc && \
rm -rf bin share lib/*.la
rm -rf bin share
endef

View file

@ -30,13 +30,13 @@ if which ccache >/dev/null; then
fi
pushd depends
make -j$(getconf _NPROCESSORS_ONLN) HOST=x86_64-apple-darwin14 NO_QT=1 V=1
make -j`getconf _NPROCESSORS_ONLN` HOST=x86_64-apple-darwin14 NO_QT=1 V=1
popd
./autogen.sh
DEPS_DIR=$(pwd)/depends/x86_64-apple-darwin14
DEPS_DIR=`pwd`/depends/x86_64-apple-darwin14
CONFIG_SITE=${DEPS_DIR}/share/config.site ./configure --enable-reduce-exports --without-gui --with-icu="${DEPS_DIR}" --enable-static --disable-shared
make -j$(getconf _NPROCESSORS_ONLN)
make -j`getconf _NPROCESSORS_ONLN`
${DEPS_DIR}/native/bin/x86_64-apple-darwin14-strip src/lbrycrdd src/lbrycrd-cli src/lbrycrd-tx
if which ccache >/dev/null; then

View file

@ -20,13 +20,13 @@ export CXXFLAGS="${CXXFLAGS:--frecord-gcc-switches}"
echo "CXXFLAGS set to $CXXFLAGS"
cd depends
make -j$(getconf _NPROCESSORS_ONLN) HOST=x86_64-pc-linux-gnu NO_QT=1 V=1
make -j`getconf _NPROCESSORS_ONLN` HOST=x86_64-pc-linux-gnu NO_QT=1 V=1
cd ..
./autogen.sh
DEPS_DIR=$(pwd)/depends/x86_64-pc-linux-gnu
DEPS_DIR=`pwd`/depends/x86_64-pc-linux-gnu
CONFIG_SITE=${DEPS_DIR}/share/config.site ./configure --enable-static --disable-shared --with-pic --without-gui
make -j$(getconf _NPROCESSORS_ONLN)
make -j`getconf _NPROCESSORS_ONLN`
strip src/lbrycrdd src/lbrycrd-cli src/lbrycrd-tx
if which ccache >/dev/null; then
@ -34,4 +34,4 @@ if which ccache >/dev/null; then
ccache -s
fi
echo "Linux 64bit build is complete"
echo "Linux 64bit build is complete"

View file

@ -20,14 +20,17 @@ if which ccache >/dev/null; then
ccache -ps
fi
export CXXFLAGS="${CXXFLAGS:--frecord-gcc-switches}"
echo "CXXFLAGS set to $CXXFLAGS"
pushd depends
make -j$(getconf _NPROCESSORS_ONLN) HOST=i686-w64-mingw32 NO_QT=1 V=1
make -j`getconf _NPROCESSORS_ONLN` HOST=i686-w64-mingw32 NO_QT=1 V=1
popd
./autogen.sh
DEPS_DIR=$(pwd)/depends/i686-w64-mingw32
DEPS_DIR=`pwd`/depends/i686-w64-mingw32
CONFIG_SITE=${DEPS_DIR}/share/config.site ./configure --prefix=/ --without-gui --with-icu="$DEPS_DIR" --enable-static --disable-shared
make -j$(getconf _NPROCESSORS_ONLN)
make -j`getconf _NPROCESSORS_ONLN`
i686-w64-mingw32-strip src/lbrycrdd.exe src/lbrycrd-cli.exe src/lbrycrd-tx.exe
if which ccache >/dev/null; then

View file

@ -19,14 +19,17 @@ if which ccache >/dev/null; then
ccache -ps
fi
export CXXFLAGS="${CXXFLAGS:--frecord-gcc-switches}"
echo "CXXFLAGS set to $CXXFLAGS"
pushd depends
make -j$(getconf _NPROCESSORS_ONLN) HOST=x86_64-w64-mingw32 NO_QT=1 V=1
make -j`getconf _NPROCESSORS_ONLN` HOST=x86_64-w64-mingw32 NO_QT=1 V=1
popd
./autogen.sh
DEPS_DIR=$(pwd)/depends/x86_64-w64-mingw32
DEPS_DIR=`pwd`/depends/x86_64-w64-mingw32
CONFIG_SITE=${DEPS_DIR}/share/config.site ./configure --prefix=/ --without-gui --with-icu="$DEPS_DIR" --enable-static --disable-shared
make -j$(getconf _NPROCESSORS_ONLN)
make -j`getconf _NPROCESSORS_ONLN`
x86_64-w64-mingw32-strip src/lbrycrdd.exe src/lbrycrd-cli.exe src/lbrycrd-tx.exe
if which ccache >/dev/null; then

View file

@ -41,7 +41,6 @@ BITCOIN_TESTS =\
test/blockchain_tests.cpp \
test/blockencodings_tests.cpp \
test/bloom_tests.cpp \
test/Checkpoints_tests.cpp \
test/bswap_tests.cpp \
test/checkqueue_tests.cpp \
test/coins_tests.cpp \

View file

@ -166,10 +166,10 @@ public:
consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1548288000; // Jan 24, 2019
// The best chain should have at least this much work.
consensus.nMinimumChainWork = uint256S("000000000000000000000000000000000000000000000499ed6684d1bf6f6fd3"); //946000
consensus.nMinimumChainWork = uint256S("00000000000000000000000000000000000000000000024108e3204a44a57a5a"); //621000
// By default assume that the signatures in ancestors of this block are valid.
consensus.defaultAssumeValid = uint256S("0d3b537afe49820e1c6efc555463f955251b1293c6e5130137e1e25744431172"); //946000
consensus.defaultAssumeValid = uint256S("7899464514d0d8854919e87eb234fd5f0c35d06418bd5fd3c1a8f7092b2a9317"); //620000
/**
* The message start string is designed to be unlikely to occur in normal data.
@ -195,11 +195,9 @@ public:
vSeeds.clear();
vFixedSeeds.clear();
vSeeds.emplace_back("dnsseed1.lbry.io"); // LBRY Inc
vSeeds.emplace_back("dnsseed2.lbry.io"); // LBRY Inc
vSeeds.emplace_back("dnsseed3.lbry.io"); // LBRY Inc
vSeeds.emplace_back("seed.lbry.grin.io"); // Grin
vSeeds.emplace_back("seed.allaboutlbc.com"); // Madiator2011
vSeeds.emplace_back("dnsseed1.lbry.io"); // lbry.io
vSeeds.emplace_back("dnsseed2.lbry.io"); // lbry.io
vSeeds.emplace_back("dnsseed3.lbry.io"); // lbry.io
base58Prefixes[PUBKEY_ADDRESS] = std::vector<unsigned char>(1, 0x55);
base58Prefixes[SCRIPT_ADDRESS] = std::vector<unsigned char>(1, 0x7a);
@ -207,6 +205,8 @@ public:
base58Prefixes[EXT_PUBLIC_KEY] = {0x04, 0x88, 0xB2, 0x1E};
base58Prefixes[EXT_SECRET_KEY] = {0x04, 0x88, 0xAD, 0xE4};
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));
bech32_hrp = "lbc";
vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));

View file

@ -62,8 +62,7 @@ bool CClaimScriptUndoAddOp::supportClaim(CClaimTrieCache& trieCache, const std::
if (LogAcceptCategory(BCLog::CLAIMS)) {
LogPrintf("--- [%lu]: OP_SUPPORT_CLAIM \"%s\" with claimId %s and tx prevout %s at index %d\n", nHeight, name,
claimId.GetHex(), point.hash.ToString(), point.n);
LogPrintf(
"%s: (txid: %s, nOut: %d) Removing support for %s, claimId: %s, from the claim trie due to block disconnect\n",
LogPrintf("%s: (txid: %s, nOut: %d) Removing support for %s, claimId: %s, from the claim trie due to block disconnect\n",
__func__, point.hash.ToString(), point.n, name, claimId.ToString());
}
bool res = trieCache.undoAddSupport(name, point, nHeight);

View file

@ -2,16 +2,16 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#ifndef CLAIMSCRIPTOP_H
#define CLAIMSCRIPTOP_H
#ifndef BITCOIN_CLAIMSCRIPTOP_H
#define BITCOIN_CLAIMSCRIPTOP_H
#include "amount.h"
#include "claimtrie.h"
#include "hash.h"
#include "primitives/transaction.h"
#include "script/script.h"
#include "uint256.h"
#include "util.h"
#include <amount.h>
#include <claimtrie.h>
#include <hash.h>
#include <primitives/transaction.h>
#include <script/script.h>
#include <uint256.h>
#include <util.h>
#include <string>
#include <vector>
@ -242,4 +242,4 @@ struct CUpdateCacheCallbacks
*/
void UpdateCache(const CTransaction& tx, CClaimTrieCache& trieCache, const CCoinsViewCache& view, int nHeight, const CUpdateCacheCallbacks& callbacks = {});
#endif // CLAIMSCRIPTOP_H
#endif // BITCOIN_CLAIMSCRIPTOP_H

View file

@ -208,15 +208,15 @@ COptional<const std::vector<queueEntryType<T>>> CClaimTrieCacheBase::getQueueCac
}
template <>
queueNameRowType* CClaimTrieCacheBase::getQueueCacheNameRow<CClaimValue>(const std::string& name, bool createIfNoExists)
queueNameRowType* CClaimTrieCacheBase::getQueueCacheNameRow<CClaimValue>(const std::string& name, bool createIfNotExists)
{
return getQueue(*(base->db), CLAIM_QUEUE_NAME_ROW, name, claimQueueNameCache, createIfNoExists);
return getQueue(*(base->db), CLAIM_QUEUE_NAME_ROW, name, claimQueueNameCache, createIfNotExists);
}
template <>
queueNameRowType* CClaimTrieCacheBase::getQueueCacheNameRow<CSupportValue>(const std::string& name, bool createIfNoExists)
queueNameRowType* CClaimTrieCacheBase::getQueueCacheNameRow<CSupportValue>(const std::string& name, bool createIfNotExists)
{
return getQueue(*(base->db), SUPPORT_QUEUE_NAME_ROW, name, supportQueueNameCache, createIfNoExists);
return getQueue(*(base->db), SUPPORT_QUEUE_NAME_ROW, name, supportQueueNameCache, createIfNotExists);
}
template <typename T>
@ -246,15 +246,15 @@ COptional<const queueNameRowType> CClaimTrieCacheBase::getQueueCacheNameRow(cons
}
template <>
expirationQueueRowType* CClaimTrieCacheBase::getExpirationQueueCacheRow<CClaimValue>(int nHeight, bool createIfNoExists)
expirationQueueRowType* CClaimTrieCacheBase::getExpirationQueueCacheRow<CClaimValue>(int nHeight, bool createIfNotExists)
{
return getQueue(*(base->db), CLAIM_EXP_QUEUE_ROW, nHeight, expirationQueueCache, createIfNoExists);
return getQueue(*(base->db), CLAIM_EXP_QUEUE_ROW, nHeight, expirationQueueCache, createIfNotExists);
}
template <>
expirationQueueRowType* CClaimTrieCacheBase::getExpirationQueueCacheRow<CSupportValue>(int nHeight, bool createIfNoExists)
expirationQueueRowType* CClaimTrieCacheBase::getExpirationQueueCacheRow<CSupportValue>(int nHeight, bool createIfNotExists)
{
return getQueue(*(base->db), SUPPORT_EXP_QUEUE_ROW, nHeight, supportExpirationQueueCache, createIfNoExists);
return getQueue(*(base->db), SUPPORT_EXP_QUEUE_ROW, nHeight, supportExpirationQueueCache, createIfNotExists);
}
template <typename T>
@ -266,8 +266,13 @@ expirationQueueRowType* CClaimTrieCacheBase::getExpirationQueueCacheRow(int, boo
bool CClaimTrieCacheBase::haveClaim(const std::string& name, const COutPoint& outPoint) const
{
auto it = find(name);
return it && it->haveClaim(outPoint);
auto it = nodesToAddOrUpdate.find(name);
if (it && it->haveClaim(outPoint))
return true;
if (it || nodesToDelete.count(name))
return false;
CClaimTrieData data;
return base->find(name, data) && data.haveClaim(outPoint);
}
bool CClaimTrieCacheBase::haveSupport(const std::string& name, const COutPoint& outPoint) const
@ -320,39 +325,70 @@ bool CClaimTrieCacheBase::haveSupportInQueue(const std::string& name, const COut
return haveInQueue<CSupportValue>(name, outPoint, nValidAtHeight);
}
void CClaimTrie::recurseNodes(const std::string& name, const CClaimTrieDataNode& current, std::function<recurseNodesCB> function) const {
CClaimTrieData data;
find(name, data);
data.hash = current.hash;
data.flags |= current.children.empty() ? 0 : CClaimTrieDataFlags::POTENTIAL_CHILDREN;
function(name, data, current.children);
for (auto& child: current.children) {
CClaimTrieDataNode node;
auto childName = name + child;
if (find(childName, node))
recurseNodes(childName, node, function);
}
}
std::size_t CClaimTrie::getTotalNamesInTrie() const
{
std::size_t count = 0;
for (auto it = begin(); it != end(); ++it)
if (!it->empty()) ++count;
CClaimTrieDataNode node;
if (find({}, node))
recurseNodes({}, node, [&count](const std::string &name, const CClaimTrieData &data, const std::vector<std::string>& children) {
count += !data.empty();
});
return count;
}
std::size_t CClaimTrie::getTotalClaimsInTrie() const
{
std::size_t count = 0;
for (auto it = begin(); it != end(); ++it)
count += it->claims.size();
CClaimTrieDataNode node;
if (find({}, node))
recurseNodes({}, node, [&count]
(const std::string &name, const CClaimTrieData &data, const std::vector<std::string>& children) {
count += data.claims.size();
});
return count;
}
CAmount CClaimTrie::getTotalValueOfClaimsInTrie(bool fControllingOnly) const
{
CAmount value_in_subtrie = 0;
for (auto it = begin(); it != end(); ++it) {
for (auto& claim : it->claims) {
value_in_subtrie += claim.nAmount;
if (fControllingOnly)
break;
}
}
CClaimTrieDataNode node;
if (find({}, node))
recurseNodes({}, node, [&value_in_subtrie, fControllingOnly]
(const std::string &name, const CClaimTrieData &data, const std::vector<std::string>& children) {
for (const auto &claim : data.claims) {
value_in_subtrie += claim.nAmount;
if (fControllingOnly)
break;
}
});
return value_in_subtrie;
}
bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& claim) const
{
auto it = find(name);
return it && it->getBestClaim(claim);
auto it = nodesToAddOrUpdate.find(name);
if (it && it->getBestClaim(claim))
return true;
if (it || nodesToDelete.count(name))
return false;
CClaimTrieData claims;
return base->find(name, claims) && claims.getBestClaim(claim);
}
template <typename T>
@ -374,9 +410,15 @@ CClaimSupportToName CClaimTrieCacheBase::getClaimsForName(const std::string& nam
auto supports = getSupportsForName(name);
insertRowsFromQueue(supports, name);
if (auto it = find(name)) {
if (auto it = nodesToAddOrUpdate.find(name)) {
claims = it->claims;
nLastTakeoverHeight = it->nHeightOfLastTakeover;
} else if (!nodesToDelete.count(name)) {
CClaimTrieData data;
if (base->find(name, data)) {
claims = data.claims;
nLastTakeoverHeight = data.nHeightOfLastTakeover;
}
}
insertRowsFromQueue(claims, name);
@ -411,79 +453,94 @@ void completeHash(uint256& partialHash, const std::string& key, std::size_t to)
.Finalize(partialHash.begin());
}
template <typename T>
using iCbType = std::function<void(T&)>;
template <typename TIterator>
uint256 recursiveMerkleHash(TIterator& it, const iCbType<TIterator>& process)
bool CClaimTrie::checkConsistency(const uint256& rootHash) const
{
std::vector<uint8_t> vchToHash;
const auto pos = it.key().size();
for (auto& child : it.children()) {
process(child);
auto& key = child.key();
auto hash = child->hash;
completeHash(hash, key, pos);
vchToHash.push_back(key[pos]);
vchToHash.insert(vchToHash.end(), hash.begin(), hash.end());
CClaimTrieDataNode node;
if (!find({}, node) || node.hash != rootHash) {
if (rootHash == one)
return true;
return error("Mismatched root claim trie hashes. This may happen when there is not a clean process shutdown. Please run with -reindex.");
}
CClaimValue claim;
if (it->getBestClaim(claim)) {
uint256 valueHash = getValueHash(claim.outPoint, it->nHeightOfLastTakeover);
vchToHash.insert(vchToHash.end(), valueHash.begin(), valueHash.end());
} else if (!it.hasChildren()) {
return {};
}
bool success = true;
recurseNodes({}, node, [&success, this](const std::string &name, const CClaimTrieData &data, const std::vector<std::string>& children) {
if (!success) return;
return Hash(vchToHash.begin(), vchToHash.end());
std::vector<uint8_t> vchToHash;
const auto pos = name.size();
for (auto &child : children) {
auto key = name + child;
CClaimTrieDataNode node;
success &= find(key, node);
auto hash = node.hash;
completeHash(hash, key, pos);
vchToHash.push_back(key[pos]);
vchToHash.insert(vchToHash.end(), hash.begin(), hash.end());
}
CClaimValue claim;
if (data.getBestClaim(claim)) {
uint256 valueHash = getValueHash(claim.outPoint, data.nHeightOfLastTakeover);
vchToHash.insert(vchToHash.end(), valueHash.begin(), valueHash.end());
} else {
success &= !children.empty(); // we disallow leaf nodes without claims
}
success &= data.hash == Hash(vchToHash.begin(), vchToHash.end());
});
return success;
}
bool CClaimTrieCacheBase::recursiveCheckConsistency(CClaimTrie::const_iterator& it, std::string& failed) const
{
struct CRecursiveBreak {};
using iterator = CClaimTrie::const_iterator;
iCbType<iterator> process = [&failed, &process](iterator& it) {
if (it->hash.IsNull() || it->hash != recursiveMerkleHash(it, process)) {
failed = it.key();
throw CRecursiveBreak();
}
};
std::vector<std::pair<std::string, CClaimTrieDataNode>> CClaimTrie::nodes(const std::string &key) const {
std::vector<std::pair<std::string, CClaimTrieDataNode>> ret;
CClaimTrieDataNode node;
try {
process(it);
} catch (const CRecursiveBreak&) {
return false;
if (!find({}, node))
return ret;
ret.emplace_back(std::string{}, node);
std::string partialKey = key;
while (!node.children.empty()) {
// auto it = node.children.lower_bound(partialKey); // for using a std::map
auto it = std::lower_bound(node.children.begin(), node.children.end(), partialKey);
if (it != node.children.end() && *it == partialKey) {
// we're completely done
if (find(key, node))
ret.emplace_back(key, node);
break;
}
if (it != node.children.begin()) --it;
const auto count = match(partialKey, *it);
if (count != it->size()) break;
if (count == partialKey.size()) break;
partialKey = partialKey.substr(count);
auto frontKey = key.substr(0, key.size() - partialKey.size());
if (find(frontKey, node))
ret.emplace_back(frontKey, node);
else break;
}
return true;
return ret;
}
bool CClaimTrieCacheBase::checkConsistency() const
{
if (base->empty())
return true;
bool CClaimTrie::contains(const std::string &key) const {
return db->Exists(std::make_pair(TRIE_NODE_CHILDREN, key));
}
auto it = base->cbegin();
std::string failed;
auto consistent = recursiveCheckConsistency(it, failed);
if (!consistent) {
LogPrintf("\nPrinting base tree from its parent:\n");
auto basePath = base->nodes(failed);
if (basePath.size() > 1) basePath.pop_back();
dumpToLog(basePath.back(), false);
auto cachePath = nodesToAddOrUpdate.nodes(failed);
if (!cachePath.empty()) {
LogPrintf("\nPrinting %s's parent from cache:\n", failed);
if (cachePath.size() > 1) cachePath.pop_back();
dumpToLog(cachePath.back(), false);
}
if (!nodesToDelete.empty()) {
std::string joined;
for (const auto &piece : nodesToDelete) joined += ", " + piece;
LogPrintf("Nodes to be deleted: %s\n", joined.substr(2));
}
}
return consistent;
bool CClaimTrie::empty() const {
return !contains({});
}
bool CClaimTrie::find(const std::string& key, CClaimTrieDataNode &node) const {
return db->Read(std::make_pair(TRIE_NODE_CHILDREN, key), node);
}
bool CClaimTrie::find(const std::string& key, CClaimTrieData &data) const {
return db->Read(std::make_pair(TRIE_NODE_CLAIMS, key), data);
}
template <typename K, typename T>
@ -522,22 +579,24 @@ bool CClaimTrieCacheBase::flush()
getMerkleHash();
for (const auto& nodeName : nodesToDelete) {
if (nodesToAddOrUpdate.contains(nodeName))
continue;
auto nodes = base->nodes(nodeName);
base->erase(nodeName);
for (auto& node : nodes)
if (!node)
batch.Erase(std::make_pair(TRIE_NODE, node.key()));
for (auto it = nodesToAddOrUpdate.begin(); it != nodesToAddOrUpdate.end(); ++it) {
bool removed = forDeleteFromBase.erase(it.key());
if (it->flags & CClaimTrieDataFlags::HASH_DIRTY) {
CClaimTrieDataNode node;
node.hash = it->hash;
for (auto &child: it.children()) // ordering here is important
node.children.push_back(child.key().substr(it.key().size()));
batch.Write(std::make_pair(TRIE_NODE_CHILDREN, it.key()), node);
if (removed || (it->flags & CClaimTrieDataFlags::CLAIMS_DIRTY))
batch.Write(std::make_pair(TRIE_NODE_CLAIMS, it.key()), it.data());
}
}
for (auto it = nodesToAddOrUpdate.begin(); it != nodesToAddOrUpdate.end(); ++it) {
auto old = base->find(it.key());
if (!old || old.data() != it.data()) {
base->copy(it);
batch.Write(std::make_pair(TRIE_NODE, it.key()), it.data());
}
for (auto& name: forDeleteFromBase) {
batch.Erase(std::make_pair(TRIE_NODE_CHILDREN, name));
batch.Erase(std::make_pair(TRIE_NODE_CLAIMS, name));
}
BatchWriteQueue(batch, SUPPORT, supportCache);
@ -561,70 +620,32 @@ bool CClaimTrieCacheBase::flush()
return ret;
}
bool CClaimTrieCacheBase::ReadFromDisk(const CBlockIndex* tip)
bool CClaimTrieCacheBase::validateTrieConsistency(const CBlockIndex* tip)
{
LogPrintf("Loading the claim trie from disk...\n");
base->nNextHeight = nNextHeight = tip ? tip->nHeight + 1 : 0;
if (tip && base->db->Exists(std::make_pair(TRIE_NODE_CHILDREN, std::string()))) {
LogPrintf("The claim trie database contains deprecated data and will need to be rebuilt.\n");
return false;
}
clear();
base->clear();
boost::scoped_ptr<CDBIterator> pcursor(base->db->NewIterator());
for (pcursor->SeekToFirst(); pcursor->Valid(); pcursor->Next()) {
std::pair<uint8_t, std::string> key;
if (!pcursor->GetKey(key) || key.first != TRIE_NODE)
continue;
CClaimTrieData data;
if (pcursor->GetValue(data)) {
if (data.empty()) {
// we have a situation where our old trie had many empty nodes
// we don't want to automatically throw those all into our prefix trie
// we'll run a second pass to clean them up
continue;
}
// nEffectiveAmount isn't serialized but it needs to be initialized (as done in reorderClaims):
auto supports = getSupportsForName(key.second);
data.reorderClaims(supports);
base->insert(key.second, std::move(data));
} else {
return error("%s(): error reading claim trie from disk", __func__);
}
}
for (pcursor->SeekToFirst(); pcursor->Valid(); pcursor->Next()) {
std::pair<uint8_t, std::string> key;
if (!pcursor->GetKey(key) || key.first != TRIE_NODE)
continue;
auto hit = base->find(key.second);
if (hit) {
CClaimTrieData data;
if (pcursor->GetValue(data))
hit->hash = data.hash;
}
else {
base->db->Erase(key); // this uses a lot of memory and it's 1-time upgrade from 12.4 so we aren't going to batch it
}
}
if (!tip || tip->nHeight < 1)
return true;
LogPrintf("Checking claim trie consistency... ");
if (checkConsistency()) {
if (base->checkConsistency(tip->hashClaimTrie)) {
LogPrintf("consistent\n");
if (tip && tip->hashClaimTrie != getMerkleHash())
return error("%s(): hashes don't match when reading claimtrie from disk", __func__);
return true;
}
LogPrintf("inconsistent!\n");
return false;
}
bool CClaimTrieCacheBase::ReadFromDisk(const CBlockIndex* tip)
{
base->nNextHeight = nNextHeight = tip ? tip->nHeight + 1 : 0;
clear();
if (tip && base->db->Exists(std::make_pair(TRIE_NODE, std::string()))) {
LogPrintf("The claim trie database contains deprecated data and will need to be rebuilt\n");
return false;
}
return validateTrieConsistency(tip);
}
CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base) : base(base)
{
assert(base);
@ -636,65 +657,92 @@ int CClaimTrieCacheBase::expirationTime() const
return Params().GetConsensus().nOriginalClaimExpirationTime;
}
uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(CClaimTrie::iterator& it)
uint256 CClaimTrieCacheBase::recursiveComputeMerkleHash(CClaimPrefixTrie::iterator& it)
{
using iterator = CClaimTrie::iterator;
iCbType<iterator> process = [&process](iterator& it) {
if (it->hash.IsNull())
it->hash = recursiveMerkleHash(it, process);
assert(!it->hash.IsNull());
};
process(it);
return it->hash;
if (!it->hash.IsNull())
return it->hash;
std::vector<uint8_t> vchToHash;
const auto pos = it.key().size();
for (auto& child : it.children()) {
auto hash = recursiveComputeMerkleHash(child);
auto& key = child.key();
completeHash(hash, key, pos);
vchToHash.push_back(key[pos]);
vchToHash.insert(vchToHash.end(), hash.begin(), hash.end());
}
CClaimValue claim;
if (it->getBestClaim(claim)) {
uint256 valueHash = getValueHash(claim.outPoint, it->nHeightOfLastTakeover);
vchToHash.insert(vchToHash.end(), valueHash.begin(), valueHash.end());
}
return it->hash = Hash(vchToHash.begin(), vchToHash.end());
}
uint256 CClaimTrieCacheBase::getMerkleHash()
{
auto it = nodesToAddOrUpdate.begin();
if (!it && nodesToDelete.empty())
it = base->begin();
return !it ? one : recursiveComputeMerkleHash(it);
if (auto it = nodesToAddOrUpdate.begin())
return recursiveComputeMerkleHash(it);
if (nodesToDelete.empty() && nodesAlreadyCached.empty()) {
CClaimTrieDataNode node;
if (base->find({}, node))
return node.hash; // it may be valuable to have base cache its current root hash
}
return one; // we have no data or we deleted everything
}
CClaimTrie::const_iterator CClaimTrieCacheBase::find(const std::string& name) const
CClaimPrefixTrie::const_iterator CClaimTrieCacheBase::begin() const
{
auto it = nodesToAddOrUpdate.find(name);
if (it || nodesToDelete.count(name))
return it;
return base->find(name);
return nodesToAddOrUpdate.begin();
}
CClaimPrefixTrie::const_iterator CClaimTrieCacheBase::end() const
{
return nodesToAddOrUpdate.end();
}
bool CClaimTrieCacheBase::empty() const
{
return nodesToAddOrUpdate.empty(); // only used with the dump method, and we don't want to dump base
return nodesToAddOrUpdate.empty();
}
CClaimTrie::iterator CClaimTrieCacheBase::cacheData(const std::string& name, bool create)
CClaimPrefixTrie::iterator CClaimTrieCacheBase::cacheData(const std::string& name, bool create)
{
// get data from the cache. if no data, create empty one
const auto insert = [this](CClaimTrie::iterator& it) {
auto& key = it.key();
// we only ever cache nodes once per cache instance
if (!nodesAlreadyCached.count(key)) {
// do not insert nodes that are already present
nodesAlreadyCached.insert(key);
nodesToAddOrUpdate.insert(key, it.data());
}
};
// we need all parent nodes and their one level deep children
// to calculate merkle hash
auto nodes = base->nodes(name);
for (auto& node: nodes) {
for (auto& child : node.children())
if (!nodesAlreadyCached.count(child.key()))
nodesToAddOrUpdate.copy(child);
insert(node);
if (nodesAlreadyCached.insert(node.first).second) {
// do not insert nodes that are already present
CClaimTrieData data;
base->find(node.first, data);
data.hash = node.second.hash;
data.flags = node.second.children.empty() ? 0 : CClaimTrieDataFlags::POTENTIAL_CHILDREN;
nodesToAddOrUpdate.insert(node.first, data);
}
for (auto& child : node.second.children) {
auto childKey = node.first + child;
if (nodesAlreadyCached.insert(childKey).second) {
CClaimTrieData childData;
if (!base->find(childKey, childData))
childData = {};
CClaimTrieDataNode childNode;
if (base->find(childKey, childNode)) {
childData.hash = childNode.hash;
childData.flags = childNode.children.empty() ? 0 : CClaimTrieDataFlags::POTENTIAL_CHILDREN;
}
nodesToAddOrUpdate.insert(childKey, childData);
}
}
}
auto it = nodesToAddOrUpdate.find(name);
if (!it && create) {
it = nodesToAddOrUpdate.insert(name, CClaimTrieData{});
// if (it.hasChildren()) any children should be in the trie (not base alone)
// it->flags |= CClaimTrieDataFlags::POTENTIAL_CHILDREN;
confirmTakeoverWorkaroundNeeded(name);
}
@ -715,10 +763,11 @@ bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, uint16
std::tie(claimId, takeoverHeight) = cit->second;
return true;
}
if (auto it = base->find(name)) {
takeoverHeight = it->nHeightOfLastTakeover;
CClaimTrieData data;
if (base->find(name, data)) {
takeoverHeight = data.nHeightOfLastTakeover;
CClaimValue claim;
if (it->getBestClaim(claim)) {
if (data.getBestClaim(claim)) {
claimId = claim.claimId;
return true;
}
@ -728,8 +777,12 @@ bool CClaimTrieCacheBase::getLastTakeoverForName(const std::string& name, uint16
void CClaimTrieCacheBase::markAsDirty(const std::string& name, bool fCheckTakeover)
{
for (auto& node : nodesToAddOrUpdate.nodes(name))
for (auto& node : nodesToAddOrUpdate.nodes(name)) {
node->flags |= CClaimTrieDataFlags::HASH_DIRTY;
node->hash.SetNull();
if (node.key() == name)
node->flags |= CClaimTrieDataFlags::CLAIMS_DIRTY;
}
if (fCheckTakeover)
namesToCheckForTakeover.insert(name);
@ -763,6 +816,9 @@ bool CClaimTrieCacheBase::removeClaimFromTrie(const std::string& name, const COu
for (auto& child: it.children())
cacheData(child.key(), false);
for (auto& node : nodesToAddOrUpdate.nodes(name))
forDeleteFromBase.emplace(node.key());
nodesToAddOrUpdate.erase(name);
nodesToDelete.insert(name);
@ -935,14 +991,10 @@ bool CClaimTrieCacheBase::remove(T& value, const std::string& name, const COutPo
nValidAtHeight = nHeight + getDelayForName(name);
std::string adjusted = adjustNameForValidHeight(name, nValidAtHeight);
auto rfq = removeFromQueue(adjusted, outPoint, value);
if (rfq || removeFromCache(name, outPoint, value, fCheckTakeover)) {
if (removeFromQueue(adjusted, outPoint, value) || removeFromCache(name, outPoint, value, fCheckTakeover)) {
int expirationHeight = value.nHeight + expirationTime();
if (auto itQueueRow = getExpirationQueueCacheRow<T>(expirationHeight, false)) {
if (auto itQueueRow = getExpirationQueueCacheRow<T>(expirationHeight, false))
eraseOutPoint(*itQueueRow, CNameOutPointType{adjusted, outPoint});
if (adjusted != name) // workaround for an off-by-1 error in normalization block (wherein we might get both):
eraseOutPoint(*itQueueRow, CNameOutPointType{name, outPoint});
}
nValidAtHeight = value.nValidAtHeight;
return true;
}
@ -1003,11 +1055,13 @@ bool CClaimTrieCacheBase::removeSupportFromMap(const std::string& name, const CO
return false;
}
void CClaimTrieCacheBase::dumpToLog(CClaimTrie::const_iterator it, bool diffFromBase) const
void CClaimTrieCacheBase::dumpToLog(CClaimPrefixTrie::const_iterator it, bool diffFromBase) const
{
if (!it) return;
if (diffFromBase) {
auto hit = base->find(it.key());
if (hit && hit->hash == it->hash)
CClaimTrieDataNode node;
if (base->find(it.key(), node) && node.hash == it->hash)
return;
}
@ -1101,12 +1155,9 @@ void CClaimTrieCacheBase::undoIncrement(insertUndoType& insertUndo, std::vector<
if (auto itExpirationRow = getExpirationQueueCacheRow<T>(nNextHeight, false)) {
for (const auto& itEntry : *itExpirationRow) {
T value;
if (removeFromCache(itEntry.name, itEntry.outPoint, value, true)) {
expireUndo.emplace_back(itEntry.name, value);
addTo(deleted, value);
}
else // a bug in the normalization stuff allows some of these to stick around after the claims were spent; don't crash
LogPrintf("Warning: missing expired entry %s, %s:%d\n", itEntry.name, itEntry.outPoint.hash.GetHex(), itEntry.outPoint.n);
assert(removeFromCache(itEntry.name, itEntry.outPoint, value, true));
expireUndo.emplace_back(itEntry.name, value);
addTo(deleted, value);
}
itExpirationRow->clear();
}
@ -1324,8 +1375,12 @@ int CClaimTrieCacheBase::getNumBlocksOfContinuousOwnership(const std::string& na
that->removalWorkaround.erase(hit);
return 0;
}
auto it = nodesToAddOrUpdate.find(name);
return (it || (it = base->find(name))) && !it->empty() ? nNextHeight - it->nHeightOfLastTakeover : 0;
if (auto it = nodesToAddOrUpdate.find(name))
return it->empty() ? 0 : nNextHeight - it->nHeightOfLastTakeover;
CClaimTrieData data;
if (base->find(name, data) && !data.empty())
return nNextHeight - data.nHeightOfLastTakeover;
return 0;
}
int CClaimTrieCacheBase::getDelayForName(const std::string& name) const
@ -1352,22 +1407,23 @@ std::string CClaimTrieCacheBase::adjustNameForValidHeight(const std::string& nam
bool CClaimTrieCacheBase::clear()
{
forDeleteFromBase.clear();
nodesToAddOrUpdate.clear();
claimsToAddToByIdIndex.clear();
supportCache.clear();
nodesToDelete.clear();
claimsToDeleteFromByIdIndex.clear();
takeoverCache.clear();
claimQueueCache.clear();
supportQueueCache.clear();
removalWorkaround.clear();
nodesToAddOrUpdate.clear();
nodesAlreadyCached.clear();
takeoverWorkaround.clear();
removalWorkaround.clear();
claimQueueNameCache.clear();
expirationQueueCache.clear();
supportQueueNameCache.clear();
claimsToAddToByIdIndex.clear();
namesToCheckForTakeover.clear();
supportExpirationQueueCache.clear();
claimsToDeleteFromByIdIndex.clear();
return true;
}
@ -1377,7 +1433,7 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, CClaimTriePro
cacheData(name, false);
getMerkleHash();
proof = CClaimTrieProof();
for (auto& it : static_cast<const CClaimTrie&>(nodesToAddOrUpdate).nodes(name)) {
for (auto& it : static_cast<const CClaimPrefixTrie&>(nodesToAddOrUpdate).nodes(name)) {
CClaimValue claim;
const auto& key = it.key();
bool fNodeHasValue = it->getBestClaim(claim);
@ -1393,7 +1449,7 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, CClaimTriePro
for (auto i = pos; i + 1 < childKey.size(); ++i) {
children.emplace_back(childKey[i], uint256{});
proof.nodes.emplace_back(children, fNodeHasValue, valueHash);
children.clear();
children.clear(); // move promises to leave it in a valid state only
valueHash.SetNull();
fNodeHasValue = false;
}
@ -1417,22 +1473,33 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, CClaimTriePro
return true;
}
void CClaimTrieCacheBase::iterate(std::function<void(const std::string&, const CClaimTrieData&)> callback) const
{
if (nodesToAddOrUpdate.empty()) {
for (auto it = base->cbegin(); it != base->cend(); ++it)
if (!nodesToDelete.count(it.key()))
callback(it.key(), it.data());
return;
void CClaimTrieCacheBase::recurseNodes(const std::string &name,
std::function<void(const std::string &, const CClaimTrieData &)> function) const {
std::function<CClaimTrie::recurseNodesCB> baseFunction = [this, &function]
(const std::string& name, const CClaimTrieData& data, const std::vector<std::string>&) {
if (nodesToDelete.find(name) == nodesToDelete.end())
function(name, data);
};
if (empty()) {
CClaimTrieDataNode node;
if (base->find(name, node))
base->recurseNodes(name, node, baseFunction);
}
for (auto it = nodesToAddOrUpdate.begin(); it != nodesToAddOrUpdate.end(); ++it) {
callback(it.key(), it.data());
if (it.hasChildren() || nodesToDelete.count(it.key()))
continue;
auto children = base->find(it.key()).children();
for (auto& child : children)
for (; child; ++child)
if (!nodesToDelete.count(child.key()))
callback(child.key(), child.data());
else {
for (auto it = begin(); it != end(); ++it) {
function(it.key(), it.data());
if ((it->flags & CClaimTrieDataFlags::POTENTIAL_CHILDREN) && !it.hasChildren()) {
CClaimTrieDataNode node;
if (base->find(it.key(), node))
for (auto& partialKey: node.children) {
auto childKey = it.key() + partialKey;
CClaimTrieDataNode childNode;
if (base->find(childKey, childNode))
base->recurseNodes(childKey, childNode, baseFunction);
}
}
}
}
}

View file

@ -18,8 +18,9 @@
#include <unordered_set>
// leveldb keys
#define TRIE_NODE 'n'
#define TRIE_NODE 'n' // deprecated
#define TRIE_NODE_CHILDREN 'b'
#define TRIE_NODE_CLAIMS 'c'
#define CLAIM_BY_ID 'i'
#define CLAIM_QUEUE_ROW 'r'
#define CLAIM_QUEUE_NAME_ROW 'm'
@ -62,6 +63,7 @@ struct CClaimValue
READWRITE(nAmount);
READWRITE(nHeight);
READWRITE(nValidAtHeight);
READWRITE(nEffectiveAmount);
}
bool operator<(const CClaimValue& other) const
@ -134,12 +136,21 @@ struct CSupportValue
typedef std::vector<CClaimValue> claimEntryType;
typedef std::vector<CSupportValue> supportEntryType;
enum CClaimTrieDataFlags: uint32_t {
HASH_DIRTY = 1U,
CLAIMS_DIRTY = 2U,
POTENTIAL_CHILDREN = 4U, // existing on disk
};
struct CClaimTrieData
{
uint256 hash;
claimEntryType claims;
int nHeightOfLastTakeover = 0;
// non-serialized data:
uint32_t flags = 0;
uint256 hash;
CClaimTrieData() = default;
CClaimTrieData(CClaimTrieData&&) = default;
CClaimTrieData(const CClaimTrieData&) = default;
@ -157,25 +168,13 @@ struct CClaimTrieData
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action)
{
READWRITE(hash);
if (ser_action.ForRead()) {
if (s.eof()) {
claims.clear();
nHeightOfLastTakeover = 0;
return;
}
}
else if (claims.empty())
return;
READWRITE(claims);
READWRITE(nHeightOfLastTakeover);
}
bool operator==(const CClaimTrieData& other) const
{
return hash == other.hash && nHeightOfLastTakeover == other.nHeightOfLastTakeover && claims == other.claims;
return nHeightOfLastTakeover == other.nHeightOfLastTakeover && claims == other.claims;
}
bool operator!=(const CClaimTrieData& other) const
@ -189,6 +188,28 @@ struct CClaimTrieData
}
};
struct CClaimTrieDataNode {
uint256 hash;
// we're using a vector to avoid RAM thrashing and for faster serialization ops.
// We're assuming its data is inserted in order and never modified.
std::vector<std::string> children;
CClaimTrieDataNode() = default;
CClaimTrieDataNode(CClaimTrieDataNode&&) = default;
CClaimTrieDataNode(const CClaimTrieDataNode&) = default;
CClaimTrieDataNode& operator=(CClaimTrieDataNode&&) = default;
CClaimTrieDataNode& operator=(const CClaimTrieDataNode& d) = default;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action)
{
READWRITE(hash);
READWRITE(children);
}
};
struct COutPointHeightType
{
COutPoint outPoint;
@ -343,7 +364,7 @@ struct CClaimSupportToName
const std::vector<CSupportValue> unmatchedSupports;
};
class CClaimTrie : public CPrefixTrie<std::string, CClaimTrieData>
class CClaimTrie
{
public:
CClaimTrie() = default;
@ -366,12 +387,23 @@ public:
std::size_t getTotalNamesInTrie() const;
std::size_t getTotalClaimsInTrie() const;
virtual bool checkConsistency(const uint256& rootHash) const;
CAmount getTotalValueOfClaimsInTrie(bool fControllingOnly) const;
bool contains(const std::string& key) const;
bool empty() const;
bool find(const std::string& key, CClaimTrieDataNode& node) const;
bool find(const std::string& key, CClaimTrieData& claims) const;
std::vector<std::pair<std::string, CClaimTrieDataNode>> nodes(const std::string& key) const;
protected:
int nNextHeight = 0;
int nProportionalDelayFactor = 0;
std::unique_ptr<CDBWrapper> db;
using recurseNodesCB = void(const std::string&, const CClaimTrieData&, const std::vector<std::string>&);
void recurseNodes(const std::string& name, const CClaimTrieDataNode& current, std::function<recurseNodesCB> function) const;
};
struct CClaimTrieProofNode
@ -476,6 +508,8 @@ typedef std::map<int, expirationQueueRowType> expirationQueueType;
typedef std::set<CClaimValue> claimIndexClaimListType;
typedef std::vector<CClaimIndexElement> claimIndexElementListType;
typedef CPrefixTrie<std::string, CClaimTrieData> CClaimPrefixTrie;
class CClaimTrieCacheBase
{
public:
@ -486,7 +520,6 @@ public:
bool flush();
bool empty() const;
bool checkConsistency() const;
bool ReadFromDisk(const CBlockIndex* tip);
bool haveClaim(const std::string& name, const COutPoint& outPoint) const;
@ -527,20 +560,21 @@ public:
virtual CClaimSupportToName getClaimsForName(const std::string& name) const;
CClaimTrie::const_iterator find(const std::string& name) const;
void iterate(std::function<void(const std::string&, const CClaimTrieData&)> callback) const;
CClaimPrefixTrie::const_iterator begin() const;
CClaimPrefixTrie::const_iterator end() const;
void dumpToLog(CClaimTrie::const_iterator it, bool diffFromBase = true) const;
void dumpToLog(CClaimPrefixTrie::const_iterator it, bool diffFromBase = true) const;
virtual std::string adjustNameForValidHeight(const std::string& name, int validHeight) const;
protected:
void recurseNodes(const std::string& name, std::function<void(const std::string&, const CClaimTrieData&)> function) const;
protected:
CClaimTrie* base;
CClaimTrie nodesToAddOrUpdate; // nodes pulled in from base (and possibly modified thereafter), written to base on flush
CClaimPrefixTrie nodesToAddOrUpdate; // nodes pulled in from base (and possibly modified thereafter), written to base on flush
std::unordered_set<std::string> nodesAlreadyCached; // set of nodes already pulled into cache from base
std::unordered_set<std::string> namesToCheckForTakeover; // takeover numbers are updated on increment
virtual uint256 recursiveComputeMerkleHash(CClaimTrie::iterator& it);
virtual bool recursiveCheckConsistency(CClaimTrie::const_iterator& it, std::string& failed) const;
virtual uint256 recursiveComputeMerkleHash(CClaimPrefixTrie::iterator& it);
virtual bool insertClaimIntoTrie(const std::string& name, const CClaimValue& claim, bool fCheckTakeover);
virtual bool removeClaimFromTrie(const std::string& name, const COutPoint& outPoint, CClaimValue& claim, bool fCheckTakeover);
@ -553,7 +587,7 @@ protected:
int getDelayForName(const std::string& name) const;
virtual int getDelayForName(const std::string& name, const uint160& claimId) const;
CClaimTrie::iterator cacheData(const std::string& name, bool create = true);
CClaimPrefixTrie::iterator cacheData(const std::string& name, bool create = true);
bool getLastTakeoverForName(const std::string& name, uint160& claimId, int& takeoverHeight) const;
@ -584,6 +618,7 @@ private:
std::unordered_set<std::string> nodesToDelete; // to be removed from base (and disk) on flush
std::unordered_map<std::string, bool> takeoverWorkaround;
std::unordered_set<std::string> removalWorkaround;
std::unordered_set<std::string> forDeleteFromBase;
bool shouldUseTakeoverWorkaround(const std::string& key) const;
void addTakeoverWorkaroundPotential(const std::string& key);
@ -595,6 +630,8 @@ private:
bool removeSupport(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight, bool fCheckTakeover);
bool removeClaim(const std::string& name, const COutPoint& outPoint, int nHeight, int& nValidAtHeight, bool fCheckTakeover);
bool validateTrieConsistency(const CBlockIndex* tip);
template <typename T>
void insertRowsFromQueue(std::vector<T>& result, const std::string& name) const;
@ -744,13 +781,20 @@ public:
bool allowSupportMetadata() const;
protected:
uint256 recursiveComputeMerkleHash(CClaimTrie::iterator& it) override;
bool recursiveCheckConsistency(CClaimTrie::const_iterator& it, std::string& failed) const override;
uint256 recursiveComputeMerkleHash(CClaimPrefixTrie::iterator& it) override;
private:
void copyAllBaseToCache();
};
class CClaimTrieHashFork : public CClaimTrie
{
public:
using CClaimTrie::CClaimTrie;
protected:
bool checkConsistency(const uint256& rootHash) const override;
};
typedef CClaimTrieCacheHashFork CClaimTrieCache;
#endif // BITCOIN_CLAIMTRIE_H

View file

@ -5,8 +5,6 @@
#include <hash.h>
#include <boost/locale.hpp>
#include <boost/locale/conversion.hpp>
#include <boost/locale/localization_backend.hpp>
#include <boost/scope_exit.hpp>
#include <boost/scoped_ptr.hpp>
@ -172,12 +170,17 @@ bool CClaimTrieCacheNormalizationFork::normalizeAllNamesInTrieIfNecessary(insert
// run the one-time upgrade of all names that need to change
// it modifies the (cache) trie as it goes, so we need to grab everything to be modified first
for (auto it = base->cbegin(); it != base->cend(); ++it) {
const std::string normalized = normalizeClaimName(it.key(), true);
if (normalized == it.key())
boost::scoped_ptr<CDBIterator> pcursor(base->db->NewIterator());
for (pcursor->SeekToFirst(); pcursor->Valid(); pcursor->Next()) {
std::pair<uint8_t, std::string> key;
if (!pcursor->GetKey(key) || key.first != TRIE_NODE_CHILDREN)
continue;
const auto& name = key.second;
const std::string normalized = normalizeClaimName(name, true);
if (normalized == key.second)
continue;
auto& name = it.key();
auto supports = getSupportsForName(name);
for (auto support : supports) {
// if it's already going to expire just skip it
@ -272,17 +275,23 @@ std::vector<uint256> getClaimHashes(const CClaimTrieData& data)
template <typename T>
using iCbType = std::function<uint256(T&)>;
template <typename TIterator>
uint256 recursiveBinaryTreeHash(TIterator& it, const iCbType<TIterator>& process)
template <typename T>
using decay = typename std::decay<T>::type;
template <typename Vector, typename T>
uint256 recursiveMerkleHash(const CClaimTrieData& data, Vector&& children, const iCbType<T>& childHash)
{
static_assert(std::is_same<decay<Vector>, std::vector<decay<T>>>::value, "Vector should be std vector");
static_assert(std::is_same<decltype(children[0]), T&>::value, "Vector element type should match callback type");
std::vector<uint256> childHashes;
for (auto& child : it.children())
childHashes.emplace_back(process(child));
for (auto& child : children)
childHashes.emplace_back(childHash(child));
std::vector<uint256> claimHashes;
if (!it->empty())
claimHashes = getClaimHashes(it.data());
else if (!it.hasChildren())
if (!data.empty())
claimHashes = getClaimHashes(data);
else if (children.empty())
return {};
auto left = childHashes.empty() ? leafHash : ComputeMerkleRoot(childHashes);
@ -291,44 +300,53 @@ uint256 recursiveBinaryTreeHash(TIterator& it, const iCbType<TIterator>& process
return Hash(left.begin(), left.end(), right.begin(), right.end());
}
uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(CClaimTrie::iterator& it)
extern const uint256 one;
bool CClaimTrieHashFork::checkConsistency(const uint256& rootHash) const
{
if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
return CClaimTrie::checkConsistency(rootHash);
CClaimTrieDataNode node;
if (!find({}, node) || node.hash != rootHash) {
if (rootHash == one)
return true;
return error("Mismatched root claim trie hashes. This may happen when there is not a clean process shutdown. Please run with -reindex.");
}
bool success = true;
recurseNodes({}, node, [&success, this](const std::string& name, const CClaimTrieData& data, const std::vector<std::string>& children) {
if (!success) return;
iCbType<const std::string> callback = [&success, &name, this](const std::string& child) -> uint256 {
auto key = name + child;
CClaimTrieDataNode node;
success &= find(key, node);
return node.hash;
};
success &= !data.hash.IsNull();
success &= data.hash == recursiveMerkleHash(data, children, callback);
});
return success;
}
uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(CClaimPrefixTrie::iterator& it)
{
if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
return CClaimTrieCacheNormalizationFork::recursiveComputeMerkleHash(it);
using iterator = CClaimTrie::iterator;
using iterator = CClaimPrefixTrie::iterator;
iCbType<iterator> process = [&process](iterator& it) -> uint256 {
if (it->hash.IsNull())
it->hash = recursiveBinaryTreeHash(it, process);
assert(!it->hash.IsNull());
it->hash = recursiveMerkleHash(it.data(), it.children(), process);
return it->hash;
};
return process(it);
}
bool CClaimTrieCacheHashFork::recursiveCheckConsistency(CClaimTrie::const_iterator& it, std::string& failed) const
{
if (nNextHeight < Params().GetConsensus().nAllClaimsInMerkleForkHeight)
return CClaimTrieCacheNormalizationFork::recursiveCheckConsistency(it, failed);
struct CRecursiveBreak {};
using iterator = CClaimTrie::const_iterator;
iCbType<iterator> process = [&failed, &process](iterator& it) -> uint256 {
if (it->hash.IsNull() || it->hash != recursiveBinaryTreeHash(it, process)) {
failed = it.key();
throw CRecursiveBreak();
}
return it->hash;
};
try {
process(it);
} catch (const CRecursiveBreak&) {
return false;
}
return true;
}
std::vector<uint256> ComputeMerklePath(const std::vector<uint256>& hashes, uint32_t idx)
{
uint32_t count = 0;
@ -404,7 +422,7 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTri
cacheData(name, false);
getMerkleHash();
proof = CClaimTrieProof();
for (auto& it : static_cast<const CClaimTrie&>(nodesToAddOrUpdate).nodes(name)) {
for (auto& it : static_cast<const CClaimPrefixTrie&>(nodesToAddOrUpdate).nodes(name)) {
std::vector<uint256> childHashes;
uint32_t nextCurrentIdx = 0;
for (auto& child : it.children()) {
@ -447,12 +465,15 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, CClaimTri
void CClaimTrieCacheHashFork::copyAllBaseToCache()
{
for (auto it = base->cbegin(); it != base->cend(); ++it)
if (nodesAlreadyCached.insert(it.key()).second)
nodesToAddOrUpdate.insert(it.key(), it.data());
recurseNodes({}, [this](const std::string& name, const CClaimTrieData& data) {
if (nodesAlreadyCached.insert(name).second)
nodesToAddOrUpdate.insert(name, data);
});
for (auto it = nodesToAddOrUpdate.begin(); it != nodesToAddOrUpdate.end(); ++it)
for (auto it = nodesToAddOrUpdate.begin(); it != nodesToAddOrUpdate.end(); ++it) {
it->hash.SetNull();
it->flags |= CClaimTrieDataFlags::HASH_DIRTY;
}
}
void CClaimTrieCacheHashFork::initializeIncrement()
@ -475,7 +496,6 @@ bool CClaimTrieCacheHashFork::finalizeDecrement(std::vector<std::pair<std::strin
return ret;
}
bool CClaimTrieCacheHashFork::allowSupportMetadata() const
{
bool CClaimTrieCacheHashFork::allowSupportMetadata() const {
return nNextHeight >= Params().GetConsensus().nAllClaimsInMerkleForkHeight;
}

View file

@ -22,7 +22,6 @@
#include <httprpc.h>
#include <index/txindex.h>
#include <key.h>
#include <lbry.h>
#include <validation.h>
#include <miner.h>
#include <netbase.h>
@ -399,7 +398,6 @@ void SetupServerArgs()
hidden_args.emplace_back("-sysperms");
#endif
gArgs.AddArg("-txindex", strprintf("Maintain a full transaction index, used by the getrawtransaction rpc call (default: %u)", DEFAULT_TXINDEX), false, OptionsCategory::OPTIONS);
gArgs.AddArg("-memfile=<GiB>", "Use a memory mapped file for the claimtrie allocations (default: use RAM instead)", false, OptionsCategory::OPTIONS);
gArgs.AddArg("-addnode=<ip>", "Add a node to connect to and attempt to keep the connection open (see the `addnode` RPC command help for more info). This option can be specified multiple times to add multiple nodes.", false, OptionsCategory::CONNECTION);
gArgs.AddArg("-banscore=<n>", strprintf("Threshold for disconnecting misbehaving peers (default: %u)", DEFAULT_BANSCORE_THRESHOLD), false, OptionsCategory::CONNECTION);
@ -486,6 +484,7 @@ void SetupServerArgs()
CURRENCY_UNIT, FormatMoney(DEFAULT_TRANSACTION_MAXFEE)), false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-printpriority", strprintf("Log transaction fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY), true, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-printtoconsole", "Send trace/debug info to console (default: 1 when no -daemon. To disable logging to file, set -nodebuglogfile)", false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-shrinkdebugfile", "Shrink debug.log file on client startup (default: 1 when no -debug)", false, OptionsCategory::DEBUG_TEST);
gArgs.AddArg("-uacomment=<cmt>", "Append comment to the user agent string", false, OptionsCategory::DEBUG_TEST);
SetupChainParamsBaseOptions();
@ -1235,6 +1234,11 @@ bool AppInitMain()
CreatePidFile(GetPidFile(), getpid());
#endif
if (g_logger->m_print_to_file) {
if (gArgs.GetBoolArg("-shrinkdebugfile", g_logger->DefaultShrinkDebugFile())) {
// Do this first since it both loads a bunch of debug.log into memory,
// and because this needs to happen before any other debug.log printing
g_logger->ShrinkDebugFile();
}
if (!g_logger->OpenDebugLog()) {
return InitError(strprintf("Could not open debug log file %s",
g_logger->m_file_path.string()));
@ -1437,8 +1441,6 @@ bool AppInitMain()
LogPrintf("* Using %.1fMiB for chain state database\n", nCoinDBCache * (1.0 / 1024 / 1024));
LogPrintf("* Using %.1fMiB for in-memory UTXO set (plus up to %.1fMiB of unused mempool space)\n", nCoinCacheUsage * (1.0 / 1024 / 1024), nMempoolSizeMax * (1.0 / 1024 / 1024));
g_memfileSize = gArgs.GetArg("-memfile", 0u);
bool fLoaded = false;
while (!fLoaded && !ShutdownRequested()) {
bool fReset = fReindex;
@ -1463,7 +1465,7 @@ bool AppInitMain()
int64_t trieCacheMB = gArgs.GetArg("-claimtriecache", nDefaultDbCache);
trieCacheMB = std::min(trieCacheMB, nMaxDbCache);
trieCacheMB = std::max(trieCacheMB, nMinDbCache);
pclaimTrie = new CClaimTrie(false, fReindex || fReindexChainState, 32, trieCacheMB);
pclaimTrie = new CClaimTrieHashFork(false, fReindex || fReindexChainState, 32, trieCacheMB);
if (fReset) {
pblocktree->WriteReindexing(true);

View file

@ -3,8 +3,6 @@
#include <cstdio>
uint32_t g_memfileSize = 0;
unsigned int CalculateLbryNextWorkRequired(const CBlockIndex* pindexLast, int64_t nFirstBlockTime, const Consensus::Params& params)
{
if (params.fPowNoRetargeting)

View file

@ -1,10 +1,9 @@
#ifndef LBRY_H
#define LBRY_H
#ifndef BITCOIN_LBRY_H
#define BITCOIN_LBRY_H
#include <chain.h>
#include <chainparams.h>
extern uint32_t g_memfileSize;
unsigned int CalculateLbryNextWorkRequired(const CBlockIndex* pindexLast, int64_t nLastRetargetTime, const Consensus::Params& params);
#endif

View file

@ -37,12 +37,6 @@ bool BCLog::Logger::OpenDebugLog()
assert(m_fileout == nullptr);
assert(!m_file_path.empty());
if (fs::exists(m_file_path)) {
fs::path old_file_path(m_file_path);
old_file_path += ".old";
fs::rename(m_file_path, old_file_path);
}
m_fileout = fsbridge::fopen(m_file_path, "a");
if (!m_fileout) {
return false;
@ -89,6 +83,11 @@ bool BCLog::Logger::WillLogCategory(BCLog::LogFlags category) const
return (m_categories.load(std::memory_order_relaxed) & category) != 0;
}
bool BCLog::Logger::DefaultShrinkDebugFile() const
{
return m_categories == BCLog::NONE;
}
struct CLogCategoryDesc
{
BCLog::LogFlags flag;
@ -232,3 +231,44 @@ void BCLog::Logger::LogPrintStr(const std::string &str)
}
}
}
void BCLog::Logger::ShrinkDebugFile()
{
// Amount of debug.log to save at end when shrinking (must fit in memory)
constexpr size_t RECENT_DEBUG_HISTORY_SIZE = 10 * 1000000;
assert(!m_file_path.empty());
// Scroll debug.log if it's getting too big
FILE* file = fsbridge::fopen(m_file_path, "r");
// Special files (e.g. device nodes) may not have a size.
size_t log_size = 0;
try {
log_size = fs::file_size(m_file_path);
} catch (boost::filesystem::filesystem_error &) {}
// If debug.log file is more than 10% bigger the RECENT_DEBUG_HISTORY_SIZE
// trim it down by saving only the last RECENT_DEBUG_HISTORY_SIZE bytes
if (file && log_size > 11 * (RECENT_DEBUG_HISTORY_SIZE / 10))
{
// Restart the file with some of the end
std::vector<char> vch(RECENT_DEBUG_HISTORY_SIZE, 0);
if (fseek(file, -((long)vch.size()), SEEK_END)) {
LogPrintf("Failed to shrink debug log file: fseek(...) failed\n");
fclose(file);
return;
}
int nBytes = fread(vch.data(), 1, vch.size(), file);
fclose(file);
file = fsbridge::fopen(m_file_path, "w");
if (file)
{
fwrite(vch.data(), 1, nBytes, file);
fclose(file);
}
}
else if (file != nullptr)
fclose(file);
}

View file

@ -93,6 +93,7 @@ namespace BCLog {
bool Enabled() const { return m_print_to_console || m_print_to_file; }
bool OpenDebugLog();
void ShrinkDebugFile();
uint32_t GetCategoryMask() const { return m_categories.load(); }
@ -102,6 +103,8 @@ namespace BCLog {
bool DisableCategory(const std::string& str);
bool WillLogCategory(LogFlags category) const;
bool DefaultShrinkDebugFile() const;
};
} // namespace BCLog

View file

@ -208,7 +208,7 @@ std::unique_ptr<CBlockTemplate> BlockAssembler::CreateNewBlock(const CScript& sc
CValidationState state;
if (!TestBlockValidity(state, chainparams, *pblock, pindexPrev, false, false)) {
if (!trieCache.empty())
trieCache.dumpToLog(trieCache.find({}));
trieCache.dumpToLog(trieCache.begin());
throw std::runtime_error(strprintf("%s: TestBlockValidity failed: %s", __func__, FormatStateMessage(state)));
}
int64_t nTime2 = GetTimeMicros();

View file

@ -1,6 +1,6 @@
#include "nameclaim.h"
#include "hash.h"
#include "util.h"
#include <nameclaim.h>
#include <hash.h>
#include <util.h>
std::vector<unsigned char> uint32_t_to_vch(uint32_t n)
{

View file

@ -1,10 +1,10 @@
#ifndef BITCOIN_NAMECLAIM_H
#define BITCOIN_NAMECLAIM_H
#include "amount.h"
#include "script/script.h"
#include "primitives/transaction.h"
#include "uint256.h"
#include <amount.h>
#include <script/script.h>
#include <primitives/transaction.h>
#include <uint256.h>
#include <vector>

View file

@ -3666,7 +3666,8 @@ bool PeerLogicValidation::SendMessages(CNode* pto)
if (state.vBlocksInFlight.size() > 0) {
QueuedBlock &queuedBlock = state.vBlocksInFlight.front();
int nOtherPeersWithValidatedDownloads = nPeersWithValidatedDownloads - (state.nBlocksInFlightValidHeaders > 0);
if (nNow > state.nDownloadingSince + consensusParams.nPowTargetSpacing * (BLOCK_DOWNLOAD_TIMEOUT_BASE + BLOCK_DOWNLOAD_TIMEOUT_PER_PEER * nOtherPeersWithValidatedDownloads)) {
auto powTargetSpacing = std::max(int64_t(2) * 60, consensusParams.nPowTargetSpacing);
if (nNow > state.nDownloadingSince + powTargetSpacing * (BLOCK_DOWNLOAD_TIMEOUT_BASE + BLOCK_DOWNLOAD_TIMEOUT_PER_PEER * nOtherPeersWithValidatedDownloads)) {
LogPrintf("Timeout downloading block %s from peer=%d, disconnecting\n", queuedBlock.hash.ToString(), pto->GetId());
pto->fDisconnect = true;
return true;

View file

@ -1,79 +1,5 @@
#include <claimtrie.h>
#include <fs.h>
#include <lbry.h>
#include <limits>
#include <memory>
#include <prefixtrie.h>
#include <boost/interprocess/allocators/private_node_allocator.hpp>
#include <boost/interprocess/indexes/null_index.hpp>
#include <boost/interprocess/managed_mapped_file.hpp>
namespace bip = boost::interprocess;
typedef bip::basic_managed_mapped_file <
char,
bip::rbtree_best_fit<bip::null_mutex_family, bip::offset_ptr<void>>,
bip::null_index
> managed_mapped_file;
template <typename T>
using node_allocator = bip::private_node_allocator<T, managed_mapped_file::segment_manager>;
static managed_mapped_file::segment_manager* segmentManager()
{
struct CSharedMemoryFile
{
CSharedMemoryFile() : file(GetDataDir() / "shared.mem")
{
fs::remove(file);
auto size = (uint64_t)g_memfileSize * 1024ULL * 1024ULL * 1024ULL;
// using string() to remove w_char filename encoding on Windows
menaged_file.reset(new managed_mapped_file(bip::create_only, file.string().c_str(), size));
}
~CSharedMemoryFile()
{
menaged_file.reset();
fs::remove(file);
}
managed_mapped_file::segment_manager* segmentManager()
{
return menaged_file->get_segment_manager();
}
const fs::path file;
std::unique_ptr<managed_mapped_file> menaged_file;
};
static CSharedMemoryFile shem;
return shem.segmentManager();
}
template <typename T>
static node_allocator<T>& nodeAllocator()
{
static node_allocator<T> allocator(segmentManager());
return allocator;
}
template <typename T, class... Args>
static std::shared_ptr<T> nodeAllocate(Args&&... args)
{
return std::allocate_shared<T>(nodeAllocator<T>(), std::forward<Args>(args)...);
}
template <typename T, class... Args>
static std::shared_ptr<T> allocateShared(Args&&... args)
{
static auto allocate = g_memfileSize ? nodeAllocate<T, Args...> : std::make_shared<T, Args...>;
try {
return allocate(std::forward<Args>(args)...);
}
catch (const bip::bad_alloc&) {
allocate = std::make_shared<T, Args...>; // in case we fill up the memfile
LogPrint(BCLog::BENCH, "WARNING: The memfile is full; reverting to the RAM allocator for %s.\n", typeid(T).name());
return allocate(std::forward<Args>(args)...);
}
}
#include <claimtrie.h>
template <typename TKey, typename TData>
template <bool IsConst>
@ -91,7 +17,7 @@ typename CPrefixTrie<TKey, TData>::template Iterator<IsConst>& CPrefixTrie<TKey,
stack.clear();
stack.reserve(o.stack.size());
for (auto& i : o.stack)
stack.push_back(Bookmark{i.name, i.it, i.end});
stack.push_back(Bookmark{i.name, i.parent, i.it, i.end});
return *this;
}
@ -121,7 +47,7 @@ typename CPrefixTrie<TKey, TData>::template Iterator<IsConst>& CPrefixTrie<TKey,
if (!shared->children.empty()) {
auto& children = shared->children;
auto it = children.begin();
stack.emplace_back(Bookmark{name, it, children.end()});
stack.emplace_back(Bookmark{name, shared, it, children.end()});
auto& postfix = it->first;
name.insert(name.end(), postfix.begin(), postfix.end());
node = it->second;
@ -179,30 +105,18 @@ bool CPrefixTrie<TKey, TData>::Iterator<IsConst>::operator!=(const Iterator& o)
template <typename TKey, typename TData>
template <bool IsConst>
typename CPrefixTrie<TKey, TData>::template Iterator<IsConst>::reference CPrefixTrie<TKey, TData>::Iterator<IsConst>::operator*()
typename CPrefixTrie<TKey, TData>::template Iterator<IsConst>::reference CPrefixTrie<TKey, TData>::Iterator<IsConst>::operator*() const
{
return reference{name, data()};
assert(!node.expired());
return TPair(name, node.lock()->data);
}
template <typename TKey, typename TData>
template <bool IsConst>
typename CPrefixTrie<TKey, TData>::template Iterator<IsConst>::const_reference CPrefixTrie<TKey, TData>::Iterator<IsConst>::operator*() const
typename CPrefixTrie<TKey, TData>::template Iterator<IsConst>::pointer CPrefixTrie<TKey, TData>::Iterator<IsConst>::operator->() const
{
return const_reference{name, data()};
}
template <typename TKey, typename TData>
template <bool IsConst>
typename CPrefixTrie<TKey, TData>::template Iterator<IsConst>::pointer CPrefixTrie<TKey, TData>::Iterator<IsConst>::operator->()
{
return &(data());
}
template <typename TKey, typename TData>
template <bool IsConst>
typename CPrefixTrie<TKey, TData>::template Iterator<IsConst>::const_pointer CPrefixTrie<TKey, TData>::Iterator<IsConst>::operator->() const
{
return &(data());
assert(!node.expired());
return &(node.lock()->data);
}
template <typename TKey, typename TData>
@ -214,20 +128,18 @@ const TKey& CPrefixTrie<TKey, TData>::Iterator<IsConst>::key() const
template <typename TKey, typename TData>
template <bool IsConst>
typename CPrefixTrie<TKey, TData>::template Iterator<IsConst>::data_reference CPrefixTrie<TKey, TData>::Iterator<IsConst>::data()
TData& CPrefixTrie<TKey, TData>::Iterator<IsConst>::data()
{
auto shared = node.lock();
assert(shared);
return *(shared->data);
assert(!node.expired());
return node.lock()->data;
}
template <typename TKey, typename TData>
template <bool IsConst>
const TData& CPrefixTrie<TKey, TData>::Iterator<IsConst>::data() const
{
auto shared = node.lock();
assert(shared);
return *(shared->data);
assert(!node.expired());
return node.lock()->data;
}
template <typename TKey, typename TData>
@ -327,20 +239,19 @@ std::shared_ptr<typename CPrefixTrie<TKey, TData>::Node>& CPrefixTrie<TKey, TDat
}
if (count == 0) {
++size;
it = children.emplace(key, allocateShared<Node>()).first;
it = children.emplace(key, std::make_shared<Node>()).first;
return it->second;
}
if (count < it->first.size()) {
TKey prefix(key.begin(), key.begin() + count);
TKey postfix(it->first.begin() + count, it->first.end());
const TKey prefix(key.begin(), key.begin() + count);
const TKey postfix(it->first.begin() + count, it->first.end());
auto nodes = std::move(it->second);
children.erase(it);
++size;
it = children.emplace(std::move(prefix), allocateShared<Node>()).first;
it->second->children.emplace(std::move(postfix), std::move(nodes));
it = children.emplace(prefix, std::make_shared<Node>()).first;
it->second->children.emplace(postfix, std::move(nodes));
if (key.size() == count)
return it->second;
it->second->data = allocateShared<TData>();
}
return insert(TKey(key.begin() + count, key.end()), it->second);
}
@ -357,12 +268,12 @@ void CPrefixTrie<TKey, TData>::erase(const TKey& key, std::shared_ptr<Node>& nod
if (!find(key, node, cb))
return;
nodes.back().second->data = allocateShared<TData>();
nodes.back().second->data = {};
for (; nodes.size() > 1; nodes.pop_back()) {
// if we have only one child and no data ourselves, bring them up to our level
auto& cNode = nodes.back().second;
auto onlyOneChild = cNode->children.size() == 1;
auto noData = cNode->data->empty();
auto noData = cNode->data.empty();
if (onlyOneChild && noData) {
auto child = cNode->children.begin();
auto& prefix = nodes.back().first;
@ -370,7 +281,7 @@ void CPrefixTrie<TKey, TData>::erase(const TKey& key, std::shared_ptr<Node>& nod
auto& postfix = child->first;
newKey.insert(newKey.end(), postfix.begin(), postfix.end());
auto& pNode = nodes[nodes.size() - 2].second;
pNode->children.emplace(std::move(newKey), std::move(child->second));
pNode->children.emplace(newKey, std::move(child->second));
pNode->children.erase(prefix);
--size;
continue;
@ -388,9 +299,8 @@ void CPrefixTrie<TKey, TData>::erase(const TKey& key, std::shared_ptr<Node>& nod
}
template <typename TKey, typename TData>
CPrefixTrie<TKey, TData>::CPrefixTrie() : size(0), root(allocateShared<Node>())
CPrefixTrie<TKey, TData>::CPrefixTrie() : size(0), root(std::make_shared<Node>())
{
root->data = allocateShared<TData>();
}
template <typename TKey, typename TData>
@ -398,7 +308,7 @@ template <typename TDataUni>
typename CPrefixTrie<TKey, TData>::iterator CPrefixTrie<TKey, TData>::insert(const TKey& key, TDataUni&& data)
{
auto& node = key.empty() ? root : insert(key, root);
node->data = allocateShared<TData>(std::forward<TDataUni>(data));
node->data = std::forward<TDataUni>(data);
return key.empty() ? begin() : iterator{key, node};
}
@ -422,9 +332,9 @@ typename CPrefixTrie<TKey, TData>::iterator CPrefixTrie<TKey, TData>::insert(CPr
auto name = it.key();
name.insert(name.end(), key.begin(), key.end());
auto& node = insert(key, shared);
copy = iterator{std::move(name), node};
copy = iterator{name, node};
}
copy.node.lock()->data = allocateShared<TData>(std::forward<TDataUni>(data));
copy.node.lock()->data = std::forward<TDataUni>(data);
return copy;
}
@ -493,7 +403,7 @@ bool CPrefixTrie<TKey, TData>::erase(const TKey& key)
{
auto size_was = height();
if (key.empty()) {
root->data = allocateShared<TData>();
root->data = {};
} else {
erase(key, root);
}
@ -504,7 +414,7 @@ template <typename TKey, typename TData>
void CPrefixTrie<TKey, TData>::clear()
{
size = 0;
root->data = allocateShared<TData>();
root->data = {};
root->children.clear();
}
@ -517,7 +427,7 @@ bool CPrefixTrie<TKey, TData>::empty() const
template <typename TKey, typename TData>
std::size_t CPrefixTrie<TKey, TData>::height() const
{
return size + (root->data->empty() ? 0 : 1);
return size + (root->data.empty() ? 0 : 1);
}
template <typename TKey, typename TData>

View file

@ -27,9 +27,9 @@ class CPrefixTrie
Node() = default;
Node(const Node&) = delete;
Node(Node&& o) noexcept = default;
Node& operator=(Node&&) noexcept = default;
Node& operator=(Node&& o) noexcept = default;
Node& operator=(const Node&) = delete;
std::shared_ptr<TData> data;
TData data;
};
using TChildren = decltype(Node::children);
@ -42,15 +42,15 @@ class CPrefixTrie
friend class CPrefixTrie<TKey, TData>;
using TKeyRef = std::reference_wrapper<const TKey>;
using TDataRef = std::reference_wrapper<typename std::conditional<IsConst, const TData, TData>::type>;
using TDataRef = std::reference_wrapper<TData>;
using TPair = std::pair<TKeyRef, TDataRef>;
using ConstTPair = std::pair<TKeyRef, const TData>;
TKey name;
std::weak_ptr<Node> node;
struct Bookmark {
TKey name;
std::weak_ptr<Node> parent;
typename TChildren::iterator it;
typename TChildren::iterator end;
};
@ -60,11 +60,8 @@ class CPrefixTrie
public:
// Iterator traits
using value_type = TPair;
using const_pointer = const TData* const;
using const_reference = ConstTPair;
using data_reference = typename std::conditional<IsConst, const TData&, TData&>::type;
using pointer = typename std::conditional<IsConst, const TData* const, TData* const>::type;
using reference = typename std::conditional<IsConst, ConstTPair, TPair>::type;
using reference = typename std::conditional<IsConst, const TPair, TPair>::type;
using difference_type = std::ptrdiff_t;
using iterator_category = std::forward_iterator_tag;
@ -92,15 +89,12 @@ class CPrefixTrie
bool operator==(const Iterator& o) const;
bool operator!=(const Iterator& o) const;
reference operator*();
const_reference operator*() const;
pointer operator->();
const_pointer operator->() const;
reference operator*() const;
pointer operator->() const;
const TKey& key() const;
data_reference data();
TData& data();
const TData& data() const;
std::size_t depth() const;

View file

@ -1310,18 +1310,16 @@ static UniValue getchaintips(const JSONRPCRequest& request)
"\nResult:\n"
"[\n"
" {\n"
" \"height\": xxxx, (numeric) height of the chain tip\n"
" \"hash\": \"xxxx\", (string) block hash of the tip\n"
" \"branchlen\": 0 (numeric) zero for main chain\n"
" \"status\": \"active\" (string) \"active\" for the main chain\n"
" \"height\": xxxx, (numeric) height of the chain tip\n"
" \"hash\": \"xxxx\", (string) block hash of the tip\n"
" \"branchlen\": 0 (numeric) zero for main chain\n"
" \"status\": \"active\" (string) \"active\" for the main chain\n"
" },\n"
" {\n"
" \"height\": xxxx,\n"
" \"hash\": \"xxxx\",\n"
" \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
" \"branchhash\": \"xxxx\", (string) hash of the historical block where we branched\n"
" \"branchhashNext\": \"xxxx\", (string) block hash of the first block down this chain\n"
" \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
" \"branchlen\": 1 (numeric) length of branch connecting the tip to the main chain\n"
" \"status\": \"xxxx\" (string) status of the chain (active, valid-fork, valid-headers, headers-only, invalid)\n"
" }\n"
"]\n"
"Possible values for status:\n"
@ -1374,19 +1372,8 @@ static UniValue getchaintips(const JSONRPCRequest& request)
obj.pushKV("height", block->nHeight);
obj.pushKV("hash", block->phashBlock->GetHex());
// not use ForkAt method because we need the previous one as well
const CBlockIndex *forkAt = block, *forkPrev = block;
while (forkAt && !chainActive.Contains(forkAt)) {
forkPrev = forkAt;
forkAt = forkAt->pprev;
}
const int branchLen = block->nHeight - forkAt->nHeight;
const int branchLen = block->nHeight - chainActive.FindFork(block)->nHeight;
obj.pushKV("branchlen", branchLen);
if (forkAt != forkPrev) {
obj.pushKV("branchhash", forkAt->phashBlock->GetHex());
obj.pushKV("branchhashNext", forkPrev->phashBlock->GetHex());
}
std::string status;
if (chainActive.Contains(block)) {

View file

@ -15,7 +15,6 @@
#include <validation.h>
#include <boost/locale.hpp>
#include <boost/locale/conversion.hpp>
#include <boost/thread.hpp>
#include <cmath>
@ -307,7 +306,7 @@ static UniValue getclaimsintrie(const JSONRPCRequest& request)
}
UniValue ret(UniValue::VARR);
trieCache.iterate([&ret, &trieCache, &coinsCache] (const std::string& name, const CClaimTrieData& data) {
trieCache.recurseNodes({}, [&ret, &trieCache, &coinsCache] (const std::string& name, const CClaimTrieData& data) {
if (ShutdownRequested())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Shutdown requested");
@ -348,7 +347,7 @@ static UniValue getnamesintrie(const JSONRPCRequest& request)
}
UniValue ret(UniValue::VARR);
trieCache.iterate([&ret](const std::string &name, const CClaimTrieData &data) {
trieCache.recurseNodes({}, [&ret](const std::string &name, const CClaimTrieData &data) {
if (!data.empty())
ret.push_back(escapeNonUtf8(name));
if (ShutdownRequested())

View file

@ -451,7 +451,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
if (strMode != "template")
throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid mode");
if (Params().NetworkIDString() == CBaseChainParams::MAIN)
if (Params().NetworkIDString() != CBaseChainParams::REGTEST) // who should own this constant?
{
if (!g_connman)
throw JSONRPCError(RPC_CLIENT_P2P_DISABLED, "Error: Peer-to-peer functionality missing or disabled");
@ -567,8 +567,6 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
// NOTE: If at some point we support pre-segwit miners post-segwit-activation, this needs to take segwit support into consideration
const bool fPreSegWit = (ThresholdState::ACTIVE != VersionBitsState(pindexPrev, consensusParams, Consensus::DEPLOYMENT_SEGWIT, versionbitscache));
if (!fPreSegWit && !fSupportsSegwit)
throw JSONRPCError(RPC_INVALID_PARAMETER, "Segwit support is now required. Please include \"segwit\" in the client's rules.");
UniValue aCaps(UniValue::VARR); aCaps.push_back("proposal");
UniValue result(UniValue::VOBJ);
@ -623,6 +621,7 @@ static UniValue getblocktemplate(const JSONRPCRequest& request)
aMutable.push_back("time");
aMutable.push_back("transactions");
aMutable.push_back("prevblock");
aMutable.push_back("submit/coinbase");
result.pushKV("capabilities", aCaps);

View file

@ -436,9 +436,17 @@ CMutableTransaction ConstructTransaction(const UniValue& inputs_in, const UniVal
throw JSONRPCError(RPC_INVALID_PARAMETER, std::string("Invalid parameter, duplicated address: ") + name_);
}
CScript scriptPubKey = GetScriptForDestination(destination);
CAmount nAmount = AmountFromValue(outputs[name_]);
auto rawAmount = outputs[name_];
CAmount nAmount;
CScript prefix;
if (rawAmount.isArray() && rawAmount.size() > 2) {
nAmount = AmountFromValue(rawAmount[0]);
prefix = ClaimNameScript(rawAmount[1].get_str(), rawAmount[2].get_str());
}
else
nAmount = AmountFromValue(outputs[name_]);
CScript scriptPubKey = prefix + GetScriptForDestination(destination);
CTxOut out(nAmount, scriptPubKey);
rawTx.vout.push_back(out);
}

View file

@ -64,20 +64,8 @@ void CScheduler::serviceQueue()
// Explicitly use a template here to avoid hitting that overload.
while (!shouldStop() && !taskQueue.empty()) {
boost::chrono::system_clock::time_point timeToWaitFor = taskQueue.begin()->first;
try {
if (newTaskScheduled.wait_until<>(lock, timeToWaitFor) == boost::cv_status::timeout) {
break; // Exit loop after timeout, it means we reached the time of the event
}
} catch (boost::thread_interrupted) {
// We need to make sure we don't ignore this, or the thread won't end
throw;
} catch (...) {
// Some boost versions have a bug that can cause a time prior to system boot (or wake from sleep) to throw an exception instead of return timeout
// See https://github.com/boostorg/thread/issues/308
// Check if the time has passed and, if so, break gracefully
if (timeToWaitFor <= boost::chrono::system_clock::now()) break;
throw;
}
if (newTaskScheduled.wait_until<>(lock, timeToWaitFor) == boost::cv_status::timeout)
break; // Exit loop after timeout, it means we reached the time of the event
}
#endif
// If there are multiple threads, the queue can empty while we're waiting (another

View file

@ -1,27 +0,0 @@
// Copyright (c) 2011-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
//
// Unit tests for block-chain checkpoints
//
#include "checkpoints.h"
#include "uint256.h"
#include "test/test_bitcoin.h"
#include "chainparams.h"
#include <boost/test/unit_test.hpp>
using namespace std;
BOOST_FIXTURE_TEST_SUITE(Checkpoints_tests, BasicTestingSetup)
BOOST_AUTO_TEST_CASE(sanity)
{
//const CCheckpointData& checkpoints = Params(CBaseChainParams::MAIN).Checkpoints();
//BOOST_CHECK(Checkpoints::GetTotalBlocksEstimate(checkpoints) >= 134444);
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -18,7 +18,7 @@ BOOST_AUTO_TEST_CASE(claim_replace_test) {
fixture.Spend(tx1);
CMutableTransaction tx2 = fixture.MakeClaim(fixture.GetCoinbase(), "bassfisher", "one", 1);
fixture.IncrementBlocks(1);
BOOST_CHECK(fixture.checkConsistency());
BOOST_CHECK(pclaimTrie->checkConsistency(fixture.getMerkleHash()));
BOOST_CHECK(!fixture.is_best_claim("bass", tx1));
BOOST_CHECK(fixture.is_best_claim("bassfisher", tx2));
}
@ -1852,18 +1852,17 @@ BOOST_AUTO_TEST_CASE(update_on_support2_test)
CMutableTransaction s2 = fixture.MakeSupport(fixture.GetCoinbase(), tx1, name, 1);
fixture.IncrementBlocks(1);
auto it = pclaimTrie->find(name);
BOOST_CHECK(it);
BOOST_CHECK_EQUAL(it->nHeightOfLastTakeover, height + 1);
CClaimTrieData node;
BOOST_CHECK(pclaimTrie->find(name, node));
BOOST_CHECK_EQUAL(node.nHeightOfLastTakeover, height + 1);
fixture.Spend(s1);
fixture.Spend(s2);
CMutableTransaction u1 = fixture.MakeUpdate(tx1, name, value, ClaimIdHash(tx1.GetHash(), 0), 3);
fixture.IncrementBlocks(1);
it = pclaimTrie->find(name);
BOOST_CHECK(it);
BOOST_CHECK_EQUAL(it->nHeightOfLastTakeover, height + 1);
BOOST_CHECK(pclaimTrie->find(name, node));
BOOST_CHECK_EQUAL(node.nHeightOfLastTakeover, height + 1);
}
BOOST_AUTO_TEST_SUITE_END()

View file

@ -37,7 +37,7 @@ public:
return nodesToAddOrUpdate.height();
}
CClaimTrie::iterator getCache(const std::string& key)
CClaimPrefixTrie::iterator getCache(const std::string& key)
{
return nodesToAddOrUpdate.find(key);
}
@ -108,7 +108,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK_EQUAL(ntState.getMerkleHash(), hash2);
BOOST_CHECK(ntState.checkConsistency());
BOOST_CHECK(pclaimTrie->checkConsistency(hash2));
CClaimTrieCacheTest ntState1(pclaimTrie);
ntState1.removeClaimFromTrie(std::string("test"), tx1OutPoint, unused, true);
@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK_EQUAL(ntState2.getMerkleHash(), hash3);
BOOST_CHECK(ntState2.checkConsistency());
BOOST_CHECK(pclaimTrie->checkConsistency(hash3));
CClaimTrieCacheTest ntState3(pclaimTrie);
ntState3.insertClaimIntoTrie(std::string("test"), CClaimValue(tx1OutPoint, hash160, 50, 100, 200), true);
@ -136,7 +136,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
ntState3.flush();
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK_EQUAL(ntState3.getMerkleHash(), hash4);
BOOST_CHECK(ntState3.checkConsistency());
BOOST_CHECK(pclaimTrie->checkConsistency(hash4));
CClaimTrieCacheTest ntState4(pclaimTrie);
ntState4.removeClaimFromTrie(std::string("abab"), tx6OutPoint, unused, true);
@ -144,7 +144,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
ntState4.flush();
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK_EQUAL(ntState4.getMerkleHash(), hash2);
BOOST_CHECK(ntState4.checkConsistency());
BOOST_CHECK(pclaimTrie->checkConsistency(hash2));
CClaimTrieCacheTest ntState5(pclaimTrie);
ntState5.removeClaimFromTrie(std::string("test"), tx3OutPoint, unused, true);
@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
ntState5.flush();
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK_EQUAL(ntState5.getMerkleHash(), hash2);
BOOST_CHECK(ntState5.checkConsistency());
BOOST_CHECK(pclaimTrie->checkConsistency(hash2));
CClaimTrieCacheTest ntState6(pclaimTrie);
ntState6.insertClaimIntoTrie(std::string("test"), CClaimValue(tx3OutPoint, hash160, 50, 101, 201), true);
@ -162,7 +162,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
ntState6.flush();
BOOST_CHECK(!pclaimTrie->empty());
BOOST_CHECK_EQUAL(ntState6.getMerkleHash(), hash2);
BOOST_CHECK(ntState6.checkConsistency());
BOOST_CHECK(pclaimTrie->checkConsistency(hash2));
CClaimTrieCacheTest ntState7(pclaimTrie);
ntState7.removeClaimFromTrie(std::string("test"), tx3OutPoint, unused, true);
@ -174,7 +174,7 @@ BOOST_AUTO_TEST_CASE(merkle_hash_multiple_test)
ntState7.flush();
BOOST_CHECK(pclaimTrie->empty());
BOOST_CHECK_EQUAL(ntState7.getMerkleHash(), hash0);
BOOST_CHECK(ntState7.checkConsistency());
BOOST_CHECK(pclaimTrie->checkConsistency(hash0));
}
BOOST_AUTO_TEST_CASE(basic_insertion_info_test)
@ -281,12 +281,14 @@ BOOST_AUTO_TEST_CASE(iteratetrie_test)
ctc.insertClaimIntoTrie("test", claimVal, true);
BOOST_CHECK(ctc.flush());
auto hit = pclaimTrie->find("");
BOOST_CHECK(hit);
BOOST_CHECK_EQUAL(hit.children().size(), 1U);
BOOST_CHECK(hit = pclaimTrie->find("test"));
BOOST_CHECK_EQUAL(hit.children().size(), 0U);
BOOST_CHECK_EQUAL(hit.data().claims.size(), 1);
CClaimTrieDataNode node;
BOOST_CHECK(pclaimTrie->find("", node));
BOOST_CHECK_EQUAL(node.children.size(), 1U);
BOOST_CHECK(pclaimTrie->find("test", node));
BOOST_CHECK_EQUAL(node.children.size(), 0U);
CClaimTrieData data;
BOOST_CHECK(pclaimTrie->find("test", data));
BOOST_CHECK_EQUAL(data.claims.size(), 1);
}
BOOST_AUTO_TEST_CASE(trie_stays_consistent_test)
@ -303,13 +305,13 @@ BOOST_AUTO_TEST_CASE(trie_stays_consistent_test)
BOOST_CHECK(cache.insertClaimIntoTrie(name, value, false));
cache.flush();
BOOST_CHECK(cache.checkConsistency());
BOOST_CHECK(trie.checkConsistency(cache.getMerkleHash()));
for (auto& name: names) {
CClaimValue temp;
BOOST_CHECK(cache.removeClaimFromTrie(name, COutPoint(), temp, false));
cache.flush();
BOOST_CHECK(cache.checkConsistency());
BOOST_CHECK(trie.checkConsistency(cache.getMerkleHash()));
}
BOOST_CHECK(trie.empty());
}
@ -382,6 +384,7 @@ BOOST_AUTO_TEST_CASE(verify_basic_serialization)
ssData >> cv2;
BOOST_CHECK_EQUAL(cv, cv2);
BOOST_CHECK_EQUAL(cv.nEffectiveAmount, cv2.nEffectiveAmount);
}
BOOST_AUTO_TEST_CASE(claimtrienode_serialize_unserialize)

View file

@ -93,7 +93,8 @@ BOOST_AUTO_TEST_CASE(claimtriebranching_normalization)
BOOST_CHECK(fixture.is_best_claim("normalizetest", tx1));
BOOST_CHECK(fixture.best_claim_effective_amount_equals("normalizetest", 3));
BOOST_CHECK(!pclaimTrie->find("normalizeTest"));
CClaimTrieData data;
BOOST_CHECK(!pclaimTrie->find("normalizeTest", data));
// Check equivalence of normalized claim names
BOOST_CHECK(fixture.is_best_claim("normalizetest", tx1)); // collapsed tx2
@ -222,7 +223,8 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
BOOST_CHECK(!trieCache.spendClaim(name_normd, COutPoint(tx2.GetHash(), 0), currentHeight, amelieValidHeight));
BOOST_CHECK(trieCache.spendClaim(name_upper, COutPoint(tx2.GetHash(), 0), currentHeight, amelieValidHeight));
BOOST_CHECK(!pclaimTrie->find(name));
CClaimTrieData data;
BOOST_CHECK(!pclaimTrie->find(name, data));
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
BOOST_CHECK(trieCache.addClaim(name, COutPoint(tx1.GetHash(), 0), ClaimIdHash(tx1.GetHash(), 0), CAmount(2), currentHeight + 1));
BOOST_CHECK(trieCache.getInfoForName(name, nval1));
@ -234,9 +236,8 @@ BOOST_AUTO_TEST_CASE(claimtriecache_normalization)
BOOST_CHECK(trieCache.incrementBlock(insertUndo, expireUndo, insertSupportUndo, expireSupportUndo, takeoverHeightUndo));
BOOST_CHECK(trieCache.shouldNormalize());
// we cannot use getXXXForName cause they will normalized name
for (auto it = pclaimTrie->cbegin(); it != pclaimTrie->cend(); ++it)
BOOST_CHECK(it.key() != name);
CClaimTrieDataNode node;
BOOST_CHECK(!pclaimTrie->find(name, node));
}
BOOST_AUTO_TEST_CASE(undo_normalization_does_not_kill_claim_order)

View file

@ -19,7 +19,7 @@
#include <rpc/register.h>
#include <script/sigcache.h>
#include "claimtrie.h"
#include <claimtrie.h>
#include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_parameters.hpp>
@ -81,10 +81,10 @@ std::ostream& operator<<(std::ostream& os, const CClaimValue& claim)
std::ostream& operator<<(std::ostream& os, const CSupportValue& support)
{
os << "support(" << support.outPoint.ToString()
<< ", " << support.supportedClaimId.ToString()
<< ", " << support.nAmount
<< ", " << support.nHeight
<< ", " << support.nValidAtHeight << ')';
<< ", " << support.supportedClaimId.ToString()
<< ", " << support.nAmount
<< ", " << support.nHeight
<< ", " << support.nValidAtHeight << ')';
return os;
}
@ -144,7 +144,7 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
pblocktree.reset(new CBlockTreeDB(1 << 20, true));
pcoinsdbview.reset(new CCoinsViewDB(1 << 23, true));
pcoinsTip.reset(new CCoinsViewCache(pcoinsdbview.get()));
pclaimTrie = new CClaimTrie(true, false, 1);
pclaimTrie = new CClaimTrieHashFork(true, false, 1);
if (!LoadGenesisBlock(chainparams)) {
throw std::runtime_error("LoadGenesisBlock failed.");
}

View file

@ -26,7 +26,7 @@ struct CDiskTxPos;
//! No need to periodic flush if at least this much space still available.
static constexpr int MAX_BLOCK_COINSDB_USAGE = 10;
//! -dbcache default (MiB)
static const int64_t nDefaultDbCache = 560;
static const int64_t nDefaultDbCache = 500;
//! -dbbatchsize default (bytes)
static const int64_t nDefaultDbBatchSize = 16 << 20;
//! max. -dbcache (MiB)
@ -34,13 +34,13 @@ static const int64_t nMaxDbCache = sizeof(void*) > 4 ? 16384 : 1024;
//! min. -dbcache (MiB)
static const int64_t nMinDbCache = 4;
//! Max memory allocated to block tree DB specific cache, if no -txindex (MiB)
static const int64_t nMaxBlockDBCache = 16;
static const int64_t nMaxBlockDBCache = 4;
//! Max memory allocated to block tree DB specific cache, if -txindex (MiB)
// Unlike for the UTXO database, for the txindex scenario the leveldb cache make
// a meaningful difference: https://github.com/bitcoin/bitcoin/pull/8273#issuecomment-229601991
static const int64_t nMaxTxIndexCache = 1024;
//! Max memory allocated to coin DB specific cache (MiB)
static const int64_t nMaxCoinsDBCache = 32;
static const int64_t nMaxCoinsDBCache = 8;
/** CCoinsView backed by the coin database (chainstate/) */
class CCoinsViewDB final : public CCoinsView

View file

@ -2,7 +2,7 @@
set -e
srcdir="$(dirname $0)"
cd "$srcdir"
if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="$(which glibtoolize 2>/dev/null)"; then
if [ -z ${LIBTOOLIZE} ] && GLIBTOOLIZE="`which glibtoolize 2>/dev/null`"; then
LIBTOOLIZE="${GLIBTOOLIZE}"
export LIBTOOLIZE
fi

View file

@ -1562,8 +1562,12 @@ DisconnectResult CChainState::DisconnectBlock(const CBlock& block, const CBlockI
assert(trieCache.finalizeDecrement(blockUndo.takeoverHeightUndo));
auto merkleHash = trieCache.getMerkleHash();
if (merkleHash != pindex->pprev->hashClaimTrie) {
if (!trieCache.empty())
trieCache.dumpToLog(trieCache.find({}));
for (auto cit = trieCache.begin(); cit != trieCache.end(); ++cit) {
if (cit->claims.size() && cit->nHeightOfLastTakeover <= 0)
LogPrintf("Invalid takeover height discovered in cache for %s\n", cit.key());
if (cit->hash.IsNull())
LogPrintf("Invalid hash discovered in cache for %s\n", cit.key());
}
LogPrintf("Hash comparison failure at block %d\n", pindex->nHeight);
assert(merkleHash == pindex->pprev->hashClaimTrie);
}
@ -2041,7 +2045,7 @@ bool CChainState::ConnectBlock(const CBlock& block, CValidationState& state, CBl
if (trieCache.getMerkleHash() != block.hashClaimTrie)
{
if (!trieCache.empty()) // we could run checkConsistency here, but it would take a while
trieCache.dumpToLog(trieCache.find({}));
trieCache.dumpToLog(trieCache.begin());
return state.DoS(100, error("ConnectBlock() : the merkle root of the claim trie does not match "
"(actual=%s vs block=%s on height=%d)", trieCache.getMerkleHash().GetHex(),
block.hashClaimTrie.GetHex(), pindex->nHeight), REJECT_INVALID, "bad-claim-merkle-hash");
@ -2184,7 +2188,7 @@ bool static FlushStateToDisk(const CChainParams& chainparams, CValidationState &
// overwrite one. Still, use a conservative safety factor of 2.
if (!CheckDiskSpace(48 * 2 * 2 * pcoinsTip->GetCacheSize()))
return state.Error("out of disk space");
if (mode == FlushStateMode::ALWAYS && !pclaimTrie->SyncToDisk())
if (!pclaimTrie->SyncToDisk())
return state.Error("Failed to write to claim trie database");
// Flush the chainstate (which may refer to block index entries).
if (!pcoinsTip->Flush())
@ -2772,15 +2776,13 @@ bool CChainState::ActivateBestChain(CValidationState &state, const CChainParams&
if (ShutdownRequested())
break;
} while (pindexNewTip != pindexMostWork);
auto& consensus = chainparams.GetConsensus();
CheckBlockIndex(consensus);
CheckBlockIndex(chainparams.GetConsensus());
auto flushMode = FlushStateMode::PERIODIC;
if (pindexNewTip && chainparams.NetworkIDString() != CBaseChainParams::REGTEST
&& pindexNewTip->nTime + consensus.nPowTargetSpacing > GetAdjustedTime()) {
if (pindexNewTip && pindexNewTip->nTime + chainparams.GetConsensus().nPowTargetSpacing > GetAdjustedTime()) {
// trying to ensure that we flush to disk after new blocks when we're caught up to the chain
// they're technically allowed to be two hours late, but experience says one minute is more likely
// LogPrintf("Added tip with time %d but it is now %ll\n", pindexNewTip->nTime, GetAdjustedTime());
flushMode = FlushStateMode::ALWAYS;
}
return FlushStateToDisk(chainparams, state, flushMode);

View file

@ -57,7 +57,7 @@ static const bool DEFAULT_WHITELISTFORCERELAY = true;
/** Default for -minrelaytxfee, minimum relay fee for transactions */
static const unsigned int DEFAULT_MIN_RELAY_TX_FEE = 1000;
//! -maxtxfee default
static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.5 * COIN;
static const CAmount DEFAULT_TRANSACTION_MAXFEE = 0.1 * COIN;
//! Discourage users to set fees higher than this amount (in satoshis) per kB
static const CAmount HIGH_TX_FEE_PER_KB = 0.01 * COIN;
//! -maxtxfee will warn if called with a higher fee than this amount (in satoshis)

View file

@ -469,10 +469,10 @@ bool BerkeleyEnvironment::Salvage(const std::string& strFile, bool fAggressive,
}
void BerkeleyEnvironment::CheckpointLSN(const std::string& strFile, bool lsnReset)
void BerkeleyEnvironment::CheckpointLSN(const std::string& strFile)
{
dbenv->txn_checkpoint(0, 0, 0);
if (fMockDb || !lsnReset)
if (fMockDb)
return;
dbenv->lsn_reset(strFile.c_str(), 0);
}
@ -799,7 +799,7 @@ bool BerkeleyBatch::PeriodicFlush(BerkeleyDatabase& database)
// Flush wallet file so it's self contained
env->CloseDb(strFile);
env->CheckpointLSN(strFile, false); // too expensive to reset LSN periodically (and it's triggered on flush or backup
env->CheckpointLSN(strFile);
env->mapFileUseCount.erase(mi++);
LogPrint(BCLog::DB, "Flushed %s %dms\n", strFile, GetTimeMillis() - nStart);

View file

@ -83,7 +83,7 @@ public:
bool Open(bool retry);
void Close();
void Flush(bool fShutdown);
void CheckpointLSN(const std::string& strFile, bool lsnReset = true);
void CheckpointLSN(const std::string& strFile);
void CloseDb(const std::string& strFile);
void ReloadDbEnv();

View file

@ -15,5 +15,5 @@ RPCAUTH=@abs_top_srcdir@/share/rpcauth/rpcauth.py
# Which components are enabled. These are commented out by `configure` if they were disabled when running config.
@ENABLE_WALLET_TRUE@ENABLE_WALLET=true
@BUILD_BITCOIN_UTILS_TRUE@ENABLE_UTILS=true
@BUILD_BITCOIND_TRUE@ENABLE_BITCOIND=true
@BUILD_BITCOIND_TRUE@ENABLE_LBRYCRDD=true
@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=true

View file

@ -1,117 +1,117 @@
{
"blocks": [
"0100000000000000000000000000000000000000000000000000000000000000000000003ba3edfd7a7b12b27ac72c3e67768f617fc81bc3888a51323a9fb8aa4b1e5e4adae5494dffff7f20020000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff4d04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73ffffffff0100f2052a01000000434104678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5fac00000000",
"0000002006226e46111a0b59caaf126043eb5bbf28c34f3a5e332a1fc7b2b73cf188910f1cd16b94f20a8a3dda91027c888025f2ec1a07ddcb2786bdff5916e66c00406f194ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002014341131c18d3b3aa30056a0f7a97c9ac852d3fd0ec9c76f7a25e83c01e7f821bf83574fb606f25c59200c844443201faf923ef5284fd4401f3104a323c601491a4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03520101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002078616da95299bd42cd8f813c8043816ec5741de466be3162e16bfff471808461f671e694afaf534d37df484f1990fc19a65fc26964b38141b7f8ecf61b8a50241a4ae75affff7f200500000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03530101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020a08613f37d305835a3a1553e77a479eba0f34c06c52e429ece54f5973cd77a7086a1efcaf75f1cd5be2c9deb6a7850225757a2cfc3031a91cc1330b3af4acc891b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03540101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000203b304fa1ce0505c2366982939ac148d9124c5ac747cc9aea133cea9916484966305de0e8d049f2be65c68d64d2c45746def5a9b4fcb8e298692b53b83b4690241b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03550101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020fbdf49978ec4f0b23704b6772a614336872587e29c463f375836ffd775248837fed9f3fdfc33f076c6663ae78070fad7263c1e24161f3ee1a4857b8931815e2c1b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03560101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020c37548b9ca256b9ff17187d4d4309cf3143845b0a5811d3ca5427b2fddf000731a10985dfd473561c070c3527c3fe3941834cf51b3dfbacb501b44c69c9745ce1b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03570101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020383dd3766c0675440f26370ad62d687e335ea3a650dec9b02fe544107cc1823a13b98696d41562945457d655f4c6921f736068f7a72afd1ad6b335f2857d16631c4ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03580101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000207476dd96d81f53e63934ce28c9e89022e0f24d040ec3c838443e925fc3a2f230a94d0cbcefb4a151191dd7664153944d9eee3b7b46d4ba997f397ed2b72c3afe1c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03590101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000209e425c73eea16cce98c0d47d6070aca29f0524eab4b97af84c386aa5322dd43055002f097e929bc6ad88ce869968e1b049aab7f6e45a5b869cf4349afd5d43e01c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000202090e16a514fad40386413a100bbaa4fc14086a8d3501ac64c91fdef922e834a369e409444d0ec496eb0dd9a47f1fe81a7ab974bab28c50a912b994acf13b5f91c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020777b767e42624c52775b331f19e81ba03be2f51a0608166cd5388c1a47d5e776473570bb9bba553a7db4a9a3083533027c54af1fea3ef6ef67757ef2255d64631c4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002076bb2bf3251a51ec367a42f8584043171a5d53157394cd776ebd017e2982127653d953aca3e2217f56533c043c07b9a926a30672ebce2562f1d06a6dc5044e7b1c4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020e6d7f02292655b73fc1f1958b09633ba07265d71d2a2784060b354cbbf1900202e9c9b02b63170002a94a0c9d8d787e2faa4c074a1ebdeb2855555347321dd101d4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020d61f077b0ed326e17f0a3d5af3fa876b72b434a252c9c3248d20130ed744287fcb10da470222dd29c7a07e2da7eb25d6499ed3919676df89cc630bd1b23fbb411d4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff035f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000205efa9741cf51533ed6e07a97c71768372f53ca9c6df83894d64fe94c718eee23a207441e79ecdcf99ef3326385f5f675e2dea84c85ab8973219c63f92847ed5b1d4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff03600101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020368386b0a0f46b2a2c4648eb9cb5dd1380c4f22e437e0bd49420670993361e5b9026632c2ddbb4b31b3c3118c51e43ea4d78e05c0aca0956278ead26a263d1521d4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401110101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020dd0a1594bbff6345a3e34f326e5ee605c855f5e0a5c363fc39615a8b1539b736200b51297dbee4aadf9b536cd2afe7617651e0a1d0f0610f436518a2a4dc54621d4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401120101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020f302a1092709dc27a32d7229d391b90824a75828692c4bb2ca8f0ca5c88b3613c2e18797ffe8b367336338f90b2cf8c3f66277eb1e1ddbe18c052977294f10691d4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401130101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000203dcc77aac703a8cd0e799384b74383c1d5f236426f77d516694607fc88fe85581276a20ceb98d02e6355c9dba4312e2fdc9832f4302cc307e1263f2df0aadd6a1e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401140101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020dfe109704a0b2801aee4232c31fb744145a7c80dd91a7727e16d4057719d5c3730f8296243521d82d96ed75c5af800a722fc9dde2e02af95c8c9822190ba07b21e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401150101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000201ef9ef2699bc36fd646bb9ba8629644bc98396122f6753710caf0315d7539f751382d3d85f17eb8b42cf17e54baa327886dcf6fa63207e097df8f9b84cc5422f1e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401160101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020834c91f23cd91b727be08b892f1c1a2f33c1e66d66f35607925fa1be4bca2c25b4145a73b1c71b945f5bb9ede3d8d95c9a3b12a0a81b7b14f440ec5146dd4ec71e4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401170101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000205743202bf1e543a9be2a59b62be6a5a494511fab96968007b8d7199ea60a524697227ba473ceaf48d4f48ee17f8ee6cd2f1f5ddff03a641642ece240e7872f8f1e4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401180101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000207469f5c1841bf57275d82db23e5a8f0e8512af1eb10119c238519cdd6cdced34fd96dc659a874b3f5d30fbe6ea421a6b9791dfce8450f8851e4b90d80f0f794e1e4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401190101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020b6338f55fcc473b744d53d675b4a83dcd80ddec9d02ad3323cf1ff50ac0412239d986ec20885d772fdc67803273aaec43871426ac93d3815846a8cd13dea5af11f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020a19d9edf2d22415cf226b4e1416c8a3097e0af222efac2bfeab15fa1f07b3f24c18580c4004de6d6244a30ce431c4be3ca44731509fc6b11710c792efed5e9191f4ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000208f9f29a27424ec01ce77485617088506ca8faeef69300f0a474ad63ca5d32972d6049609fa3588d6ffab4d9d89a90636ac94c0ca1995f7768163abeb25dbf2bc1f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020fbd87d530a9ec3835ab579337fd16e512cec6c4779ab4d84e7256b3333dece28de1065c8c3d3d166e057139ac59af6f4f2c0d241b6269bbea6f61c5eff3dba431f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020dc6ef4f436baab2d6880f242a2588313a2739ac694e30319344045ee318c9524d0ec7fbcaca30ce85392cb03b64015ece769afb50fd07db05c15ec49abf7d71c1f4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020386bf4cbb3708ae6345b9f2459bdd99d07422b05f9b005d2d4d1d3bf87d47359ebb22b3a15c8e94ddd8129527873b9bebfa10c54d11196961376efbcaad3c4681f4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04011f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020600e892f12ad82a23ce12684d3ffa0887eab5e3e97804fa651050b23366cc55ef2468e65c3d3cf49650657eb47d0b0b7949c71dcc0922eb824523157b7eff478204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401200101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002068e4aec52a3f4e44279e3a65cd476237bdfcc2328390bb31b8a903f89ddfa70e8d669f61b469acb31b1d4ecdc238e6616a83a30644a5d06fc2ca1aad6449d09b204ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401210101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020cf2428ae9a5014b910275807f54a8bbbeec47d462f9d284ada60329b4955ff10cf83c44ddde39a709aef54fb302c7f1cb36db8fe7c3befce20dcc3729767518c204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401220101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000205801eef8cca082407ce4798648c4d3ba0fc4dd2d4459eccfe5300c7960760d16cb3dd78a2f22fb88717a175e45c53d34f970b94ef9f7cd1b6c279294d427d163204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401230101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002088320983a4bcb95b9f342994c6943c227f3102d3b16282f048ceb8e15748662a52d1207591a0a364bc9245a76e36530f147ec4d1b4e1917676b4071f542c3b19204ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401240101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020acd85b6d8087d3b6bd2a208a2e39b75da459c0e0eb14088075a23a2e043e8a4ed5a1754491f8180d293b42e6c04ec3f82e29c1f2600dc8607616f69a4a464e6e204ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401250101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204873bcb379f78da4497ce1e22f6bfb63537b89c8c522257a7b7bef74e515ed1b6b235faab048fa73a76c68fdbdde6a4ee7ebe0a3b7b23df24ce75dbd2cf49c33214ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401260101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020a87f6d13bae8e2e07996c3316e8e0da6aec7d1aee6b80aa5883018e4d136db3e9a498ff7d322ad93863e0a5318af7e7d0ed683fd2e4ecf523f2b7369106dbe4a214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401270101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020d9b0618450a51c08f43187c479e20d351f0466464409bb3071dc0af7c51d65498a198cef23dddd2c4b93d9d3288ae922584e221a9ef1ded3dba5a2ad494d9237214ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401280101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020167dff31847b8dcad472bb6bb7d0af53b245f0f1d4c9f83d4ce14a0f05d42d7f0f2638ffc0e6896230f28df1865ef133dccb1f027545c6a1177dffd1fecf8a01214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401290101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000208236c04424573692504e777e179b9247e54622b118239311413812f13cefbf6e39a639143f599dc76208b2014de12a364716df2918af9186453e3676dca743d7214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020fab7b55aeb59f63315dbc10784c55e55635a7600cc4f3b94a00003007e7fc90b4af016248e9908882f8a7f0bd8743c8da82da119446e8b02e4d3b8d1d938a3aa214ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020794b4160d8fd4ebe7611d0fc9d3e04f3038a485669f74075aa153852ed181121c577f4c0b7151f6d78a16e3c21ab291b53ced8a5c4f05a22caf24a25ed029d56224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204a8acdb549d2ed922360ae0e81de6c913c3fd84b0de51abacbf97162a99f7c26c656b252d3259c33ffc7e5d403843accc6ace9b7e60e911e2347a6a0b0abd122224ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020dee6d00c7058b3422e4273c98c16181e04ea93116496a8442de546c2ee9fd86b550013f39e004b3829dc3717b17fcfedc87de9450315fcca540963119cb264c1224ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000202ebca471f5fb2226a790233c3d0bc323f73d935872f3e15b66bd5fdcb822101d7b68788ed61d3fb8cb746f627e09db2fc09d8a07672747709d92ae400e053e78224ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04012f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020ee500470fc1c71a82f2cbb9f8d5723bcdf57b8051fc458a8dbd8d0dbf60d0e40d1a0be0e50f3312d4830e3900186e5a6760d44006c164b4f0758218ef2b2de8e224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401300101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000205057e8d8a7451d79325851dc8e0f4dfdb1dfaaab637509d9e61f0e064af5ee5c185221c53c0cf43261b3c238c0e8117da5d6ac60085615f7a3d8027726cb2143224ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401310101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000200907f01d9c5c872296796ca77feb62eb414cc080e13a93e59e181528bc19c336eaabacb1ebcbd20b26f6bacdc712ffe17d4c8131e7f99b9cac309c0683737c04234ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401320101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000209bd6a4ec962d9e6199c0a2f39481a7ecc322fedbd2320cbe7dc984c6ab958421fe7a5c7f2513a3c3de9ddf7b211f5bfe85675b31183c4bb98ae79ab28cd055ac234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401330101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000202b8a6381b7c9476fd77be379a929863db6b7edd9858d6eca0f68a430dc87cc3a9c6c8b34bfadfdacbe95cb1d4ae5ce4e4f4ccf0300171d7a91cdc97f620c7b37234ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401340101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000203d3e9a0b4decf12b4402a2178b60599311c8a9c7d50ece365a61ca29530da7056754ddf7d77a11cc8ce680a74fae01d851bda024fc9c51712c55b4a190caef24234ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401350101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002067fa05082d4f7a29a3985f30798940cd854c76a2b20e9560b2047f7753193f71ac61b8df17a8a63f099c8f55869301fc2a0aa37355a4a2f89078135ee72a1362234ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401360101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020249684272865fec3ad62ecb73dfd930500e32e475306c9e5d4b6d545e3687b0a48deaeebfafa213f0a560994b3f4000d5e2b93951d7e5be40073503877292dc7234ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401370101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204671db1df91098669bb03c3e8504d432da99853601366c7de7585bb8f23a6e1e2996a16c11a0f9ae87d937f566c8bbd919040528c1bf8dae4e22a8f0ac5f935a244ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401380101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000203046500cabfee552ed114c505279cd75c28faa811adcb5010c53c14df5de3216d265321a4168c70fff1c85fd83bd976cc03c8c1fb6567398cc24053e343ad137244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401390101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020591533cf8dd1fa1872c7e6d62ef714b28886f38f7921ee614e13b748eaf923282a96287277f18b1113a9c3ac384fd7b43bccd0e45114908ca5396a76cbd736fd244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000205286b5747d0244a55e1dce435fdbb9f300d7138fff3b16767bc09196eb00256c6795e3f372a2d5d137244a4fd72fd799e8de913f868f22269eaa628d7d2970a1244ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000209649b55f6a5ff0d5db73aeb7089fcce605fb9dd23971e577b73747ffab586f4edf84581240223e2d8912a6eca049e06aa46ddbf271af08e9ac9605505311418b244ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020fe7ff82c11ad3a3db3dc11a03a67e0b86b727d232c80f37209b028bc2689296c0da76fb756e1c9833f38b198cfe843ab820fbc0c38e30f8f858f6ffdbd64e834244ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020c02e6109b6aaf6643cac109ad5b5be7f7ec47c7993335bdceea6e0e490ae9067eb1fcee49ecc40a61477f934e3b9821f2cc7ada429fcca2cd645866742854c40254ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020956c46fce0adfc8a30d91c7b7f328f17c2a90771083884c4fdb7f24640598f6fa69c4e5971bd3b6cdc7e3ee98e03a969b28c3220fdc685cc2eb77293763ca4ba254ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04013f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000203eec7d0ea9c539f47e684eec9dba900e27c805b8200f237924c7df8065957726c83caf659fa341bf45f733a92cf76daf2cfb6bccbf969a2753f5f7d9cda4bd1e254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401400101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000203c022b42283bf651ee4d536fe71b7e5382e9783d4a85f8bc159f00b97f16d82d312ac4f89f1b1496de576811f2ff17de44b512db0beddae59e030e2ce3eba4df254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401410101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000205da9709dea4bea4f3229d0eed439a4820a0e817f9fbbcd8bb355cd8052702973403358080a2881b823a740f58b6b0c922b42189e06326478cc33390f2c704743254ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401420101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020447c49f664916cc13a839e27f7cbe0b09dea990dec71dd479b537ecfb771c7159ae6241727c2645ce00817909ba97d43447fe2e146bce55b7dccd5bcd27d2e3d254ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401430101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020ae3b214b1495953eea3b99af7ade4b8d22d615d598dd6c790c6576d6453ef35d37fbd3446f8431f00052f278c3e0359beba54a2f5064bc6be4990478fcf4e086264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401440101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204cc68f9f571f59145e1f7505550d56da13a797fbc7e5a178dd7f6f9241d91f007f2400f7aa1b32b30bf869e4da86f75eaf2baae182efc45c42c6245f06aba675264ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401450101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002096d55714a83c3d030cc72141eac3577b8a394b8366b2c93354fcecdafeab025022f5e26de7e4eba3f8e4a09f243b55ea6f08bfd013e2051cf1d5df20dcb3331b264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401460101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000202ccf49665bd46e4915dcc9221f5fc72124bb73fb11fed8869dc5862a47950c0d654693a1d86098212d68fa9a27f9df0faafea4aecebd8b203f2ab8f3f0b86196264ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401470101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000205d0be5aea546eab7734cbee757ea5f4983ab3a3f202323c1c88590bdbc8b561974cb0de6549bfdec92322ad53d8a4192433edab0e33a10e7561d2e27c7759f8a264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401480101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020fc3d70d4f690d7d7da90b1c832a51c2a92940cdd9fccda6a909c7256ad567160550e1089b48fe75f0f1e6f712cc2a1d4aad384a4ceacf1c71576420fe8e7de46264ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401490101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020995ab1f2293e3aa1e7bef418919bdce60032e89e60223b8c12b17488c50af83b3a360b4f89551aa0ced646a6210b0c3d3f7d0464faa248b9d252c89615babc9f274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020e02dd5e1201ebe7ef453e77df3021cffde1b5447b9eced017963489e005ac247e1f2b80e91180cd9744c3e126eb8a0fb34ced45587da6b0fa9fd1c6946f049bf274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002081b265800d61feb37525c58aacc7e6d32cfc6b6579784f9952dca51c3addeb37da900ae4ec1b2075056001a361c0fc8f9ac1ca018bde2a2bd8fc587424dfe18f274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000207daba0dc6fccc067a19dec46770d1443fc715b50540242ff26073a6748bcd9583804c315b783d4f9aac4dc8f109fa60bcbf1c3cf98a7e1e593fcb969e88aafae274ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204a35ab2d9c4656c4992d2445ee566e4f5cd0468358292c94839de2b270ba0628de9148db03da59ca2eb727a4f7a03f2b9ee1e4045f37bdaa4b75a89de56b63ee274ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020215ed7b31d118a45a06407133e41f3f9d25c913ff98f3e798144f981d9145305266efc9274f7c836aa0f8b831732aec2c1d85c5bb9176af4c889a707cca380fc274ae75affff7f200400000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04014f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020425321a1f12ed4613b63b3cc5b4c7674242c3de67ea86984f2d9bb2766f6220a5c460ce6840832b7ef05f206c5d255bc2d8ea83753a7f5ef5c0bf3dbcbc7c74a284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401500101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204e088cfd312091bf589f0fc24131dba20ed83f716530a7b033356e9ec803be23a73c4af5b64fc631d20aa1f646c7c61c4cc5d4be6e2fa29570030d72219726a0284ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401510101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204287a2bf40300e39b45d6667d6e17abba37d98c41efc7023fd21b643fb2f6b76d915d10e1f9e224d3bfdf5203da57173f0b8d8eedc92ed9ff23372927e86073b284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401520101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002083137929ca902f409a1f35385b4d31e0f5163d488d71b00ade724d7831986a280a187c13fe0db45aed5fa4f5089d544a617da9f4f80fe6ce1d0711b228f3a6bd284ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401530101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020b38c074d78cbcc8bbbf20c48e30639c2dcf444488efee59f5aa01c48322a30418009c11df7e14de6a6d0d72cc22f20ff5fdba3a7dbe409409ff92b1302340fb8284ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401540101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020a6865148220c7f5ac3259f57fa381676d6be5fdab56eed8e060808fcce4118492476fe6d5ecc681e7a18c20a04239143de1c2cddefbb08f15153b8e9b0c22f62284ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401550101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020ae146263f4087106b8c51ffb5cdddb03a4e593ea1a22a8f6580eaa374185126db2187dbe694a1b17b7c5664115307965407274c25bf6ae02049817685f923256294ae75affff7f200600000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401560101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020718abe22705f33134812b56d04c129d453da890e27caf6e77d2bfb3f9be460083634f35fc8ea4a29b0f30d6c6b4926455a31de62d2f763bc95c8cd1a7a425599294ae75affff7f200300000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401570101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002084537c50520f4e6b0173926320c3193f6b4259c9a724fe202337d3d5cf7da70b1104e1d6f25c411165a856a0bfdd5ddbe168238425c05271962aa6e5ebb676fb294ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401580101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204bae65b948c9790468cfc8fbf78a81e7aec5407dbab18c18ef1ab37a13f0c257792cd1246dac5ce265a8439e539db1aebe4776535d422315bac8e57a51605aa6294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401590101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000201e68985b2a15920524c3c2da77354c0ccfb202c3ab4005128eb2743aa33f0a5b0527a624a6d1f808c896d8cd1552c251a4ae5310e6c62493977b0965d17f580d294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015a0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020ab1d90854505caa1ee748c1987f4cb6674844b84d17224bc3983fdd6e44a930b2edf3e5a90be7a9080ad15014ce796b38b6c19ddd3754443243fc277bcd2368a294ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015b0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002062242f316efa083c17e2173d9f9831afc1465f3fe84431d8e52fec71ae358b243e29246e0db770708987f2cff380920321636926d9c66c2c808d2d5f0ed27d672a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015c0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020258c1a9b0ca17819d8d7fea5178e9c72c2e7c6769696f70098e0d5d2a9dc0e5cf039f5f686d727c6158ef5405ee8794ec2f89c641093a1dff0f5240263a441bc2a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015d0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020434ce26cddae99571a1d663419d715f88e6ff0e413c45f21c44b1991d041fd2745534db221054e2233052aaffe7d7232a91b3f0918c14eac74b2f704b37bfb8e2a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015e0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020ec94475f112ea37dddd84f066e61446b431d28d2d9b6fbb336d16295e7eece52f1dc01abb3b27e71d8a25c3ed2d6fbbc5900bf954738ed63d57689ba5e68f6532a4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff04015f0101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000206188cca18a2be3b7f0b500a724f1b73312873488f04c5082abd81ca0b2250a75ec0efb2fa994ad23e1f39416e69976e66fc4ef9f101bd4f60fcee1f8c45a2b802a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401600101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000202384b91bd0bfb1385ef42bda9b2fa43930aa8889214bb14f63c61a74f380dc7f9d547f2925ad39b9161fa55b9cd258463fd058234778a7c7b3061113d64179812a4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401610101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204c266a3008c3bd95ae4bc8228bf878595cabf76cc2ef3fed32936777fe37833a1a13ea016868b2352a8d6d1eb35d0aee784cef06ed50655b8d84c089324351df2b4ae75affff7f200200000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401620101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"00000020ab2c78d1249de8482cf26bfb1616ac04f7b8404eafcae3e0654f398943fd41571b4d7549862be0b06ed1408ddc3e7c01b07af24c203a18fe9744e214b14d2d652b4ae75affff7f200000000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401630101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"0000002031aa0fc5e0242a9c9d91024b6b7e67544da72c4773537f881ee5caacd45a3c38c650ff5fa0ffd080b3e5f9752527b718e8c6b731467028e14b0b009d4e7406ee2b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401640101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000200418c57609fc6ea3f24f569dc3afe163538a6aab940fe8c3d73c72cd781221380482c6f8ef2c19429da2f7a842bb811496aa86247c55f7ecb3337718b694d9472b4ae75affff7f200100000001020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401650101ffffffff0200f2052a01000000232103836d350d84c3782a7579c5f542c7e70fe628d3062c6bac563d2264c21e56f70eac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf90120000000000000000000000000000000000000000000000000000000000000000000000000",
"000000204f36abaf10d6a8b3113103f3413475db0640c89a39f02a718e8bd2190fe87f1d6ffaf2b9fdbed67ebae4b36c97f9582814c99c90d0b5123f14da4861bf3e4f742b4ae75affff7f200100000002020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401660101ffffffff02b000062a01000000232102f6869601b2b9980b07fc047e309c1fc1433e08c5bf0498115c5c0e117ef59bfdac0000000000000000266a24aa21a9ed5896cd6a40cd126b09e317cbd179f39e2bcef2f9d423751d980258396416e671012000000000000000000000000000000000000000000000000000000000000000000000000002000000011cd16b94f20a8a3dda91027c888025f2ec1a07ddcb2786bdff5916e66c00406f0000000048473044022046d00465c4508cfd02fcb878b19d120e28be28e40658b1f15458828891ed1541022036aac054f36a42666dfb7b42a20506315a0b72232ce7704406e23c7a9515178701feffffff0200286bee0000000017a91481ddd4a9708ba8088cdcfeab9583ede8d83a298c8750bb9a3b0000000017a91484e16967722289584257803688aae36cd64480688765000000",
"00000020cc7c39992f2dae21e0ebd958f6ba77a6d0bcc568e044b9b61ca4d77536a4214e7b4ade79dd733ea72d97993aaac27f2263b91b1500467350ff35ea40c2850d392b4ae75affff7f200100000004020000000001010000000000000000000000000000000000000000000000000000000000000000ffffffff0401670101ffffffff0230d0062a01000000232102f58ba54b2d51c4e2a6096f9d266261b45f1026a86ba88c29ed8070dfe3f5ec6bac0000000000000000266a24aa21a9edb824d92cb231c2366f0726aedf8bfc2705239a40ae6b10a106534e8b5395a09d01200000000000000000000000000000000000000000000000000000000000000000000000000200000000010196bac2a0f6212b8e5710f8c7214dd32c393d38d20b7703cf0b7b25276bb6ab8001000000171600144f8a6c8d4c6c309b1e2b725b7496859e172ea367feffffff02781ef5050000000017a9149f00bafb542049fe32d532b0ea7494ebb7ae41398750daa4350000000017a9147794e6dc43de332ca7a095e582478c331446686d8702483045022100bd85ed3954f1151c2fde32c4021a32c96d7defa4a57c14b1a056be9b361a8e49022054947bf6fdb535c46cbee62efc1262cc0389a6eaa19afbcfa98fb1fb30c3ef230121031b2371df07fb88dddf590b246dc74defc265fdbfe258e4b168250859b806f5ce660000000200000001bf83574fb606f25c59200c844443201faf923ef5284fd4401f3104a323c601490000000049483045022100d1c4b09b488f6375ee4540a531a13b5549e88e2459bd88c84867e293c54862740220222e8af70c8d8b1139c2a7b616d9132bde94244edca7eee3c7a783b12839dadc01feffffff0250196bee0000000017a91490e5e33cfedf18d5cf911d6f853770c62e1f5d028700ca9a3b0000000017a91422311ee58518edf3a2289012461dc66bc8739d2687660000000200000000010196bac2a0f6212b8e5710f8c7214dd32c393d38d20b7703cf0b7b25276bb6ab800000000017160014b81faaafa52f7723f539f8d595147b1a112b38ecfeffffff0208bd9a3b0000000017a9146b2e611708a94d9c674dd08c7c4c1fbb97bcdba987005ed0b20000000017a914933a20f07bab1d8f341f391819466a271f0cfd648702483045022100dfa8b0052c7825e6abcea05d10fc82550a8d6538681ffc8188d48ba789e4d9b40220697371cdf527a6ecd1887f87da3c87dca3419e4a1aa2683e5c4e035199084d100121021cc37c2ec090f30ea0b49508ae8a7d65d9759903932666da56671c1faa445d5d53000000"
"010000000000000000000000000000000000000000000000000000000000000000000000cc59e59ff97ac092b55e423aa5495151ed6fb80570a5bb78cd5bd1c3821c21b8010000000000000000000000000000000000000000000000000000000000000033193156ffff7f20010000000101000000010000000000000000000000000000000000000000000000000000000000000000ffffffff1f04ffff001d010417696e736572742074696d657374616d7020737472696e67ffffffff01000004bfc91b8e001976a914345991dbf57bfb014b87006acdfafbfc5fe8292f88ac00000000",
"000000205675686976674f50a0a1953d172e9ecf4a4a621dc9a4c3795decd49912cf3f6e9c2646796e96a45b91dd9199a449736bd9a78880936306be5f125a7ebcbc69e4010000000000000000000000000000000000000000000000000000000000000045298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03510101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002062b18e4b01940481bc4d3dc3d49851177ae06fbb651e9027f35acb15046499556f9c965b9b8c109db568d32d7d3a0dd7ee4d132490f42b51f4ba2652fec7bd1b010000000000000000000000000000000000000000000000000000000000000046298e5dffff7f20050000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03520101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020206689482dff24cf7b740fec087fded521465ab6e902d44b9edd81fcbed205189bef9d4d146ce1baddb2e321b6cd48c7ff10d1a9c24c6860f195710575a2168f010000000000000000000000000000000000000000000000000000000000000046298e5dffff7f20040000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03530101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020af6bafcae32d53ed80d5ebc76ff7f8f6ae33ee1e1d111f1581cc6999242035d4b06a8e0c34b018cf12ce80647162741e7151d6a64af60e8d93e4642510d320e8010000000000000000000000000000000000000000000000000000000000000047298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03540101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020917411a2c128c8d514268810af750a485ca175000082b6925beb4217168de79d2bec9aeb4b9ecbd4205a11951a4939402524dd8e9d8f982d4f12d01b300af7de010000000000000000000000000000000000000000000000000000000000000047298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03550101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020e8881b5ca1d771630f7a16590c05a269f3fde4d548b21c056105aaab827dd7bff4e300719036df10ebb927cbd6b5005003807a71427b8a8a433597a14743b3d2010000000000000000000000000000000000000000000000000000000000000047298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03560101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020cd187a1c21cc697ea2a8b12767900ade0c50537666e2d9f0612cb568b2809cd205477c5c00c155eadd3f24a662b9ce3d45e94714fa6680514e84ce81dbae641b010000000000000000000000000000000000000000000000000000000000000047298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03570101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002046925fe8d280c0ed84269e7d2f6fc75e0989f5b12a8329c9d3750b204af1e231cde3845b2f0b31b6adb93e0e3a0a4546010a9f70d9edd2d3945b44ddfd1f3286010000000000000000000000000000000000000000000000000000000000000048298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03580101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000200fa35702ea19e64830a09274eeaa84376257865960d42ef686c7ee036aef79ab9eadc578fb13d50e5f392884a1c2b5d5558bed09dbd573af82f3a3b2203918fe010000000000000000000000000000000000000000000000000000000000000048298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03590101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002078a772ace3aaa0ee543c1e039c0fb298f57cfaca055f53410fcabc7d593c6c87bbdeae34c9cb3617bc38e3ab0a43ffeb37c06b1d624d2e50d2f843c5f08fa507010000000000000000000000000000000000000000000000000000000000000048298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035a0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002021307a96ba4a365dfbe87c8c99ba8c43bd89cc4092310bcec9ea6eadca718a35731fa75a0f07302b163ad8f680b8d557dfd0acf18280b4ebbc41e5e8515923fb010000000000000000000000000000000000000000000000000000000000000048298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035b0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000208520fad5219fe882f6f0e5742d64624687a2fd5f1f4dced164594e8c51e886468757b56faabb2905c5c264ec6303e5df726e7448efb30e662c5eab6e4c19f5cd010000000000000000000000000000000000000000000000000000000000000048298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035c0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020b6cae7e19f4ac24957a8f932b1da05d9abceec8875dfccec7c2b4d8af9f8d510140d54e8dbd0ea528aad963ea5a4036f7b050d8cea603b706e36bd9f6e601e6f010000000000000000000000000000000000000000000000000000000000000048298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035d0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020f5e9391e41591c52889ad5e1bac5be8cb2c632592f13b039fa8f15dbe80083b9cf1a5a45904bda75bc081d78d370776f4a2d2bbe03dfe54e12cc26c6ab52b9cd010000000000000000000000000000000000000000000000000000000000000049298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035e0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020ca24db3b830fadbd52dce722453f40433b3bd373a7b146603c489b8ec8eaf76a709f5659d1242f71629dc7b46dd2328add4f12672c3e4a0a6c002f9d220ef58f010000000000000000000000000000000000000000000000000000000000000049298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff035f0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002037920b818e2deb397ae1b6816e95c846af08dbffb9917c026c9004dd5bbb750d037207bdebdb719af94d699ed8b7f8443e0e49ee2857fa4d01c782cd6411e18f010000000000000000000000000000000000000000000000000000000000000049298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff03600101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020418ba5059965888fc5b34bc4f454da675e14b87c4e5936004e2be27ab1c754b1bfde5825b014d9b49397ea4a74800a7bc070ba26aaebb0fd39cc4aea79678290010000000000000000000000000000000000000000000000000000000000000049298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401110101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020b87c7b459c40c17e1767f2823772eedacd36dcbe923dbdb50a93d5a8c714c35bf50ca0b9ecbd902f0e51d28841871c5cee712f91dd8791c620bd223bdf0e6a33010000000000000000000000000000000000000000000000000000000000000049298e5dffff7f20040000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401120101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020c41716369b5eb60c987548f45fc79a1e0d92b32731e8652366ad884fad383a809e07104556faa0d9f6e4d7611d5868f7e7d46b302de2b0e45b322a487bf6c70c010000000000000000000000000000000000000000000000000000000000000049298e5dffff7f20040000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401130101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020684b238cbf19d1f77054be44701353eb7d4d8ebf56432a5e0b37cfc4b986e45b17549e75a37864a74ed7c3617e2f620da9c5c736762eb73b66bedf7bf79ddb2301000000000000000000000000000000000000000000000000000000000000004a298e5dffff7f20040000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401140101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020b6ef5783f5c123e87b11cb186ceb1d4cc7c3290e8e12165f1bfad7577b486c184eead20e1914c8090d7bab52dc4a92ae58ff97a029b6c075f1ca4abc30d6df4f01000000000000000000000000000000000000000000000000000000000000004a298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401150101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002096a670e039d621b147c4c68b8ece1d442502aa1b3389896e0a2c9ee24092bb2e155c431d467db173e369a59198b2bc50a16185f914306c3e032f42b24454440001000000000000000000000000000000000000000000000000000000000000004a298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401160101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020fde40a0ddb45461a36120b2300fb19ad701b93eaa2d99f8d7da85101fd80c5efc6455c8ecceb8d07485a799ea260e635528d863e36573023f9c1e2a3e8de2b7601000000000000000000000000000000000000000000000000000000000000004a298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401170101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000207d4488c7932c51ab2f922f010ceb3df5b4dec027862e57b8c244d42f5534c6c38e2190ef4d9186ca5ab6dac103432302c481be9769b9cf9fa096868e77a3764101000000000000000000000000000000000000000000000000000000000000004a298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401180101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020896b06cf7936eba3ca7d79470bcc2c290a1b15a3de06d1cd73b10a106b27f8fb49b54d8e2162871dc1c295f5163ad3df67d4a7a5cd43c800094ef1cb1e8a1b9d01000000000000000000000000000000000000000000000000000000000000004a298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401190101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020be9003ce95f64c98bf870555b9263304c546079dd3614a599cf07fb4776af3aa2e8cd162f0ae28e7a4fb10f173e44f80f1fafe36e35dc5a4a9b33bb7629e04b101000000000000000000000000000000000000000000000000000000000000004b298e5dffff7f20050000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011a0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000205d826c945361bd5283024395ba3f07bc3ec107bc79407d8ae6891e08848dad96e30e56c9ab0ad1e6107d3f95b88004128a732f2589e2f2ccaef41c886b07abf001000000000000000000000000000000000000000000000000000000000000004b298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011b0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020fb80b3a74bf9f8446419e32d172725c2edfd755283cad14f16c9fd8e0db8f63a8165ffe9fb63399644d6a3465b84972eba11a560ac2bb327f350b8c859beb63901000000000000000000000000000000000000000000000000000000000000004b298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011c0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002026aafd727bc33bebb8c9d4c5c231edc6ad7f1b120416f6eec899345137155287da9b8b939a2e0dae1fdc57e8f051b847a898bf372632e47aa906852a445a24bc01000000000000000000000000000000000000000000000000000000000000004b298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011d0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020eff266f8410f99391deffa0f2fbffcc2ef8224ba82d2f990711a28538c537e0094f83b6c8fada8283220abceb95e2180473f068ff096264a8f2bad31863152eb01000000000000000000000000000000000000000000000000000000000000004b298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011e0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020ba106ca41ee82bbb2bc6d0fe05d495dcc62a0e23c9519edd4b2d7ec12a08d8510db06e473aec2b882def52f084b4b0d9f6265d47780c15abd54827df6c62fea601000000000000000000000000000000000000000000000000000000000000004b298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04011f0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020043eb2d4b22b694311bb7489d61bf58b66bc278ea260a48f834c2d4032e32bb311976be9aaf30c1d8d6a9723d210adce2b625c0a29947cd14953410e00642f7a01000000000000000000000000000000000000000000000000000000000000004c298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401200101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000207a1bce01ae3d23f10eb96c919d69bece9764584690aa62ac5e529f5b11e39c8a77679b50d559cbaac0040176e82355231529ac2f48de1d5983bc9366d4a1fb3c01000000000000000000000000000000000000000000000000000000000000004c298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401210101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000209afb1c2dbdb163ae0a769e6b0f45ce0a6120ae93e8b0cd9c3c324e680c368d0ceabbb0033eedd8bfe159ba57d523ece2b9d4e86c1754b09fca80e78890744a3201000000000000000000000000000000000000000000000000000000000000004c298e5dffff7f20040000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401220101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020139aab4d7175fcabb17a76c6660a2484d596a1a87b8794863aaa403015e794e9bda24098c56906da7fa1d0f104f3731e5d9ac14886148c7dcf728a562051dd0f01000000000000000000000000000000000000000000000000000000000000004c298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401230101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020433a8cf135270470d6bbd5c66751d8b343a26bf2e215b77b4840c07f8c2edb80f2e3a01d0db6fa8565e780e15d7650ca3913e9dc0a362bce208b69eee8778c6e01000000000000000000000000000000000000000000000000000000000000004c298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401240101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002058df283f1cab9904c9d31ea0c69ddcf0bbaf9059ef94303fa03e7aff67f90b656f4c2c390587d278e29453a773dda990246265d181a64b4f8de5f87e0b2d72d601000000000000000000000000000000000000000000000000000000000000004c298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401250101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020474409f36e71c4ae8aa34e5cf5e30edb96444afffccdc0adaeda4a5b33ac0edcc757ff2a006fa36785373524813efc635e42a8a6ffd7b30d87d7d45aab6473f101000000000000000000000000000000000000000000000000000000000000004d298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401260101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020b2a45ac6975c714b53f173477bd4d7abed2e131f6d1d0f36228a59d278a0803a362739c353a03108aabda333039e417365c29271b4fed1577ca88300a0f903e801000000000000000000000000000000000000000000000000000000000000004d298e5dffff7f20050000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401270101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020a2eb5532ba64f5b4980217cc53abc0122133b67da0cd15e27620296175b6773110d335e63a14d0c7f87360044640b2430f36d56dfdb51faa03a78f7b0682bebe01000000000000000000000000000000000000000000000000000000000000004d298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401280101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020703c37af817a6d6a5d4ea28eb8273dd039d3e5aad463d2079f7311e9f7ec0270d733d311164ef0c13d63fdc6ae1859a1212c77f6b99bc232502ab0f6e9c2463601000000000000000000000000000000000000000000000000000000000000004d298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401290101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000207016a47fdb3ad2dfa1f5dfb4d325d7397b48d773aa84e89e0e4fd1c86d1963867b121f48a0be5dff0406e4e5e3b84c9b9502f43610114a6937c12e4eba142e3401000000000000000000000000000000000000000000000000000000000000004d298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012a0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020f17810d1cc695dfad2789149c9b21c90ed4f2a2663b33a9c1154763bf599601dad47e87a7bbaf33cc004e13f7a0722acc62755a69a666c24da7ba1f838e11a9701000000000000000000000000000000000000000000000000000000000000004d298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012b0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002047e742da0f3d882548e333c5de9ba5c1e89c366b53de17e95f2126089b473f8d9927f26f88eec45759dc6d1f5a310b303a3dd7d113e1c7732a472a3163bb2d3601000000000000000000000000000000000000000000000000000000000000004e298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012c0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020b74842271729497e94c33429c6e21ebfc46c82f587fbfaa91bf30a7fa1df77197c65d2b6735b85a3718befcf7a789df26bfaf929b32eec42594c94862fec6d7f01000000000000000000000000000000000000000000000000000000000000004e298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012d0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020a3291c68b92c19bf503e3a48f89b3d85923d8d23791b3b77b541224be114da6f052f7b4a4a72a178fc26adf081cb28494d2e2386f42cb8fd3db9ff2da5f8a22e01000000000000000000000000000000000000000000000000000000000000004e298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012e0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020b84c9aedee6173c6926b37c5c451fc0a9ae1bcf23508ac4de8b790befc65216665f48aa0f54655f985e9f1e3a5a58683d40b523ef430aae8593734171a204e9d01000000000000000000000000000000000000000000000000000000000000004e298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04012f0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020bd7b9820463851223f9543192c338fd3701c7998c823086951df721335665eb2d2d152c34514ff98c551509347d4415e8f7aff1f3639be677df20d03557ee9f101000000000000000000000000000000000000000000000000000000000000004e298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401300101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020a4f6ad65c748ab035e3d520f6c33ba047d28bdfdb6e5a0a4015a5a3a9e0f4ba0f79d7ae2f66ff289ff6b8f4ce435152f382d6d54285528b422a3d0c94ea9483701000000000000000000000000000000000000000000000000000000000000004e298e5dffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401310101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020fa467509059c29bc043e527bd38ca2620dc441145deed28a9d7865a7417ac5b8428f2c186fa501cc53f1e91972e0fb9ba8bc6ae7daebb54784cdeb21c5076c0d01000000000000000000000000000000000000000000000000000000000000004f298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401320101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000205dc60a8d80efe426d3dfcd8a5741499f9f7a0bebf5f9da39e6887d13a84690429f2c8e7a35b50bc86245a4250b3e3ce74d1ca128bb11ddf7da9fde9ca0f0c40101000000000000000000000000000000000000000000000000000000000000004f298e5dffff7f20050000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401330101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020ea09bbbdbb30103822f451568802e25341ead64a0538c529f8e3159d3f3162f57b7460f7b6ab41416b590f664473e0887b148f4482ab1842cdbcbfce807bd69201000000000000000000000000000000000000000000000000000000000000004f298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401340101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020d8dd90f93424b2fbbd10ef671d14edf5ea4727ab4e574126b9f7dab2a3ba17ac7a5412415fa65b28385e15f30c50202101d26aec4360f967e8449b15fc230c0e01000000000000000000000000000000000000000000000000000000000000004f298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401350101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000202e6425938fb77136939680c552a6be236e15ac4ed625998f63471227239c29d02dedb613647b0ad43c476af1b44286d66c2d09b94bcfb409bf9b078cddbd82ca01000000000000000000000000000000000000000000000000000000000000004f298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401360101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020267e25450655771ab9a1a3e04a65c184c728bd3cd9d325a347e2f8e339df2502951d2d58675bdd42d0485baecef3fd996220059a6c30e5272e92c35c0588506501000000000000000000000000000000000000000000000000000000000000004f298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401370101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020c3a96bd46f98c92a3311b8053980954f8d66c12581d3dc1eaff58d2cc2524377bafafac9739f3ad59b142347361e92c56a6a2433b96395b1f32ad070c940341a010000000000000000000000000000000000000000000000000000000000000050298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401380101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000206d0512cd762e3ac801a71b2a34440d54e879f20ec6ce46c1affaf500a6d473a2fc5485980b8c8ea92e2e021555c4c7d51a1bc1876ba159d268fd9b82bfa565da010000000000000000000000000000000000000000000000000000000000000050298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401390101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020b1fcc4dfb3c7234a37b412c53d7875f3904a8fabbc53e6371e5e4893bcf2637ae58c32587cef1ca2302eade194d66bc81f727204cf76e1d884d63f8d3939b358010000000000000000000000000000000000000000000000000000000000000050298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013a0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020404faf641adf310aa8fc82b9cff35f33d4259583add438e565df88a6fa67855f0ceb812d629a05ae41aa3dd2cc8393f3043f5d038c5c39e2764d804ac3e8d8ae010000000000000000000000000000000000000000000000000000000000000050298e5dffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013b0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000205e026a6a245be5cca56cbdff8bfb8880455aef0ace6bd67ec1b0b0756824325668b82f456bae643458146e4242df88046b0d39f5b80f4d3bce9619cd0849d43e010000000000000000000000000000000000000000000000000000000000000050298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013c0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020229ebb1ae197e0626ead2b50480fa897c8aa13367999360d901a616a3d378aaeacfa4886f415f04cc0a86adcea8d5ceca8cbca31049f2986cca7e921732cb5c4010000000000000000000000000000000000000000000000000000000000000050298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013d0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000201ff4b0bc9ac5207724a625f7116579f93c59e976ed187b9c9188336c75887b3b14931ab5dfef97c4a9bb83cd6994ee705bad1b2c2be7dc5ec8d1d70415867092010000000000000000000000000000000000000000000000000000000000000051298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013e0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020f93263a21cd8b06dba37ae68182bebe2dc4884bd87f6bb90421662ce3517b7851bd25e4486ddb133ee285c31fd67dd0ab1fad43696ef3b9a7f258372afddd92a010000000000000000000000000000000000000000000000000000000000000051298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04013f0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000206e901e57352c9c935270bd33cf42b3aeca463290c264744b7593434a348b94286e21b29fddfee89035236430f0519fdde42edbba2cff3a69395e71ac0a8cc078010000000000000000000000000000000000000000000000000000000000000051298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401400101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020547e4b25278bef0b46c4ff096179c05a9ad25b1e8d735bab9109e5f9c625228f22aaf37d0db4e12ad40d286c0c210787d7b4e55fb1cca0e0756045183ddb7304010000000000000000000000000000000000000000000000000000000000000051298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401410101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000207d8a623bcfd2ca3da4a10d9842f18489d2e1b1bba5803d236f881aba3b152c7d1f41e6374dae64966b3791bede633c69a4a7c1a362ccfc232a47041b684655c7010000000000000000000000000000000000000000000000000000000000000051298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401420101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020e6f81efb92a28e66b65eab2dbccaf70570eb53d6dc5057e640e7a3cd14983b79f94c3177a4cd10e1b04baadf9ef3e97fee16d5787a5c6a4b6a000aeccdef7322010000000000000000000000000000000000000000000000000000000000000051298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401430101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020b318408ed77cfdd0e5c4106b3d963df17474289d7a94989fd51b3a62028f905db2c4447dbaa57602ce22c585a0203819ab96c932ac91d9908e288c501366ccd9010000000000000000000000000000000000000000000000000000000000000052298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401440101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002042fd200cbc0f6d5e21e753df0cf9b4bf411173188c5f629515dd9e438621873266e52da4579cf92d25016da99bd70854cfeefc787f89d291b647886a0f98cada010000000000000000000000000000000000000000000000000000000000000052298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401450101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002049a79824a608770beaefd83b6bf490c5205ddeb33bb51b63472945a62c2fa3d30208ffe437833ddb3df6ab62506b5c3f2d9b05f35bf029b64681edb499b79d9b010000000000000000000000000000000000000000000000000000000000000052298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401460101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000203a6ebcc5e5031f3a90cb145feb8614c922b01bca955e9878ecea00f6e0635f4a6e144c018c0a95e5d83473865107f0453b4d0cb2d655687bba38fa3c8664fe0c010000000000000000000000000000000000000000000000000000000000000052298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401470101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020d6990869ce59bec3a60675ac9e9997f147090869b1dd07be9e1cb2f94f28fe9c7d5e5f0cb033a158cdfa50ec6d5118d42ffb4d52284348bf0f68f0990db0627c010000000000000000000000000000000000000000000000000000000000000052298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401480101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000206515ed2b781786fd8bbd982a7e170776b0ea4320ced88972bd90649f7542231431b27ee4ea6d05f07887027356a76c5cce03375eb525fee6bde3b69656575882010000000000000000000000000000000000000000000000000000000000000052298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401490101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020f87d4477a677bd04749b9c52f7a4544ca0adc7150fd2f691e0d0930a09a7d1b043a9d9deb3739829c6fa8e8abc9c30573224e43f6c36ee103012f4fffbba2b9b010000000000000000000000000000000000000000000000000000000000000053298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014a0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002027f74ac6b315fa990ff6fe9fd07966ee64c4d051e7ce92cad3dc84f1cbf2452bd1d0326fe6c571de5fb37707d8bbeb55b932f0b4ad89c506e414c020d5088e5f010000000000000000000000000000000000000000000000000000000000000053298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014b0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000206c98fd30a20783935ace23743a8cb9a02e6eed8b508cbe16305cc685dbef0e2d12e5d1eca285a4ca2cc974ede1ca60fd35e5f04303017143fcc3ba710efadaab010000000000000000000000000000000000000000000000000000000000000053298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014c0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002036d8823d48e38575bcd2b13e2fa89be8f3f581151e06be6545fbf67336a300ac43e661b5889f90f1511a72c2d6ff1ae990bf7fecc44d01cb08621c238bd8e887010000000000000000000000000000000000000000000000000000000000000053298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014d0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020aabbc62ff10ebc5466db39bc4ba5acc763e854dd8a766d018d8341b5371cc47fe96433fea9696b53603cbacfad8d3808d70c681925606ef11be24c81388f556c010000000000000000000000000000000000000000000000000000000000000053298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014e0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002079660b6b38721b49ef7e05a9ed78d3c11ce1af6a8dcb08a862f61e9513cc780bda411454214807f29a201bb710436eb95f153aafffaac1b9d29254ec0f39d681010000000000000000000000000000000000000000000000000000000000000053298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04014f0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020bd361170eecaa766944c2c22b54a2048ebb1ab4fc52837a66bad850479b9fd61e13cb2bd7da4f99412c40cb43227cdc0df404d977be0f0ae24c1804f661135a1010000000000000000000000000000000000000000000000000000000000000054298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401500101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000202bae167d754ca4b3ba9fb4bae2d452561a021bf64988bfc9dc11f05824bbab24c84a68a6d88174fdeb6863596ea35f97735b9fb80037a90fc512529731429b6b010000000000000000000000000000000000000000000000000000000000000054298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401510101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020ab2ecf71d724d650baf77cb63e108cd933e08ab1c3533ed5057730b52382d9e30ba6864fb662e379c2a2d8d64ba4c17ec8f183a2a0102c969893a813cd1c6e56010000000000000000000000000000000000000000000000000000000000000054298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401520101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020940d5c843cec6cb987d18506f44343e4176f54f0028720d7036d323fc8bd0f5f950bcc074e1ecd1b543e39872af433fc5575004fa96c8864ef5be3a7a8feecd1010000000000000000000000000000000000000000000000000000000000000054298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401530101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000200eff6985d00d2dae0c9ed5d8d9ee1d6e1742f7bdca76bdbcb68f8540203fe830704265dcfb6c95cb07fc701f39123a804fbdf59cc7302dc889a172070f6dcf0b010000000000000000000000000000000000000000000000000000000000000054298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401540101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020a2f82b9acba4b57dd50f4e63489138ee1af0d3fd956aea5f64dd6eaf5bed11aae43256d7f8457700b24f4057eca70f498a4669424a453c8b25ca53d5936caa74010000000000000000000000000000000000000000000000000000000000000054298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401550101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002076594d858f8491fdb94daa2c9f199690d0e4b1e10f49570cc63de870efdc7cdfe4fea89c7cacde1ce6a385f186e6ae2660d6f96ad1c5f65a55374e78f05c2088010000000000000000000000000000000000000000000000000000000000000055298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401560101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002073c9c91546655921ffecd56bf6c88a431569553df0514cd160ef6e648c3038208d170a1d6049197890ae215dee26eb1c4f56d3e72a9ff76d05028c522dad5df5010000000000000000000000000000000000000000000000000000000000000055298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401570101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000206f0a68329f9ec8b2212d92da2efd233cc287b92a6ad558ebd7c877d378382690e4871ece6f3dbb9510c7ec2f06264ece3d0d786924782cc87c880104797d308d010000000000000000000000000000000000000000000000000000000000000055298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401580101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020f95fc51dfaf099418f31316b0e2511a1381f292dc77d5cbcb323bc623736e47bab12001f519e5f29675f9723610c2adb06fc09a3433164183618af3d5f2d5d13010000000000000000000000000000000000000000000000000000000000000055298e5dffff7f20020000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401590101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020a2b24bcd260e921e21eaaa24f9ee49646a19ec90a2776e4d5569d1e4b96ae550ab283476b7512a414a45d0afd1067542aa21b35136858cc228f093b79a86a168010000000000000000000000000000000000000000000000000000000000000055298e5dffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015a0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020f98eb5e8ea9b3a7e0e7b97d22dfc4940e81b3efa7a52b1ae984ae62d258eb6094f21c0bc0a6b5d04a200cd96e7afc8903f693c73841d7a7f46444061b87cf4dc010000000000000000000000000000000000000000000000000000000000000055298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015b0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020c9b5bd09d4cdf36fd437dcfc6d467496aaf8a2a9b48a9109a6573d93ba1fe1dbd81b4c34fdc739646dc6d7652315e672df987039c108f21c6233a29ca6b0269d010000000000000000000000000000000000000000000000000000000000000056298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015c0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000200643717cbcb0cce475b5f0fb63e56f1447799264726631396c30224bc7f798790c341d332c183b762fca8c54f6fe148772e0f9181dfea77974a3afb71a1052b0010000000000000000000000000000000000000000000000000000000000000056298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015d0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020ac06f84bfaf2ceb8b19ead70177dbd6201387983d72a977da1f57ffd921a6783b2d5511af0de5e43edb43e0d766e1e70d0de2710f3eb7f89a10ad0f512648c46010000000000000000000000000000000000000000000000000000000000000056298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015e0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002023f31418b84cfa73db871d97b08497af8cfc05658cc65baeb88140943a88985c0d7727f13069e326603003358d3618953e17ff6e4ffc8be096474d3512bad092010000000000000000000000000000000000000000000000000000000000000056298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff04015f0101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020a7c86fccf39d979b930e8e94061dc2ae1cb4af16c58557dc28ba136c2714196797e7c32249c1eaf9138dc9279cebf0189b61b6ba6e694af744f93949e0c531b0010000000000000000000000000000000000000000000000000000000000000056298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401600101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002015ab67be546784d304150d6912c3ad77b5135f06db0a82517f0e7bc7ee3c14ff9b540ec1386e01df66f097f37a57f7f777fe9a7605394d3c60b43e7a0f21f775010000000000000000000000000000000000000000000000000000000000000056298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401610101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020e5656df91c69f8a74de2002fe237014cb7ffba5c198f2740fab78b0e532e4b6cb1eee816671fd7ff909c68b67c86172a2840733837943c2b99f7b0232112308b010000000000000000000000000000000000000000000000000000000000000057298e5dffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401620101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"00000020c2f75754521bfd09fdce186ccee3de0724558ab0dd7e6d66aeb2c24ecd0b72c88befbb4db8b957c2de6545459d810bd8b316b48d13384cbc65417eb0053d9afd010000000000000000000000000000000000000000000000000000000000000057298e5dffff7f20010000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401630101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002068569744e5ad15456dde211456d1d6d88e8575d318cca972be4c4214802d0e8204d450ccd28e34284b290f457a24e62a1362f9a2f804d2d6b3be8b39b2512112010000000000000000000000000000000000000000000000000000000000000057298e5dffff7f20030000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401640101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"000000201e5bfcdf805e44ecf759571ab08560ad66166044be47696807937623b30faba39d638f685167f53a0b4683fe059370e1dcad605eabd79c4fc602980e5ff97db0010000000000000000000000000000000000000000000000000000000000000057298e5dffff7f20000000000102000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401650101ffffffff0200e1f5050000000023210375c6e5384af4df0ef340e9a7de57dee04253e470ab3752aa7ded36dcebe24183ac0000000000000000266a24aa21a9ede2f61c3f71d1defd3fa999dfa36953755c690689799962b48bebd836974e8cf900000000",
"0000002066bd635be5b553539cd953474c4907b44c7846a3bec06cea96c7258914d5509a430025a9bd953d89a962a10f81ad1a2b1559a5d94dd0bac31fc15967bd15d974010000000000000000000000000000000000000000000000000000000000000057298e5dffff7f20000000000202000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401660101ffffffff02eceff505000000002321032c6891656ef6cfc5b6c7b311133ea2bff07b890a029ced48ee51a2c90801b528ac0000000000000000266a24aa21a9edd2bfb4f47890a95750585964ee6f4f69555a306a4819f89dd72c0ff014839bb80000000002000000019c2646796e96a45b91dd9199a449736bd9a78880936306be5f125a7ebcbc69e40000000048473044022074058acb16acdc220b34b695668dfe5d2ed4819e2a11ab9c9c56a1c9bd7636d302205364ee6d261b725040255aaea5e11b618644642c8f9f718772fe3a7eaaf3787101feffffff02141e3101000000001976a9148b9217f042f56f05f71e20f5420f9fc90d32f87f88ac00b4c404000000001976a9145bb987c92e0c23bf14659cee81a90cf0c80cb03c88ac65000000",
"00000020237f85d3c2263dd3d424076549ebc19656b3c724f03bfd9b527184b44e77a7ce15f37e2055a2c2feecbe763101c6f8a5850c8f1ae95eb2c100fc75c58e283123010000000000000000000000000000000000000000000000000000000000000057298e5dffff7f20010000000402000000010000000000000000000000000000000000000000000000000000000000000000ffffffff0401670101ffffffff022c09f705000000002321036c9111e5a6523faa990b7452c2c88c3c5e22ef6d9ad5288637168a3b0ac9bc54ac0000000000000000266a24aa21a9ed3befd64d33a3d249c6882f1a4e08a948b03f848270c8d717889a0a914bbe989b00000000020000000129b86f6b974b8c38a47ffd1a97b73e16864a344fe72c7b20f26f3dfaeab8e23f000000006a4730440220450b9e79c405c5a50df883cef44073b5fe0f76a268e8c2617ebe84b67c7d61770220163f696ceb92ca0d798dd0a11ea1aa49f0403658097b56eb20da82c0b0cc99eb0121034107f19591db3b08fbef4c466b8fe5831c2cafeefeb55325ea191ae1c645b154feffffff02d47c1d00000000001976a9145f881a61d39c56d83ad6adc45e0dd5d87c48ea1488ac94991201000000001976a914be83ea53e1caef62a9da4ac46bee932fb6e64d6588ac6600000002000000016f9c965b9b8c109db568d32d7d3a0dd7ee4d132490f42b51f4ba2652fec7bd1b00000000484730440220727dd1aaf6727c76b3754305147de818ddd9b6cb7c7cb6669c5a235ea35b658f02202e8b340309ab3b2e937ff54bc5405670921a08498322b6acb03b14d570b1c96b01feffffff02002d3101000000001976a914347e511d57756463f6e298d1a545d19f657e3c5b88ac14a5c404000000001976a9146e6bd61c46f7feb09855769d1ed0206818deb88388ac40000000020000000129b86f6b974b8c38a47ffd1a97b73e16864a344fe72c7b20f26f3dfaeab8e23f010000006a473044022079dc6bfd6537301ca23178845bf789b3c34ab4f0b838f271f1526df41bc24e39022038b9b78a1554af83f4bc0616945b6af66e3e938c237553a76fd96f9074375540012102ffd149a0a5c08f0fb54fa934bb93786cda9440d3cdc09614b0f09cca5c435970feffffff0200879303000000001976a9148e6032ef5414a7d0a26b3d6be863827b5a3c82c988ac6c1b3101000000001976a914f843cea430f0ef2bd291f7251a6201cb2422809b88ac66000000"
],
"mocktime": 1525107225,
"mocktime": 1569597765,
"stats": [
{
"avgfee": 0,
"avgfeerate": 0,
"avgtxsize": 0,
"blockhash": "1d7fe80f19d28b8e712af0399ac84006db753441f3033111b3a8d610afab364f",
"blockhash": "9a50d5148925c796ea6cc0bea346784cb407494c4753d99c5353b5e55b63bd66",
"feerate_percentiles": [
0,
0,
@ -125,17 +125,17 @@
"maxfeerate": 0,
"maxtxsize": 0,
"medianfee": 0,
"mediantime": 1525107242,
"mediantime": 1569597782,
"mediantxsize": 0,
"minfee": 0,
"minfeerate": 0,
"mintxsize": 0,
"outs": 2,
"subsidy": 5000000000,
"subsidy": 100000000,
"swtotal_size": 0,
"swtotal_weight": 0,
"swtxs": 0,
"time": 1525107243,
"time": 1569597783,
"total_out": 0,
"total_size": 0,
"total_weight": 0,
@ -145,11 +145,10 @@
"utxo_size_inc": 173
},
{
"avgfee": 3760,
"avgfee": 3820,
"avgfeerate": 20,
"avgtxsize": 187,
"blockhash": "4e21a43675d7a41cb6b944e068c5bcd0a677baf658d9ebe021ae2d2f99397ccc",
"height": 102,
"avgtxsize": 191,
"blockhash": "cea7774eb48471529bfd3bf024c7b35696c1eb49650724d4d33d26c2d3857f23",
"feerate_percentiles": [
20,
20,
@ -157,35 +156,36 @@
20,
20
],
"height": 102,
"ins": 1,
"maxfee": 3760,
"maxfee": 3820,
"maxfeerate": 20,
"maxtxsize": 187,
"medianfee": 3760,
"mediantime": 1525107242,
"mediantxsize": 187,
"minfee": 3760,
"maxtxsize": 191,
"medianfee": 3820,
"mediantime": 1569597782,
"mediantxsize": 191,
"minfee": 3820,
"minfeerate": 20,
"mintxsize": 187,
"mintxsize": 191,
"outs": 4,
"subsidy": 5000000000,
"subsidy": 100000000,
"swtotal_size": 0,
"swtotal_weight": 0,
"swtxs": 0,
"time": 1525107243,
"total_out": 4999996240,
"total_size": 187,
"total_weight": 748,
"totalfee": 3760,
"time": 1569597783,
"total_out": 99996180,
"total_size": 191,
"total_weight": 764,
"totalfee": 3820,
"txs": 2,
"utxo_increase": 3,
"utxo_size_inc": 234
"utxo_size_inc": 238
},
{
"avgfee": 18960,
"avgfeerate": 109,
"avgtxsize": 228,
"blockhash": "22d9b8b9c2a37c81515f3fc84f7241f6c07dbcea85ef16b00bcc33ae400a030f",
"avgfee": 25273,
"avgfeerate": 118,
"avgtxsize": 213,
"blockhash": "981d9ad0c7dcd22dce86deb6d118fdde6a3e62092ecfea93f9856f2eb23a37f5",
"feerate_percentiles": [
20,
20,
@ -195,28 +195,28 @@
],
"height": 103,
"ins": 3,
"maxfee": 49800,
"maxfee": 67500,
"maxfeerate": 300,
"maxtxsize": 248,
"medianfee": 3760,
"mediantime": 1525107243,
"mediantxsize": 248,
"minfee": 3320,
"maxtxsize": 225,
"medianfee": 4500,
"mediantime": 1569597783,
"mediantxsize": 225,
"minfee": 3820,
"minfeerate": 20,
"mintxsize": 188,
"mintxsize": 191,
"outs": 8,
"subsidy": 5000000000,
"swtotal_size": 496,
"swtotal_weight": 1324,
"swtxs": 2,
"time": 1525107243,
"total_out": 9999939360,
"total_size": 684,
"total_weight": 2076,
"totalfee": 56880,
"subsidy": 100000000,
"swtotal_size": 0,
"swtotal_weight": 0,
"swtxs": 0,
"time": 1569597783,
"total_out": 199920360,
"total_size": 641,
"total_weight": 2564,
"totalfee": 75820,
"txs": 4,
"utxo_increase": 5,
"utxo_size_inc": 380
"utxo_size_inc": 388
}
]
}

View file

@ -42,10 +42,10 @@
],
"outputs" : [
{
"bcrt1qmpwzkuwsqc9snjvgdt4czhjsnywa5yjdqpxskv":1.49990000
"rlbc1qmpwzkuwsqc9snjvgdt4czhjsnywa5yjdqpxskv": 0.029998
},
{
"bcrt1qqzh2ngh97ru8dfvgma25d6r595wcwqy0cee4cc": 1
"rlbc1qqzh2ngh97ru8dfvgma25d6r595wcwqy0cee4cc": 0.02
}
],
"result" : "cHNidP8BAJoCAAAAAljoeiG1ba8MI76OcHBFbDNvfLqlyHV5JPVFiHuyq911AAAAAAD/////g40EJ9DsZQpoqka7CwmK6kQiwHGyyng1Kgd5WdB86h0BAAAAAP////8CcKrwCAAAAAAWABTYXCtx0AYLCcmIauuBXlCZHdoSTQDh9QUAAAAAFgAUAK6pouXw+HaliN9VRuh0LR2HAI8AAAAAAAAAAAA="
@ -136,4 +136,4 @@
"result" : "0200000000010258e87a21b56daf0c23be8e7070456c336f7cbaa5c8757924f545887bb2abdd7500000000da00473044022074018ad4180097b873323c0015720b3684cc8123891048e7dbcd9b55ad679c99022073d369b740e3eb53dcefa33823c8070514ca55a7dd9544f157c167913261118c01483045022100f61038b308dc1da865a34852746f015772934208c6d24454393cd99bdf2217770220056e675a675a6d0a02b85b14e5e29074d8a25a9b5760bea2816f661910a006ea01475221029583bf39ae0a609747ad199addd634fa6108559d6c5cd39b4c2183f1ab96e07f2102dab61ff49a14db6a7d02b0cd1fbb78fc4b18312b5b4e54dae4dba2fbfef536d752aeffffffff838d0427d0ec650a68aa46bb0b098aea4422c071b2ca78352a077959d07cea1d01000000232200208c2353173743b595dfb4a07b72ba8e42e3797da74e87fe7d9d7497e3b2028903ffffffff0270aaf00800000000160014d85c2b71d0060b09c9886aeb815e50991dda124d00e1f5050000000016001400aea9a2e5f0f876a588df5546e8742d1d87008f000400473044022062eb7a556107a7c73f45ac4ab5a1dddf6f7075fb1275969a7f383efff784bcb202200c05dbb7470dbf2f08557dd356c7325c1ed30913e996cd3840945db12228da5f01473044022065f45ba5998b59a27ffe1a7bed016af1f1f90d54b3aa8f7450aa5f56a25103bd02207f724703ad1edb96680b284b56d4ffcb88f7fb759eabbe08aa30f29b851383d20147522103089dc10c7ac6db54f91329af617333db388cead0c231f723379d1b99030b02dc21023add904f3d6dcf59ddb906b0dee23529b7ffb9ed50e5e86151926860221f0e7352ae00000000"
}
]
}
}

14
test/functional/feature_block.py Executable file → Normal file
View file

@ -309,7 +309,7 @@ class FullBlockTest(BitcoinTestFramework):
b26 = self.update_block(26, [])
self.sync_blocks([b26], success=False, reject_code=16, reject_reason=b'bad-cb-length', reconnect=True)
# Extend the b26 chain to make sure bitcoind isn't accepting b26
# Extend the b26 chain to make sure lbrycrdd isn't accepting b26
b27 = self.next_block(27, spend=out[7])
self.sync_blocks([b27], False)
@ -321,7 +321,7 @@ class FullBlockTest(BitcoinTestFramework):
b28 = self.update_block(28, [])
self.sync_blocks([b28], success=False, reject_code=16, reject_reason=b'bad-cb-length', reconnect=True)
# Extend the b28 chain to make sure bitcoind isn't accepting b28
# Extend the b28 chain to make sure lbrycrdd isn't accepting b28
b29 = self.next_block(29, spend=out[7])
self.sync_blocks([b29], False)
@ -829,7 +829,7 @@ class FullBlockTest(BitcoinTestFramework):
assert_equal(len(b64a.serialize()), MAX_BLOCK_BASE_SIZE + 8)
self.sync_blocks([b64a], success=False, reject_code=1, reject_reason=b'error parsing message')
# bitcoind doesn't disconnect us for sending a bloated block, but if we subsequently
# lbrycrdd doesn't disconnect us for sending a bloated block, but if we subsequently
# resend the header message, it won't send us the getdata message again. Just
# disconnect and reconnect and then call sync_blocks.
# TODO: improve this test to be less dependent on P2P DOS behaviour.
@ -1061,18 +1061,18 @@ class FullBlockTest(BitcoinTestFramework):
self.log.info("Test transaction resurrection during a re-org")
self.move_tip(76)
b77 = self.next_block(77)
tx77 = self.create_and_sign_transaction(out[24], 10 * COIN)
tx77 = self.create_and_sign_transaction(out[24], 1 * COIN)
b77 = self.update_block(77, [tx77])
self.sync_blocks([b77], True)
self.save_spendable_output()
b78 = self.next_block(78)
tx78 = self.create_tx(tx77, 0, 9 * COIN)
tx78 = self.create_tx(tx77, 0, int(0.9 * COIN))
b78 = self.update_block(78, [tx78])
self.sync_blocks([b78], True)
b79 = self.next_block(79)
tx79 = self.create_tx(tx78, 0, 8 * COIN)
tx79 = self.create_tx(tx78, 0, int(0.8 * COIN))
b79 = self.update_block(79, [tx79])
self.sync_blocks([b79], True)
@ -1165,6 +1165,8 @@ class FullBlockTest(BitcoinTestFramework):
b89a = self.update_block("89a", [tx])
self.sync_blocks([b89a], success=False, reject_code=16, reject_reason=b'bad-txns-inputs-missingorspent', reconnect=True)
# FIXME it's allocate too many resources for a test
return
self.log.info("Test a re-org of one week's worth of blocks (1088 blocks)")
self.move_tip(88)

View file

@ -105,7 +105,7 @@ class BIP65Test(BitcoinTestFramework):
block.nVersion = 4
spendtx = create_transaction(self.nodes[0], self.coinbase_txids[1],
self.nodeaddress, amount=1.0)
self.nodeaddress, amount=0.1)
cltv_invalidate(spendtx)
spendtx.rehash()

View file

@ -21,7 +21,7 @@ class ConfArgsTest(BitcoinTestFramework):
# Assume node is stopped
inc_conf_file_path = os.path.join(self.nodes[0].datadir, 'include.conf')
with open(os.path.join(self.nodes[0].datadir, 'bitcoin.conf'), 'a', encoding='utf-8') as conf:
with open(os.path.join(self.nodes[0].datadir, 'lbrycrd.conf'), 'a', encoding='utf-8') as conf:
conf.write('includeconf={}\n'.format(inc_conf_file_path))
with open(inc_conf_file_path, 'w', encoding='utf-8') as conf:
@ -52,7 +52,7 @@ class ConfArgsTest(BitcoinTestFramework):
self.nodes[0].assert_start_raises_init_error(['-datadir=' + new_data_dir], 'Error: Specified data directory "' + new_data_dir + '" does not exist.')
# Check that using non-existent datadir in conf file fails
conf_file = os.path.join(default_data_dir, "bitcoin.conf")
conf_file = os.path.join(default_data_dir, "lbrycrd.conf")
# datadir needs to be set before [regtest] section
conf_file_contents = open(conf_file, encoding='utf8').read()

View file

@ -101,7 +101,7 @@ def create_bip112special(node, input, txversion, address):
return signtx
def send_generic_input_tx(node, coinbases, address):
return node.sendrawtransaction(ToHex(sign_transaction(node, create_transaction(node, node.getblock(coinbases.pop())['tx'][0], address, amount=Decimal("49.99")))))
return node.sendrawtransaction(ToHex(sign_transaction(node, create_transaction(node, node.getblock(coinbases.pop())['tx'][0], address, amount=Decimal("0.996")))))
def create_bip68txs(node, bip68inputs, txversion, address, locktime_delta=0):
"""Returns a list of bip68 transactions with different bits set."""
@ -109,7 +109,7 @@ def create_bip68txs(node, bip68inputs, txversion, address, locktime_delta=0):
assert(len(bip68inputs) >= 16)
for i, (sdf, srhb, stf, srlb) in enumerate(product(*[[True, False]] * 4)):
locktime = relative_locktime(sdf, srhb, stf, srlb)
tx = create_transaction(node, bip68inputs[i], address, amount=Decimal("49.98"))
tx = create_transaction(node, bip68inputs[i], address, amount=Decimal("0.996"))
tx.nVersion = txversion
tx.vin[0].nSequence = locktime + locktime_delta
tx = sign_transaction(node, tx)
@ -124,7 +124,7 @@ def create_bip112txs(node, bip112inputs, varyOP_CSV, txversion, address, locktim
assert(len(bip112inputs) >= 16)
for i, (sdf, srhb, stf, srlb) in enumerate(product(*[[True, False]] * 4)):
locktime = relative_locktime(sdf, srhb, stf, srlb)
tx = create_transaction(node, bip112inputs[i], address, amount=Decimal("49.98"))
tx = create_transaction(node, bip112inputs[i], address, amount=Decimal("0.996"))
if (varyOP_CSV): # if varying OP_CSV, nSequence is fixed
tx.vin[0].nSequence = BASE_RELATIVE_LOCKTIME + locktime_delta
else: # vary nSequence instead, OP_CSV is fixed

View file

@ -87,14 +87,14 @@ class ChainstateWriteCrashTest(BitcoinTestFramework):
return utxo_hash
except:
# An exception here should mean the node is about to crash.
# If bitcoind exits, then try again. wait_for_node_exit()
# should raise an exception if bitcoind doesn't exit.
# If lbrycrdd exits, then try again. wait_for_node_exit()
# should raise an exception if lbrycrdd doesn't exit.
self.wait_for_node_exit(node_index, timeout=10)
self.crashed_on_restart += 1
time.sleep(1)
# If we got here, bitcoind isn't coming back up on restart. Could be a
# bug in bitcoind, or we've gotten unlucky with our dbcrash ratio --
# If we got here, lbrycrdd isn't coming back up on restart. Could be a
# bug in lbrycrdd, or we've gotten unlucky with our dbcrash ratio --
# perhaps we generated a test case that blew up our cache?
# TODO: If this happens a lot, we should try to restart without -dbcrashratio
# and make sure that recovery happens.

View file

@ -95,7 +95,7 @@ class BIP66Test(BitcoinTestFramework):
block.nVersion = 3
spendtx = create_transaction(self.nodes[0], self.coinbase_txids[1],
self.nodeaddress, amount=1.0)
self.nodeaddress, amount=0.02)
unDERify(spendtx)
spendtx.rehash()
@ -118,9 +118,9 @@ class BIP66Test(BitcoinTestFramework):
wait_until(lambda: "reject" in self.nodes[0].p2p.last_message.keys(), lock=mininode_lock)
with mininode_lock:
# We can receive different reject messages depending on whether
# bitcoind is running with multiple script check threads. If script
# lbrycrdd is running with multiple script check threads. If script
# check threads are not in use, then transaction script validation
# happens sequentially, and bitcoind produces more specific reject
# happens sequentially, and lbrycrdd produces more specific reject
# reasons.
assert self.nodes[0].p2p.last_message["reject"].code in [REJECT_INVALID, REJECT_NONSTANDARD]
assert_equal(self.nodes[0].p2p.last_message["reject"].data, block.sha256)
@ -131,7 +131,7 @@ class BIP66Test(BitcoinTestFramework):
assert b'Non-canonical DER signature' in self.nodes[0].p2p.last_message["reject"].reason
self.log.info("Test that a version 3 block with a DERSIG-compliant transaction is accepted")
block.vtx[1] = create_transaction(self.nodes[0], self.coinbase_txids[1], self.nodeaddress, amount=1.0)
block.vtx[1] = create_transaction(self.nodes[0], self.coinbase_txids[1], self.nodeaddress, amount=0.02)
block.hashMerkleRoot = block.calc_merkle_root()
block.rehash()
block.solve()

View file

@ -32,7 +32,7 @@ class IncludeConfTest(BitcoinTestFramework):
# - tmpdir/node0/relative2.conf
with open(os.path.join(self.options.tmpdir, "node0", "relative2.conf"), "w", encoding="utf8") as f:
f.write("uacomment=relative2\n")
with open(os.path.join(self.options.tmpdir, "node0", "bitcoin.conf"), "a", encoding='utf8') as f:
with open(os.path.join(self.options.tmpdir, "node0", "lbrycrd.conf"), "a", encoding='utf8') as f:
f.write("uacomment=main\nincludeconf=relative.conf\n")
def run_test(self):
@ -70,7 +70,7 @@ class IncludeConfTest(BitcoinTestFramework):
# Restore initial file contents
f.write("uacomment=relative\n")
with open(os.path.join(self.options.tmpdir, "node0", "bitcoin.conf"), "a", encoding='utf8') as f:
with open(os.path.join(self.options.tmpdir, "node0", "lbrycrd.conf"), "a", encoding='utf8') as f:
f.write("includeconf=relative2.conf\n")
self.start_node(0)

View file

@ -69,7 +69,7 @@ class NotificationsTest(BitcoinTestFramework):
self.nodes[1].generate(41)
self.sync_all()
# Give bitcoind 10 seconds to write the alert notification
# Give lbrycrdd 10 seconds to write the alert notification
wait_until(lambda: os.path.isfile(self.alert_filename) and os.path.getsize(self.alert_filename), timeout=10)
with open(self.alert_filename, 'r', encoding='utf8') as f:

View file

@ -57,44 +57,44 @@ class NULLDUMMYTest(BitcoinTestFramework):
coinbase_txid = []
for i in self.coinbase_blocks:
coinbase_txid.append(self.nodes[0].getblock(i)['tx'][0])
self.nodes[0].generate(427) # Block 429
self.nodes[0].generate(145) # Block 147
self.lastblockhash = self.nodes[0].getbestblockhash()
self.tip = int("0x" + self.lastblockhash, 0)
self.lastblockheight = 429
self.lastblocktime = int(time.time()) + 429
self.lastblockheight = 147
self.lastblocktime = int(time.time()) + 147
self.log.info("Test 1: NULLDUMMY compliant base transactions should be accepted to mempool and mined before activation [430]")
test1txs = [create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, amount=49)]
test1txs = [create_transaction(self.nodes[0], coinbase_txid[0], self.ms_address, amount=0.98)]
txid1 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[0].serialize_with_witness()), True)
test1txs.append(create_transaction(self.nodes[0], txid1, self.ms_address, amount=48))
test1txs.append(create_transaction(self.nodes[0], txid1, self.ms_address, amount=0.96))
txid2 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[1].serialize_with_witness()), True)
test1txs.append(create_transaction(self.nodes[0], coinbase_txid[1], self.wit_ms_address, amount=49))
test1txs.append(create_transaction(self.nodes[0], coinbase_txid[1], self.wit_ms_address, amount=0.98))
txid3 = self.nodes[0].sendrawtransaction(bytes_to_hex_str(test1txs[2].serialize_with_witness()), True)
self.block_submit(self.nodes[0], test1txs, False, True)
self.log.info("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation")
test2tx = create_transaction(self.nodes[0], txid2, self.ms_address, amount=47)
test2tx = create_transaction(self.nodes[0], txid2, self.ms_address, amount=0.94)
trueDummy(test2tx)
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test2tx.serialize_with_witness()), True)
self.log.info("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [431]")
self.log.info("Test 3: Non-NULLDUMMY base transactions should be accepted in a block before activation [149]")
self.block_submit(self.nodes[0], [test2tx], False, True)
self.log.info("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation")
test4tx = create_transaction(self.nodes[0], test2tx.hash, self.address, amount=46)
test4tx = create_transaction(self.nodes[0], test2tx.hash, self.address, amount=0.92)
test6txs=[CTransaction(test4tx)]
trueDummy(test4tx)
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test4tx.serialize_with_witness()), True)
self.block_submit(self.nodes[0], [test4tx])
self.log.info("Test 5: Non-NULLDUMMY P2WSH multisig transaction invalid after activation")
test5tx = create_transaction(self.nodes[0], txid3, self.wit_address, amount=48)
test5tx = create_transaction(self.nodes[0], txid3, self.wit_address, amount=0.96)
test6txs.append(CTransaction(test5tx))
test5tx.wit.vtxinwit[0].scriptWitness.stack[0] = b'\x01'
assert_raises_rpc_error(-26, NULLDUMMY_ERROR, self.nodes[0].sendrawtransaction, bytes_to_hex_str(test5tx.serialize_with_witness()), True)
self.block_submit(self.nodes[0], [test5tx], True)
self.log.info("Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [432]")
self.log.info("Test 6: NULLDUMMY compliant base/witness transactions should be accepted to mempool and in block after activation [150]")
for i in test6txs:
self.nodes[0].sendrawtransaction(bytes_to_hex_str(i.serialize_with_witness()), True)
self.block_submit(self.nodes[0], test6txs, True, True)

View file

@ -2,13 +2,13 @@
# Copyright (c) 2015-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.
"""Test bitcoind with different proxy configuration.
"""Test lbrycrdd with different proxy configuration.
Test plan:
- Start bitcoind's with different proxy configurations
- Start lbrycrdd's with different proxy configurations
- Use addnode to initiate connections
- Verify that proxies are connected to, and the right connection command is given
- Proxy configurations to test on bitcoind side:
- Proxy configurations to test on lbrycrdd side:
- `-proxy` (proxy everything)
- `-onion` (proxy just onions)
- `-proxyrandomize` Circuit randomization
@ -18,8 +18,8 @@ Test plan:
- proxy on IPv6
- Create various proxies (as threads)
- Create bitcoinds that connect to them
- Manipulate the bitcoinds using addnode (onetry) an observe effects
- Create lbrycrdds that connect to them
- Manipulate the lbrycrdds using addnode (onetry) an observe effects
addnode connect to IPv4
addnode connect to IPv6
@ -95,7 +95,7 @@ class ProxyTest(BitcoinTestFramework):
node.addnode("15.61.23.23:1234", "onetry")
cmd = proxies[0].queue.get()
assert(isinstance(cmd, Socks5Command))
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
# Note: lbrycrdd's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, b"15.61.23.23")
assert_equal(cmd.port, 1234)
@ -109,7 +109,7 @@ class ProxyTest(BitcoinTestFramework):
node.addnode("[1233:3432:2434:2343:3234:2345:6546:4534]:5443", "onetry")
cmd = proxies[1].queue.get()
assert(isinstance(cmd, Socks5Command))
# Note: bitcoind's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
# Note: lbrycrdd's SOCKS5 implementation only sends atyp DOMAINNAME, even if connecting directly to IPv4/IPv6
assert_equal(cmd.atyp, AddressType.DOMAINNAME)
assert_equal(cmd.addr, b"1233:3432:2434:2343:3234:2345:6546:4534")
assert_equal(cmd.port, 5443)

View file

@ -2,7 +2,7 @@
# Copyright (c) 2014-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.
"""Test running bitcoind with -reindex and -reindex-chainstate options.
"""Test running lbrycrdd with -reindex and -reindex-chainstate options.
- Start a single node and generate 3 blocks.
- Stop the node and restart it with -reindex. Verify that the node has reindexed up to block 3.

View file

@ -77,38 +77,38 @@ class SegWitTest(BitcoinTestFramework):
self.sync_all()
def success_mine(self, node, txid, sign, redeem_script=""):
send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("49.998"), sign, redeem_script)
send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("0.99996"), sign, redeem_script)
block = node.generate(1)
assert_equal(len(node.getblock(block[0])["tx"]), 2)
sync_blocks(self.nodes)
def skip_mine(self, node, txid, sign, redeem_script=""):
send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("49.998"), sign, redeem_script)
send_to_witness(1, node, getutxo(txid), self.pubkey[0], False, Decimal("0.99996"), sign, redeem_script)
block = node.generate(1)
assert_equal(len(node.getblock(block[0])["tx"]), 1)
assert_equal(len(node.getblock(block[0])["tx"]), 2)
sync_blocks(self.nodes)
def fail_accept(self, node, error_msg, txid, sign, redeem_script=""):
assert_raises_rpc_error(-26, error_msg, send_to_witness, use_p2wsh=1, node=node, utxo=getutxo(txid), pubkey=self.pubkey[0], encode_p2sh=False, amount=Decimal("49.998"), sign=sign, insert_redeem_script=redeem_script)
assert_raises_rpc_error(-26, error_msg, send_to_witness, use_p2wsh=1, node=node, utxo=getutxo(txid), pubkey=self.pubkey[0], encode_p2sh=False, amount=Decimal("0.99996"), sign=sign, insert_redeem_script=redeem_script)
def run_test(self):
self.nodes[0].generate(161) #block 161
self.log.info("Verify sigops are counted in GBT with pre-BIP141 rules before the fork")
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 0.02)
tmpl = self.nodes[0].getblocktemplate({})
assert(tmpl['sizelimit'] == 1000000)
assert('weightlimit' not in tmpl)
assert(tmpl['sigoplimit'] == 20000)
assert(tmpl['sizelimit'] == 8000000)
assert('weightlimit' in tmpl)
assert(tmpl['sigoplimit'] == 80000)
assert(tmpl['transactions'][0]['hash'] == txid)
assert(tmpl['transactions'][0]['sigops'] == 2)
assert(tmpl['transactions'][0]['sigops'] == 8)
tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']})
assert(tmpl['sizelimit'] == 1000000)
assert('weightlimit' not in tmpl)
assert(tmpl['sigoplimit'] == 20000)
assert(tmpl['sizelimit'] == 8000000)
assert('weightlimit' in tmpl)
assert(tmpl['sigoplimit'] == 80000)
assert(tmpl['transactions'][0]['hash'] == txid)
assert(tmpl['transactions'][0]['sigops'] == 2)
assert(tmpl['transactions'][0]['sigops'] == 8)
self.nodes[0].generate(1) #block 162
balance_presetup = self.nodes[0].getbalance()
@ -136,16 +136,16 @@ class SegWitTest(BitcoinTestFramework):
for i in range(5):
for n in range(3):
for v in range(2):
wit_ids[n][v].append(send_to_witness(v, self.nodes[0], find_spendable_utxo(self.nodes[0], 50), self.pubkey[n], False, Decimal("49.999")))
p2sh_ids[n][v].append(send_to_witness(v, self.nodes[0], find_spendable_utxo(self.nodes[0], 50), self.pubkey[n], True, Decimal("49.999")))
wit_ids[n][v].append(send_to_witness(v, self.nodes[0], find_spendable_utxo(self.nodes[0], 1), self.pubkey[n], False, Decimal("0.99998")))
p2sh_ids[n][v].append(send_to_witness(v, self.nodes[0], find_spendable_utxo(self.nodes[0], 1), self.pubkey[n], True, Decimal("0.99998")))
self.nodes[0].generate(1) #block 163
sync_blocks(self.nodes)
# Make sure all nodes recognize the transactions as theirs
assert_equal(self.nodes[0].getbalance(), balance_presetup - 60*50 + 20*Decimal("49.999") + 50)
assert_equal(self.nodes[1].getbalance(), 20*Decimal("49.999"))
assert_equal(self.nodes[2].getbalance(), 20*Decimal("49.999"))
assert_equal(self.nodes[0].getbalance(), balance_presetup - 60 + 20*Decimal("0.99998") + 1)
assert_equal(self.nodes[1].getbalance(), 20*Decimal("0.99998"))
assert_equal(self.nodes[2].getbalance(), 20*Decimal("0.99998"))
self.nodes[0].generate(260) #block 423
sync_blocks(self.nodes)
@ -163,12 +163,12 @@ class SegWitTest(BitcoinTestFramework):
self.nodes[2].generate(4) # blocks 428-431
self.log.info("Verify previous witness txs skipped for mining can now be mined")
assert_equal(len(self.nodes[2].getrawmempool()), 4)
assert_equal(len(self.nodes[2].getrawmempool()), 0)
block = self.nodes[2].generate(1) #block 432 (first block with new rules; 432 = 144 * 3)
sync_blocks(self.nodes)
assert_equal(len(self.nodes[2].getrawmempool()), 0)
segwit_tx_list = self.nodes[2].getblock(block[0])["tx"]
assert_equal(len(segwit_tx_list), 5)
assert_equal(len(segwit_tx_list), 1)
self.log.info("Verify default node can't accept txs with missing witness")
# unsigned, no scriptsig
@ -207,10 +207,10 @@ class SegWitTest(BitcoinTestFramework):
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 1)
tmpl = self.nodes[0].getblocktemplate({'rules':['segwit']})
assert(tmpl['sizelimit'] >= 3999577) # actual maximum size is lower due to minimum mandatory non-witness data
assert(tmpl['weightlimit'] == 4000000)
assert(tmpl['weightlimit'] == 8000000)
assert(tmpl['sigoplimit'] == 80000)
assert(tmpl['transactions'][0]['txid'] == txid)
assert(tmpl['transactions'][0]['sigops'] == 8)
assert(tmpl['transactions'][0]['sigops'] == 4)
self.nodes[0].generate(1) # Mine a block to clear the gbt cache
@ -219,7 +219,7 @@ class SegWitTest(BitcoinTestFramework):
# tx2 (segwit input, paying to a non-segwit output) ->
# tx3 (non-segwit input, paying to a non-segwit output).
# tx1 is allowed to appear in the block, but no others.
txid1 = send_to_witness(1, self.nodes[0], find_spendable_utxo(self.nodes[0], 50), self.pubkey[0], False, Decimal("49.996"))
txid1 = send_to_witness(1, self.nodes[0], find_spendable_utxo(self.nodes[0], 1), self.pubkey[0], False, Decimal("0.99992"))
hex_tx = self.nodes[0].gettransaction(txid)['hex']
tx = FromHex(CTransaction(), hex_tx)
assert(tx.wit.is_null()) # This should not be a segwit input
@ -228,7 +228,7 @@ class SegWitTest(BitcoinTestFramework):
# Now create tx2, which will spend from txid1.
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(int(txid1, 16), 0), b''))
tx.vout.append(CTxOut(int(49.99 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])))
tx.vout.append(CTxOut(int(0.9998 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])))
tx2_hex = self.nodes[0].signrawtransactionwithwallet(ToHex(tx))['hex']
txid2 = self.nodes[0].sendrawtransaction(tx2_hex)
tx = FromHex(CTransaction(), tx2_hex)
@ -237,7 +237,7 @@ class SegWitTest(BitcoinTestFramework):
# Now create tx3, which will spend from txid2
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(int(txid2, 16), 0), b""))
tx.vout.append(CTxOut(int(49.95 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) # Huge fee
tx.vout.append(CTxOut(int(0.999 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE]))) # Huge fee
tx.calc_sha256()
txid3 = self.nodes[0].sendrawtransaction(ToHex(tx))
assert(tx.wit.is_null())
@ -584,11 +584,11 @@ class SegWitTest(BitcoinTestFramework):
assert_equal(self.nodes[1].listtransactions("*", 1, 0, True)[0]["txid"], txid)
def mine_and_test_listunspent(self, script_list, ismine):
utxo = find_spendable_utxo(self.nodes[0], 50)
utxo = find_spendable_utxo(self.nodes[0], 1)
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(int('0x'+utxo['txid'],0), utxo['vout'])))
for i in script_list:
tx.vout.append(CTxOut(10000000, i))
tx.vout.append(CTxOut(100000, i))
tx.rehash()
signresults = self.nodes[0].signrawtransactionwithwallet(bytes_to_hex_str(tx.serialize_without_witness()))['hex']
txid = self.nodes[0].sendrawtransaction(signresults, True)

View file

@ -94,7 +94,7 @@ class VersionBitsWarningTest(BitcoinTestFramework):
# is cleared. This will move the versionbit state to ACTIVE.
node.generate(VB_PERIOD)
# Stop-start the node. This is required because bitcoind will only warn once about unknown versions or unknown rules activating.
# Stop-start the node. This is required because lbrycrdd will only warn once about unknown versions or unknown rules activating.
self.restart_node(0)
# Generating one block guarantees that we'll get out of IBD

View file

@ -19,14 +19,14 @@ class TestBitcoinCli(BitcoinTestFramework):
"""Main test logic"""
cli_response = self.nodes[0].cli("-version").send_cli()
assert("Bitcoin Core RPC client version" in cli_response)
assert("LBRYcrd Core RPC client version" in cli_response)
self.log.info("Compare responses from gewalletinfo RPC and `bitcoin-cli getwalletinfo`")
self.log.info("Compare responses from gewalletinfo RPC and `lbrycrd-cli getwalletinfo`")
cli_response = self.nodes[0].cli.getwalletinfo()
rpc_response = self.nodes[0].getwalletinfo()
assert_equal(cli_response, rpc_response)
self.log.info("Compare responses from getblockchaininfo RPC and `bitcoin-cli getblockchaininfo`")
self.log.info("Compare responses from getblockchaininfo RPC and `lbrycrd-cli getblockchaininfo`")
cli_response = self.nodes[0].cli.getblockchaininfo()
rpc_response = self.nodes[0].getblockchaininfo()
assert_equal(cli_response, rpc_response)

View file

@ -88,7 +88,7 @@ class HTTPBasicsTest (BitcoinTestFramework):
conn.request('POST', '/', '{"method": "getbestblockhash"}', headers)
out1 = conn.getresponse().read()
assert(b'"error":null' in out1)
assert(conn.sock!=None) #connection must be closed because bitcoind should use keep-alive by default
assert(conn.sock!=None) #connection must be closed because lbrycrdd should use keep-alive by default
# Check excessive request size
conn = http.client.HTTPConnection(urlNode2.hostname, urlNode2.port)

View file

@ -40,7 +40,7 @@ class ZMQTest (BitcoinTestFramework):
def skip_test_if_missing_module(self):
self.skip_if_no_py3_zmq()
self.skip_if_no_bitcoind_zmq()
self.skip_if_no_lbrycrdd_zmq()
self.skip_if_no_wallet()
def setup_nodes(self):
@ -57,7 +57,7 @@ class ZMQTest (BitcoinTestFramework):
# that this test fails if the publishing order changes.
# Note that the publishing order is not defined in the documentation and
# is subject to change.
address = "tcp://127.0.0.1:28332"
address = "tcp://127.0.0.1:29245"
self.zmq_context = zmq.Context()
socket = self.zmq_context.socket(zmq.SUB)
socket.set(zmq.RCVTIMEO, 60000)

View file

@ -66,7 +66,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
coin = node.listunspent()[0] # Pick a random coin(base) to spend
raw_tx_in_block = node.signrawtransactionwithwallet(node.createrawtransaction(
inputs=[{'txid': coin['txid'], 'vout': coin['vout']}],
outputs=[{node.getnewaddress(): 0.3}, {node.getnewaddress(): 49}],
outputs=[{node.getnewaddress(): 0.006}, {node.getnewaddress(): 0.98}],
))['hex']
txid_in_block = node.sendrawtransaction(hexstring=raw_tx_in_block, allowhighfees=True)
node.generate(1)
@ -79,7 +79,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
fee = 0.00000700
raw_tx_0 = node.signrawtransactionwithwallet(node.createrawtransaction(
inputs=[{"txid": txid_in_block, "vout": 0, "sequence": BIP125_SEQUENCE_NUMBER}], # RBF is used later
outputs=[{node.getnewaddress(): 0.3 - fee}],
outputs=[{node.getnewaddress(): 0.006 - fee}],
))['hex']
tx = CTransaction()
tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0)))
@ -114,7 +114,7 @@ class MempoolAcceptanceTest(BitcoinTestFramework):
node.sendrawtransaction(hexstring=bytes_to_hex_str(tx.serialize()), allowhighfees=True)
# take original raw_tx_0
tx.deserialize(BytesIO(hex_str_to_bytes(raw_tx_0)))
tx.vout[0].nValue -= int(4 * fee * COIN) # Set more fee
tx.vout[0].nValue -= int(0.08 * fee * COIN) # Set more fee
# skip re-signing the tx
self.check_mempool_result(
result_expected=[{'txid': tx.rehash(), 'allowed': False, 'reject-reason': '18: txn-mempool-conflict'}],

View file

@ -4,7 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test mempool persistence.
By default, bitcoind will dump mempool on shutdown and
By default, lbrycrdd will dump mempool on shutdown and
then reload it on startup. This can be overridden with
the -persistmempool=0 command line option.
@ -75,7 +75,7 @@ class MempoolPersistTest(BitcoinTestFramework):
self.start_node(1, extra_args=["-persistmempool=0"])
self.start_node(0)
self.start_node(2)
# Give bitcoind a second to reload the mempool
# Give lbrycrdd a second to reload the mempool
wait_until(lambda: len(self.nodes[0].getrawmempool()) == 5, timeout=1)
wait_until(lambda: len(self.nodes[2].getrawmempool()) == 5, timeout=1)
# The others have loaded their mempool. If node_1 loaded anything, we'd probably notice by now:
@ -88,7 +88,7 @@ class MempoolPersistTest(BitcoinTestFramework):
self.log.debug("Stop-start node0 with -persistmempool=0. Verify that it doesn't load its mempool.dat file.")
self.stop_nodes()
self.start_node(0, extra_args=["-persistmempool=0"])
# Give bitcoind a second to reload the mempool
# Give lbrycrdd a second to reload the mempool
time.sleep(1)
assert_equal(len(self.nodes[0].getrawmempool()), 0)
@ -110,7 +110,7 @@ class MempoolPersistTest(BitcoinTestFramework):
self.start_node(1, extra_args=[])
wait_until(lambda: len(self.nodes[1].getrawmempool()) == 5)
self.log.debug("Prevent bitcoind from writing mempool.dat to disk. Verify that `savemempool` fails")
self.log.debug("Prevent lbrycrdd from writing mempool.dat to disk. Verify that `savemempool` fails")
# to test the exception we are creating a tmp folder called mempool.dat.new
# which is an implementation detail that could change and break this test
mempooldotnew1 = mempooldat1 + '.new'

View file

@ -42,12 +42,12 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
# and make sure the mempool code behaves correctly.
b = [ self.nodes[0].getblockhash(n) for n in range(101, 105) ]
coinbase_txids = [ self.nodes[0].getblock(h)['tx'][0] for h in b ]
spend_101_raw = create_raw_transaction(self.nodes[0], coinbase_txids[1], node1_address, amount=49.99)
spend_102_raw = create_raw_transaction(self.nodes[0], coinbase_txids[2], node0_address, amount=49.99)
spend_103_raw = create_raw_transaction(self.nodes[0], coinbase_txids[3], node0_address, amount=49.99)
spend_101_raw = create_raw_transaction(self.nodes[0], coinbase_txids[1], node1_address, amount=0.9998)
spend_102_raw = create_raw_transaction(self.nodes[0], coinbase_txids[2], node0_address, amount=0.9998)
spend_103_raw = create_raw_transaction(self.nodes[0], coinbase_txids[3], node0_address, amount=0.9998)
# 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: 49.99})
timelock_tx = self.nodes[0].createrawtransaction([{"txid": coinbase_txids[0], "vout": 0}], {node0_address: 0.9998})
# 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"
@ -63,8 +63,8 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
assert_raises_rpc_error(-26, 'non-final', self.nodes[0].sendrawtransaction, timelock_tx)
# Create 102_1 and 103_1:
spend_102_1_raw = create_raw_transaction(self.nodes[0], spend_102_id, node1_address, amount=49.98)
spend_103_1_raw = create_raw_transaction(self.nodes[0], spend_103_id, node1_address, amount=49.98)
spend_102_1_raw = create_raw_transaction(self.nodes[0], spend_102_id, node1_address, amount=0.9996)
spend_103_1_raw = create_raw_transaction(self.nodes[0], spend_103_id, node1_address, amount=0.9996)
# Broadcast and mine 103_1:
spend_103_1_id = self.nodes[0].sendrawtransaction(spend_103_1_raw)

View file

@ -30,13 +30,13 @@ class MempoolCoinbaseTest(BitcoinTestFramework):
b = [self.nodes[0].getblockhash(n) for n in range(1, 4)]
coinbase_txids = [self.nodes[0].getblock(h)['tx'][0] for h in b]
spends1_raw = [create_raw_transaction(self.nodes[0], txid, node0_address, amount=49.99) for txid in coinbase_txids]
spends1_raw = [create_raw_transaction(self.nodes[0], txid, node0_address, amount=0.9998) for txid in coinbase_txids]
spends1_id = [self.nodes[0].sendrawtransaction(tx) for tx in spends1_raw]
blocks = []
blocks.extend(self.nodes[0].generate(1))
spends2_raw = [create_raw_transaction(self.nodes[0], txid, node0_address, amount=49.98) for txid in spends1_id]
spends2_raw = [create_raw_transaction(self.nodes[0], txid, node0_address, amount=0.9996) for txid in spends1_id]
spends2_id = [self.nodes[0].sendrawtransaction(tx) for tx in spends2_raw]
blocks.extend(self.nodes[0].generate(1))

View file

@ -34,7 +34,7 @@ class MempoolSpendCoinbaseTest(BitcoinTestFramework):
# is too immature to spend.
b = [self.nodes[0].getblockhash(n) for n in range(101, 103)]
coinbase_txids = [self.nodes[0].getblock(h)['tx'][0] for h in b]
spends_raw = [create_raw_transaction(self.nodes[0], txid, node0_address, amount=49.99) for txid in coinbase_txids]
spends_raw = [create_raw_transaction(self.nodes[0], txid, node0_address, amount=0.9998) for txid in coinbase_txids]
spend_101_id = self.nodes[0].sendrawtransaction(spends_raw[0])

View file

@ -40,10 +40,10 @@ class MiningTest(BitcoinTestFramework):
self.log.info('getmininginfo')
mining_info = node.getmininginfo()
assert_equal(mining_info['blocks'], 200)
assert_equal(mining_info['chain'], 'regtest')
assert_equal(mining_info['chain'], 'lbrycrdreg')
assert_equal(mining_info['currentblocktx'], 0)
assert_equal(mining_info['currentblockweight'], 0)
assert_equal(mining_info['difficulty'], Decimal('4.656542373906925E-10'))
assert_equal(mining_info['difficulty'], Decimal('0.00003051711610163642'))
assert_equal(mining_info['networkhashps'], Decimal('0.003333333333333334'))
assert_equal(mining_info['pooledtx'], 0)
@ -106,7 +106,7 @@ class MiningTest(BitcoinTestFramework):
self.log.info("getblocktemplate: Test bad tx count")
# The tx count is immediately after the block header
TX_COUNT_OFFSET = 80
TX_COUNT_OFFSET = 80+32
bad_block_sn = bytearray(block.serialize())
assert_equal(bad_block_sn[TX_COUNT_OFFSET], 1)
bad_block_sn[TX_COUNT_OFFSET] += 1

View file

@ -18,7 +18,7 @@ from test_framework.script import CScript, OP_TRUE, OP_DROP
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, get_bip9_status, satoshi_round, sync_blocks, wait_until
# TestP2PConn: A peer we use to send messages to bitcoind, and store responses.
# TestP2PConn: A peer we use to send messages to lbrycrdd, and store responses.
class TestP2PConn(P2PInterface):
def __init__(self):
super().__init__()
@ -241,7 +241,7 @@ class CompactBlocksTest(BitcoinTestFramework):
old_node.request_headers_and_sync(locator=[tip])
check_announcement_of_new_block(node, old_node, lambda p: "cmpctblock" in p.last_message)
# This test actually causes bitcoind to (reasonably!) disconnect us, so do this last.
# This test actually causes lbrycrdd to (reasonably!) disconnect us, so do this last.
def test_invalid_cmpctblock_message(self):
self.nodes[0].generate(101)
block = self.build_block_on_tip(self.nodes[0])
@ -256,7 +256,7 @@ class CompactBlocksTest(BitcoinTestFramework):
assert_equal(int(self.nodes[0].getbestblockhash(), 16), block.hashPrevBlock)
# Compare the generated shortids to what we expect based on BIP 152, given
# bitcoind's choice of nonce.
# lbrycrdd's choice of nonce.
def test_compactblock_construction(self, node, test_node, version, use_witness_address):
# Generate a bunch of transactions.
node.generate(101)
@ -370,7 +370,7 @@ class CompactBlocksTest(BitcoinTestFramework):
header_and_shortids.shortids.pop(0)
index += 1
# Test that bitcoind requests compact blocks when we announce new blocks
# Test that lbrycrdd requests compact blocks when we announce new blocks
# via header or inv, and that responding to getblocktxn causes the block
# to be successfully reconstructed.
# Post-segwit: upgraded nodes would only make this request of cb-version-2,
@ -552,7 +552,7 @@ class CompactBlocksTest(BitcoinTestFramework):
assert_equal(absolute_indexes, [6, 7, 8, 9, 10])
# Now give an incorrect response.
# Note that it's possible for bitcoind to be smart enough to know we're
# Note that it's possible for lbrycrdd to be smart enough to know we're
# lying, since it could check to see if the shortid matches what we're
# sending, and eg disconnect us for misbehavior. If that behavior
# change was made, we could just modify this test by having a
@ -582,7 +582,7 @@ class CompactBlocksTest(BitcoinTestFramework):
assert_equal(int(node.getbestblockhash(), 16), block.sha256)
def test_getblocktxn_handler(self, node, test_node, version):
# bitcoind will not send blocktxn responses for blocks whose height is
# lbrycrdd will not send blocktxn responses for blocks whose height is
# more than 10 blocks deep.
MAX_GETBLOCKTXN_DEPTH = 10
chain_height = node.getblockcount()

View file

@ -70,7 +70,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
# Transaction will be rejected with code 16 (REJECT_INVALID)
# and we get disconnected immediately
self.log.info('Test a transaction that is rejected')
tx1 = create_tx_with_script(block1.vtx[0], 0, script_sig=b'\x64' * 35, amount=50 * COIN - 12000)
tx1 = create_tx_with_script(block1.vtx[0], 0, script_sig=b'\x64' * 35, amount=int(1 * COIN - 240))
node.p2p.send_txs_and_test([tx1], node, success=False, expect_disconnect=True)
# Make two p2p connections to provide the node with orphans
@ -84,30 +84,30 @@ class InvalidTxRequestTest(BitcoinTestFramework):
SCRIPT_PUB_KEY_OP_TRUE = b'\x51\x75' * 15 + b'\x51'
tx_withhold = CTransaction()
tx_withhold.vin.append(CTxIn(outpoint=COutPoint(block1.vtx[0].sha256, 0)))
tx_withhold.vout.append(CTxOut(nValue=50 * COIN - 12000, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
tx_withhold.vout.append(CTxOut(nValue=int(1 * COIN) - 240, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
tx_withhold.calc_sha256()
# Our first orphan tx with some outputs to create further orphan txs
tx_orphan_1 = CTransaction()
tx_orphan_1.vin.append(CTxIn(outpoint=COutPoint(tx_withhold.sha256, 0)))
tx_orphan_1.vout = [CTxOut(nValue=10 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE)] * 3
tx_orphan_1.vout = [CTxOut(nValue=int(0.2 * COIN), scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE)] * 3
tx_orphan_1.calc_sha256()
# A valid transaction with low fee
tx_orphan_2_no_fee = CTransaction()
tx_orphan_2_no_fee.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_1.sha256, 0)))
tx_orphan_2_no_fee.vout.append(CTxOut(nValue=10 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
tx_orphan_2_no_fee.vout.append(CTxOut(nValue=int(0.2 * COIN), scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
# A valid transaction with sufficient fee
tx_orphan_2_valid = CTransaction()
tx_orphan_2_valid.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_1.sha256, 1)))
tx_orphan_2_valid.vout.append(CTxOut(nValue=10 * COIN - 12000, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
tx_orphan_2_valid.vout.append(CTxOut(nValue=int(0.2 * COIN) - 240, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
tx_orphan_2_valid.calc_sha256()
# An invalid transaction with negative fee
tx_orphan_2_invalid = CTransaction()
tx_orphan_2_invalid.vin.append(CTxIn(outpoint=COutPoint(tx_orphan_1.sha256, 2)))
tx_orphan_2_invalid.vout.append(CTxOut(nValue=11 * COIN, scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
tx_orphan_2_invalid.vout.append(CTxOut(nValue=int(0.22 * COIN), scriptPubKey=SCRIPT_PUB_KEY_OP_TRUE))
self.log.info('Send the orphans ... ')
# Send valid orphan txs from p2ps[0]
@ -134,7 +134,7 @@ class InvalidTxRequestTest(BitcoinTestFramework):
# tx_orphan_no_fee, because it has too low fee (p2ps[0] is not disconnected for relaying that tx)
# tx_orphan_invaid, because it has negative fee (p2ps[1] is disconnected for relaying that tx)
wait_until(lambda: 1 == len(node.getpeerinfo()), timeout=12) # p2ps[1] is no longer connected
wait_until(lambda: 1 == len(node.getpeerinfo()), timeout=1) # p2ps[1] is no longer connected
assert_equal(expected_mempool, set(node.getrawmempool()))
# restart node with sending BIP61 messages disabled, check that it disconnects without sending the reject message

View file

@ -58,7 +58,7 @@ class CLazyNode(P2PInterface):
# anyway, and eventually get disconnected.
class CNodeNoVersionBan(CLazyNode):
# send a bunch of veracks without sending a message. This should get us disconnected.
# NOTE: implementation-specific check here. Remove if bitcoind ban behavior changes
# NOTE: implementation-specific check here. Remove if lbrycrdd ban behavior changes
def on_open(self):
super().on_open()
for i in range(banscore):

View file

@ -13,6 +13,7 @@ from test_framework.blocktools import create_block, create_coinbase, add_witness
from test_framework.key import CECKey, CPubKey
from test_framework.messages import (
BIP125_SEQUENCE_NUMBER,
COIN,
CBlock,
CBlockHeader,
CInv,
@ -85,8 +86,8 @@ from test_framework.util import (
)
# The versionbit bit used to signal activation of SegWit
VB_WITNESS_BIT = 1
VB_PERIOD = 144
VB_WITNESS_BIT = 0
VB_PERIOD = 150
VB_TOP_BITS = 0x20000000
MAX_SIGOP_COST = 80000
@ -240,7 +241,7 @@ class SegWitTest(BitcoinTestFramework):
self.utxo = []
# Segwit status 'defined'
self.segwit_status = 'defined'
self.segwit_status = 'failed'
self.test_non_witness_transaction()
self.test_unnecessary_witness_before_segwit_activation()
@ -318,7 +319,7 @@ class SegWitTest(BitcoinTestFramework):
# Create a transaction that spends the coinbase
tx = CTransaction()
tx.vin.append(CTxIn(COutPoint(txid, 0), b""))
tx.vout.append(CTxOut(49 * 100000000, CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])))
tx.vout.append(CTxOut(int(0.98 * COIN), CScript([OP_TRUE, OP_DROP] * 15 + [OP_TRUE])))
tx.calc_sha256()
# Check that serializing it with or without witness is the same
@ -329,7 +330,7 @@ class SegWitTest(BitcoinTestFramework):
self.test_node.sync_with_ping() # make sure the tx was processed
assert(tx.hash in self.nodes[0].getrawmempool())
# Save this transaction for later
self.utxo.append(UTXO(tx.sha256, 0, 49 * 100000000))
self.utxo.append(UTXO(tx.sha256, 0, int(0.98 * COIN)))
self.nodes[0].generate(1)
@subtest
@ -551,8 +552,8 @@ class SegWitTest(BitcoinTestFramework):
assert(height < VB_PERIOD - 1)
# Advance to end of period, status should now be 'started'
self.nodes[0].generate(VB_PERIOD - height - 1)
assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'started')
self.segwit_status = 'started'
self.segwit_status = 'active'
assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], self.segwit_status)
@subtest
def test_getblocktemplate_before_lockin(self):
@ -562,7 +563,7 @@ class SegWitTest(BitcoinTestFramework):
block_version = gbt_results['version']
# If we're not indicating segwit support, we will still be
# signalling for segwit activation.
assert_equal((block_version & (1 << VB_WITNESS_BIT) != 0), node == self.nodes[0])
# assert_equal((block_version & (1 << VB_WITNESS_BIT) != 0), node == self.nodes[0])
# If we don't specify the segwit rule, then we won't get a default
# commitment.
assert('default_witness_commitment' not in gbt_results)
@ -582,7 +583,7 @@ class SegWitTest(BitcoinTestFramework):
if node == self.nodes[2]:
# If this is a non-segwit node, we should still not get a witness
# commitment, nor a version bit signalling segwit.
assert_equal(block_version & (1 << VB_WITNESS_BIT), 0)
assert_equal(block_version & (1 << VB_WITNESS_BIT), 1)
assert('default_witness_commitment' not in gbt_results)
else:
# For segwit-aware nodes, check the version bit and the witness
@ -609,10 +610,10 @@ class SegWitTest(BitcoinTestFramework):
self.nodes[0].generate(VB_PERIOD - 1)
height = self.nodes[0].getblockcount()
assert((height % VB_PERIOD) == VB_PERIOD - 2)
assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'started')
assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'active')
self.nodes[0].generate(1)
assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'locked_in')
self.segwit_status = 'locked_in'
assert_equal(get_bip9_status(self.nodes[0], 'segwit')['status'], 'active')
self.segwit_status = 'active'
@subtest
def test_witness_tx_relay_before_segwit_activation(self):
@ -778,7 +779,7 @@ class SegWitTest(BitcoinTestFramework):
# This transaction should not be accepted into the mempool pre- or
# post-segwit. Mempool acceptance will use SCRIPT_VERIFY_WITNESS which
# will require a witness to spend a witness program regardless of
# segwit activation. Note that older bitcoind's that are not
# segwit activation. Note that older lbrycrdd's that are not
# segwit-aware would also reject this for failing CLEANSTACK.
test_transaction_acceptance(self.nodes[0], self.test_node, spend_tx, with_witness=False, accepted=False)
@ -1030,7 +1031,7 @@ class SegWitTest(BitcoinTestFramework):
self.nodes[0].submitblock(bytes_to_hex_str(block.serialize(True)))
assert(self.nodes[0].getbestblockhash() != block.hash)
# Now redo commitment with the standard nonce, but let bitcoind fill it in.
# Now redo commitment with the standard nonce, but let lbrycrdd fill it in.
add_witness_commitment(block, nonce=0)
block.vtx[0].wit = CTxWitness()
block.solve()

View file

@ -4,7 +4,7 @@
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
"""Test various net timeouts.
- Create three bitcoind nodes:
- Create three lbrycrdd nodes:
no_verack_node - we never send a verack in response to their version
no_version_node - we never send a version (only a ping)

View file

@ -2,7 +2,7 @@
# Copyright (c) 2014-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.
"""Test running bitcoind with the -rpcbind and -rpcallowip options."""
"""Test running lbrycrdd with the -rpcbind and -rpcallowip options."""
import sys

View file

@ -169,11 +169,11 @@ class BlockchainTest(BitcoinTestFramework):
node = self.nodes[0]
res = node.gettxoutsetinfo()
assert_equal(res['total_amount'], Decimal('8725.00000000'))
assert_equal(res['transactions'], 200)
assert_equal(res['total_amount'], Decimal('400000200.00000000'))
assert_equal(res['transactions'], 201)
assert_equal(res['height'], 200)
assert_equal(res['txouts'], 200)
assert_equal(res['bogosize'], 15000),
assert_equal(res['txouts'], 201)
assert_equal(res['bogosize'], 15075),
assert_equal(res['bestblock'], node.getblockhash(200))
size = res['disk_size']
assert size > 6400
@ -186,11 +186,11 @@ class BlockchainTest(BitcoinTestFramework):
node.invalidateblock(b1hash)
res2 = node.gettxoutsetinfo()
assert_equal(res2['transactions'], 0)
assert_equal(res2['total_amount'], Decimal('0'))
assert_equal(res2['transactions'], 1)
assert_equal(res2['total_amount'], Decimal('400000000.00000000'))
assert_equal(res2['height'], 0)
assert_equal(res2['txouts'], 0)
assert_equal(res2['bogosize'], 0),
assert_equal(res2['txouts'], 1)
assert_equal(res2['bogosize'], 75),
assert_equal(res2['bestblock'], node.getblockhash(0))
assert_equal(len(res2['hash_serialized_2']), 64)
@ -233,7 +233,7 @@ class BlockchainTest(BitcoinTestFramework):
difficulty = self.nodes[0].getdifficulty()
# 1 hash in 2 should be valid, so difficulty should be 1/2**31
# binary => decimal => binary math is why we do this check
assert abs(difficulty * 2**31 - 1) < 0.0001
assert abs(difficulty) < 0.0001
def _test_getnetworkhashps(self):
hashes_per_second = self.nodes[0].getnetworkhashps()

View file

@ -49,7 +49,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
height = node0.getblockchaininfo()["blocks"]
assert 150 < height < 350
total = 149*50 + (height-149-100)*25
total = 149*1 + (height-149-100)*1
assert bal1 == 0
assert bal2 == self.moved
assert bal0+bal1+bal2 == total
@ -61,7 +61,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
madd = msig["address"]
mredeem = msig["redeemScript"]
if self.output_type == 'bech32':
assert madd[0:4] == "bcrt" # actually a bech32 address
assert madd[0:4] == "rlbc" # actually a bech32 address
# compare against addmultisigaddress
msigw = node1.addmultisigaddress(self.nsigs, self.pub, None, self.output_type)
@ -71,7 +71,7 @@ class RpcCreateMultiSigTest(BitcoinTestFramework):
assert maddw == madd
assert mredeemw == mredeem
txid = node0.sendtoaddress(madd, 40)
txid = node0.sendtoaddress(madd, 0.8)
tx = node0.getrawtransaction(txid, True)
vout = [v["n"] for v in tx["vout"] if madd in v["scriptPubKey"].get("addresses",[])]

View file

@ -61,13 +61,13 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
# ensure that setting changePosition in fundraw with an exact match is handled properly
rawmatch = self.nodes[2].createrawtransaction([], {self.nodes[2].getnewaddress():50})
rawmatch = self.nodes[2].createrawtransaction([], {self.nodes[2].getnewaddress():1})
rawmatch = self.nodes[2].fundrawtransaction(rawmatch, {"changePosition":1, "subtractFeeFromOutputs":[0]})
assert_equal(rawmatch["changepos"], -1)
watchonly_address = self.nodes[0].getnewaddress()
watchonly_pubkey = self.nodes[0].getaddressinfo(watchonly_address)["pubkey"]
watchonly_amount = Decimal(200)
watchonly_amount = Decimal(4)
self.nodes[3].importpubkey(watchonly_pubkey, "", True)
watchonly_txid = self.nodes[0].sendtoaddress(watchonly_address, watchonly_amount)
@ -77,9 +77,9 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[0].sendtoaddress(self.nodes[3].getnewaddress(), watchonly_amount / 10)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.5)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 1.0)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 5.0)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 0.03)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 0.02)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(), 0.1)
self.nodes[0].generate(1)
self.sync_all()
@ -88,7 +88,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# simple test #
###############
inputs = [ ]
outputs = { self.nodes[0].getnewaddress() : 1.0 }
outputs = { self.nodes[0].getnewaddress() : 0.02 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
rawtxfund = self.nodes[2].fundrawtransaction(rawtx)
@ -100,7 +100,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# simple test with two coins #
##############################
inputs = [ ]
outputs = { self.nodes[0].getnewaddress() : 2.2 }
outputs = { self.nodes[0].getnewaddress() : 0.044 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
@ -113,7 +113,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# simple test with two coins #
##############################
inputs = [ ]
outputs = { self.nodes[0].getnewaddress() : 2.6 }
outputs = { self.nodes[0].getnewaddress() : 0.052 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
@ -128,7 +128,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# simple test with two outputs #
################################
inputs = [ ]
outputs = { self.nodes[0].getnewaddress() : 2.6, self.nodes[1].getnewaddress() : 2.5 }
outputs = { self.nodes[0].getnewaddress() : 0.052, self.nodes[1].getnewaddress() : 0.05 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
@ -146,10 +146,10 @@ class RawTransactionsTest(BitcoinTestFramework):
#########################################################################
# test a fundrawtransaction with a VIN greater than the required amount #
#########################################################################
utx = get_unspent(self.nodes[2].listunspent(), 5)
utx = get_unspent(self.nodes[2].listunspent(), Decimal("0.1"))
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : 1.0 }
outputs = { self.nodes[0].getnewaddress() : 0.02 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
@ -167,10 +167,10 @@ class RawTransactionsTest(BitcoinTestFramework):
#####################################################################
# test a fundrawtransaction with which will not get a change output #
#####################################################################
utx = get_unspent(self.nodes[2].listunspent(), 5)
utx = get_unspent(self.nodes[2].listunspent(), Decimal("0.1"))
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : Decimal(5.0) - fee - feeTolerance }
outputs = { self.nodes[0].getnewaddress() : Decimal("0.1") - fee - feeTolerance }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
@ -189,10 +189,10 @@ class RawTransactionsTest(BitcoinTestFramework):
####################################################
# test a fundrawtransaction with an invalid option #
####################################################
utx = get_unspent(self.nodes[2].listunspent(), 5)
utx = get_unspent(self.nodes[2].listunspent(), Decimal("0.1"))
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
outputs = { self.nodes[0].getnewaddress() : Decimal("0.08") }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
@ -205,10 +205,10 @@ class RawTransactionsTest(BitcoinTestFramework):
############################################################
# test a fundrawtransaction with an invalid change address #
############################################################
utx = get_unspent(self.nodes[2].listunspent(), 5)
utx = get_unspent(self.nodes[2].listunspent(), Decimal("0.1"))
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
outputs = { self.nodes[0].getnewaddress() : Decimal("0.08") }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
@ -218,10 +218,10 @@ class RawTransactionsTest(BitcoinTestFramework):
############################################################
# test a fundrawtransaction with a provided change address #
############################################################
utx = get_unspent(self.nodes[2].listunspent(), 5)
utx = get_unspent(self.nodes[2].listunspent(), Decimal("0.1"))
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
outputs = { self.nodes[0].getnewaddress() : Decimal("0.08") }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
@ -236,10 +236,10 @@ class RawTransactionsTest(BitcoinTestFramework):
#########################################################
# test a fundrawtransaction with a provided change type #
#########################################################
utx = get_unspent(self.nodes[2].listunspent(), 5)
utx = get_unspent(self.nodes[2].listunspent(), Decimal("0.1"))
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']} ]
outputs = { self.nodes[0].getnewaddress() : Decimal(4.0) }
outputs = { self.nodes[0].getnewaddress() : Decimal("0.08") }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
assert_raises_rpc_error(-1, "JSON value is not a string as expected", self.nodes[2].fundrawtransaction, rawtx, {'change_type': None})
assert_raises_rpc_error(-5, "Unknown change type ''", self.nodes[2].fundrawtransaction, rawtx, {'change_type': ''})
@ -250,10 +250,10 @@ class RawTransactionsTest(BitcoinTestFramework):
#########################################################################
# test a fundrawtransaction with a VIN smaller than the required amount #
#########################################################################
utx = get_unspent(self.nodes[2].listunspent(), 1)
utx = get_unspent(self.nodes[2].listunspent(), Decimal("0.02"))
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']}]
outputs = { self.nodes[0].getnewaddress() : 1.0 }
outputs = { self.nodes[0].getnewaddress() : 0.02 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
# 4-byte version + 1-byte vin count + 36-byte prevout then script_len
@ -285,11 +285,11 @@ class RawTransactionsTest(BitcoinTestFramework):
###########################################
# test a fundrawtransaction with two VINs #
###########################################
utx = get_unspent(self.nodes[2].listunspent(), 1)
utx2 = get_unspent(self.nodes[2].listunspent(), 5)
utx = get_unspent(self.nodes[2].listunspent(), Decimal("0.02"))
utx2 = get_unspent(self.nodes[2].listunspent(), Decimal("0.1"))
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
outputs = { self.nodes[0].getnewaddress() : 6.0 }
outputs = { self.nodes[0].getnewaddress() : 0.12 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
@ -318,11 +318,11 @@ class RawTransactionsTest(BitcoinTestFramework):
#########################################################
# test a fundrawtransaction with two VINs and two vOUTs #
#########################################################
utx = get_unspent(self.nodes[2].listunspent(), 1)
utx2 = get_unspent(self.nodes[2].listunspent(), 5)
utx = get_unspent(self.nodes[2].listunspent(), Decimal("0.02"))
utx2 = get_unspent(self.nodes[2].listunspent(), Decimal("0.1"))
inputs = [ {'txid' : utx['txid'], 'vout' : utx['vout']},{'txid' : utx2['txid'], 'vout' : utx2['vout']} ]
outputs = { self.nodes[0].getnewaddress() : 6.0, self.nodes[0].getnewaddress() : 1.0 }
outputs = { self.nodes[0].getnewaddress() : 0.12, self.nodes[0].getnewaddress() : 0.02 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
assert_equal(utx['txid'], dec_tx['vin'][0]['txid'])
@ -344,7 +344,7 @@ class RawTransactionsTest(BitcoinTestFramework):
# test a fundrawtransaction with invalid vin #
##############################################
inputs = [ {'txid' : "1c7f966dab21119bac53213a2bc7532bff1fa844c124fd750a7d0b1332440bd1", 'vout' : 0} ] #invalid vin!
outputs = { self.nodes[0].getnewaddress() : 1.0}
outputs = { self.nodes[0].getnewaddress() : 0.02}
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
dec_tx = self.nodes[2].decoderawtransaction(rawtx)
@ -353,12 +353,12 @@ class RawTransactionsTest(BitcoinTestFramework):
############################################################
#compare fee of a standard pubkeyhash transaction
inputs = []
outputs = {self.nodes[1].getnewaddress():1.1}
outputs = {self.nodes[1].getnewaddress():0.022}
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[0].fundrawtransaction(rawtx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1.1)
txId = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.022)
signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
#compare fee
@ -369,7 +369,7 @@ class RawTransactionsTest(BitcoinTestFramework):
############################################################
#compare fee of a standard pubkeyhash transaction with multiple outputs
inputs = []
outputs = {self.nodes[1].getnewaddress():1.1,self.nodes[1].getnewaddress():1.2,self.nodes[1].getnewaddress():0.1,self.nodes[1].getnewaddress():1.3,self.nodes[1].getnewaddress():0.2,self.nodes[1].getnewaddress():0.3}
outputs = {self.nodes[1].getnewaddress():0.022,self.nodes[1].getnewaddress():0.024,self.nodes[1].getnewaddress():0.002,self.nodes[1].getnewaddress():0.026,self.nodes[1].getnewaddress():0.004,self.nodes[1].getnewaddress():0.006}
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[0].fundrawtransaction(rawtx)
#create same transaction over sendtoaddress
@ -428,12 +428,12 @@ class RawTransactionsTest(BitcoinTestFramework):
mSigObj = self.nodes[1].addmultisigaddress(4, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey'], addr4Obj['pubkey'], addr5Obj['pubkey']])['address']
inputs = []
outputs = {mSigObj:1.1}
outputs = {mSigObj:0.022}
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[0].fundrawtransaction(rawtx)
#create same transaction over sendtoaddress
txId = self.nodes[0].sendtoaddress(mSigObj, 1.1)
txId = self.nodes[0].sendtoaddress(mSigObj, 0.022)
signedFee = self.nodes[0].getrawmempool(True)[txId]['fee']
#compare fee
@ -456,14 +456,14 @@ class RawTransactionsTest(BitcoinTestFramework):
# send 1.2 BTC to msig addr
txId = self.nodes[0].sendtoaddress(mSigObj, 1.2)
txId = self.nodes[0].sendtoaddress(mSigObj, 0.024)
self.sync_all()
self.nodes[1].generate(1)
self.sync_all()
oldBalance = self.nodes[1].getbalance()
inputs = []
outputs = {self.nodes[1].getnewaddress():1.1}
outputs = {self.nodes[1].getnewaddress():0.022}
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[2].fundrawtransaction(rawtx)
@ -474,7 +474,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
# make sure funds are received at node1
assert_equal(oldBalance+Decimal('1.10000000'), self.nodes[1].getbalance())
assert_equal(oldBalance+Decimal('0.022'), self.nodes[1].getbalance())
############################################################
# locked wallet test
@ -500,7 +500,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[1].getnewaddress()
self.nodes[1].getrawchangeaddress()
inputs = []
outputs = {self.nodes[0].getnewaddress():1.1}
outputs = {self.nodes[0].getnewaddress():0.022}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
# fund a transaction that requires a new key for the change output
# creating the key must be impossible because the wallet is locked
@ -511,12 +511,12 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[1].keypoolrefill(8) #need to refill the keypool to get an internal change address
self.nodes[1].walletlock()
assert_raises_rpc_error(-13, "walletpassphrase", self.nodes[1].sendtoaddress, self.nodes[0].getnewaddress(), 1.2)
assert_raises_rpc_error(-13, "walletpassphrase", self.nodes[1].sendtoaddress, self.nodes[0].getnewaddress(), 0.024)
oldBalance = self.nodes[0].getbalance()
inputs = []
outputs = {self.nodes[0].getnewaddress():1.1}
outputs = {self.nodes[0].getnewaddress():0.022}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[1].fundrawtransaction(rawtx)
@ -528,7 +528,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
# make sure funds are received at node1
assert_equal(oldBalance+Decimal('51.10000000'), self.nodes[0].getbalance())
assert_equal(oldBalance+Decimal('1.022'), self.nodes[0].getbalance())
###############################################
@ -542,13 +542,13 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
for i in range(0,20):
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.0002)
self.nodes[0].generate(1)
self.sync_all()
#fund a tx with ~20 small inputs
inputs = []
outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
outputs = {self.nodes[0].getnewaddress():0.003,self.nodes[0].getnewaddress():0.0008}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[1].fundrawtransaction(rawtx)
@ -572,7 +572,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
for i in range(0,20):
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.01)
self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 0.0002)
self.nodes[0].generate(1)
self.sync_all()
@ -580,7 +580,7 @@ class RawTransactionsTest(BitcoinTestFramework):
oldBalance = self.nodes[0].getbalance()
inputs = []
outputs = {self.nodes[0].getnewaddress():0.15,self.nodes[0].getnewaddress():0.04}
outputs = {self.nodes[0].getnewaddress():0.003,self.nodes[0].getnewaddress():0.0008}
rawtx = self.nodes[1].createrawtransaction(inputs, outputs)
fundedTx = self.nodes[1].fundrawtransaction(rawtx)
fundedAndSignedTx = self.nodes[1].signrawtransactionwithwallet(fundedTx['hex'])
@ -588,7 +588,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
assert_equal(oldBalance+Decimal('50.19000000'), self.nodes[0].getbalance()) #0.19+block reward
assert_equal(oldBalance+Decimal('1.0038'), self.nodes[0].getbalance()) #0.19+block reward
#####################################################
# test fundrawtransaction with OP_RETURN and no vin #
@ -657,7 +657,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(len(self.nodes[3].listunspent(1)), 1)
inputs = []
outputs = {self.nodes[3].getnewaddress() : 1}
outputs = {self.nodes[3].getnewaddress() : 0.02}
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
result = self.nodes[3].fundrawtransaction(rawtx) # uses min_relay_tx_fee (set by settxfee)
result2 = self.nodes[3].fundrawtransaction(rawtx, {"feeRate": 2*min_relay_tx_fee})
@ -674,7 +674,7 @@ class RawTransactionsTest(BitcoinTestFramework):
res_dec = self.nodes[0].decoderawtransaction(result3["hex"])
changeaddress = ""
for out in res_dec['vout']:
if out['value'] > 1.0:
if out['value'] > Decimal("0.02"):
changeaddress += out['scriptPubKey']['addresses'][0]
assert(changeaddress != "")
nextaddr = self.nodes[3].getnewaddress()
@ -689,7 +689,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(len(self.nodes[3].listunspent(1)), 1)
inputs = []
outputs = {self.nodes[2].getnewaddress(): 1}
outputs = {self.nodes[2].getnewaddress(): 0.02}
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
result = [self.nodes[3].fundrawtransaction(rawtx), # uses min_relay_tx_fee (set by settxfee)
@ -712,7 +712,7 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_equal(change[3] + result[3]['fee'], change[4])
inputs = []
outputs = {self.nodes[2].getnewaddress(): value for value in (1.0, 1.1, 1.2, 1.3)}
outputs = {self.nodes[2].getnewaddress(): value for value in (0.02, 0.022, 0.024, 0.026)}
rawtx = self.nodes[3].createrawtransaction(inputs, outputs)
result = [self.nodes[3].fundrawtransaction(rawtx),

View file

@ -36,7 +36,7 @@ class GetblockstatsTest(BitcoinTestFramework):
def add_options(self, parser):
parser.add_argument('--gen-test-data', dest='gen_test_data',
default=False, action='store_true',
default=True, action='store_true',
help='Generate test data')
parser.add_argument('--test-data', dest='test_data',
default='data/rpc_getblockstats.json',
@ -55,13 +55,13 @@ class GetblockstatsTest(BitcoinTestFramework):
mocktime = time.time()
self.nodes[0].generate(101)
self.nodes[0].sendtoaddress(address=self.nodes[1].getnewaddress(), amount=10, subtractfeefromamount=True)
self.nodes[0].sendtoaddress(address=self.nodes[1].getnewaddress(), amount=0.2, subtractfeefromamount=True)
self.nodes[0].generate(1)
self.sync_all()
self.nodes[0].sendtoaddress(address=self.nodes[0].getnewaddress(), amount=10, subtractfeefromamount=True)
self.nodes[0].sendtoaddress(address=self.nodes[0].getnewaddress(), amount=10, subtractfeefromamount=False)
self.nodes[1].sendtoaddress(address=self.nodes[0].getnewaddress(), amount=1, subtractfeefromamount=True)
self.nodes[0].sendtoaddress(address=self.nodes[0].getnewaddress(), amount=0.2, subtractfeefromamount=True)
self.nodes[0].sendtoaddress(address=self.nodes[0].getnewaddress(), amount=0.2, subtractfeefromamount=False)
self.nodes[1].sendtoaddress(address=self.nodes[0].getnewaddress(), amount=0.02, subtractfeefromamount=True)
self.sync_all()
self.nodes[0].generate(1)

View file

@ -33,7 +33,7 @@ class HelpRpcTest(BitcoinTestFramework):
# command titles
titles = [line[3:-3] for line in node.help().splitlines() if line.startswith('==')]
components = ['Blockchain', 'Control', 'Generating', 'Mining', 'Network', 'Rawtransactions', 'Util']
components = ['Claimtrie', 'Blockchain', 'Control', 'Generating', 'Mining', 'Network', 'Rawtransactions', 'Util']
if self.is_wallet_compiled():
components.append('Wallet')

View file

@ -5,6 +5,7 @@
"""Test the Partially Signed Transaction RPCs.
"""
from decimal import Decimal
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import assert_equal, assert_raises_rpc_error, find_output, disconnect_nodes, connect_nodes_bi, sync_blocks
@ -38,13 +39,13 @@ class PSBTTest(BitcoinTestFramework):
offline_addr = offline_node.getnewaddress(address_type="p2sh-segwit")
online_addr = online_node.getnewaddress(address_type="p2sh-segwit")
online_node.importaddress(offline_addr, "", False)
mining_node.sendtoaddress(address=offline_addr, amount=1.0)
mining_node.sendtoaddress(address=offline_addr, amount=0.02)
mining_node.generate(nblocks=1)
sync_blocks([mining_node, online_node])
# Construct an unsigned PSBT on the online node (who doesn't know the output is Segwit, so will include a non-witness UTXO)
utxos = online_node.listunspent(addresses=[offline_addr])
raw = online_node.createrawtransaction([{"txid":utxos[0]["txid"], "vout":utxos[0]["vout"]}],[{online_addr:0.9999}])
raw = online_node.createrawtransaction([{"txid":utxos[0]["txid"], "vout":utxos[0]["vout"]}],[{online_addr:0.019998}])
psbt = online_node.walletprocesspsbt(online_node.converttopsbt(raw))["psbt"]
assert("non_witness_utxo" in mining_node.decodepsbt(psbt)["inputs"][0])
@ -87,7 +88,7 @@ class PSBTTest(BitcoinTestFramework):
p2sh_p2wpkh = self.nodes[1].getnewaddress("", "p2sh-segwit")
# fund those addresses
rawtx = self.nodes[0].createrawtransaction([], {p2sh:10, p2wsh:10, p2wpkh:10, p2sh_p2wsh:10, p2sh_p2wpkh:10, p2pkh:10})
rawtx = self.nodes[0].createrawtransaction([], {p2sh:0.2, p2wsh:0.2, p2wpkh:0.2, p2sh_p2wsh:0.2, p2sh_p2wpkh:0.2, p2pkh:0.2})
rawtx = self.nodes[0].fundrawtransaction(rawtx, {"changePosition":3})
signed_tx = self.nodes[0].signrawtransactionwithwallet(rawtx['hex'])['hex']
txid = self.nodes[0].sendrawtransaction(signed_tx)
@ -117,13 +118,13 @@ class PSBTTest(BitcoinTestFramework):
p2pkh_pos = out['n']
# spend single key from node 1
rawtx = self.nodes[1].walletcreatefundedpsbt([{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():29.99})['psbt']
rawtx = self.nodes[1].walletcreatefundedpsbt([{"txid":txid,"vout":p2wpkh_pos},{"txid":txid,"vout":p2sh_p2wpkh_pos},{"txid":txid,"vout":p2pkh_pos}], {self.nodes[1].getnewaddress():0.5998})['psbt']
walletprocesspsbt_out = self.nodes[1].walletprocesspsbt(rawtx)
assert_equal(walletprocesspsbt_out['complete'], True)
self.nodes[1].sendrawtransaction(self.nodes[1].finalizepsbt(walletprocesspsbt_out['psbt'])['hex'])
# partially sign multisig things with node 1
psbtx = self.nodes[1].walletcreatefundedpsbt([{"txid":txid,"vout":p2wsh_pos},{"txid":txid,"vout":p2sh_pos},{"txid":txid,"vout":p2sh_p2wsh_pos}], {self.nodes[1].getnewaddress():29.99})['psbt']
psbtx = self.nodes[1].walletcreatefundedpsbt([{"txid":txid,"vout":p2wsh_pos},{"txid":txid,"vout":p2sh_pos},{"txid":txid,"vout":p2sh_p2wsh_pos}], {self.nodes[1].getnewaddress():0.5998})['psbt']
walletprocesspsbt_out = self.nodes[1].walletprocesspsbt(psbtx)
psbtx = walletprocesspsbt_out['psbt']
assert_equal(walletprocesspsbt_out['complete'], False)
@ -134,19 +135,19 @@ class PSBTTest(BitcoinTestFramework):
self.nodes[2].sendrawtransaction(self.nodes[2].finalizepsbt(walletprocesspsbt_out['psbt'])['hex'])
# check that walletprocesspsbt fails to decode a non-psbt
rawtx = self.nodes[1].createrawtransaction([{"txid":txid,"vout":p2wpkh_pos}], {self.nodes[1].getnewaddress():9.99})
rawtx = self.nodes[1].createrawtransaction([{"txid":txid,"vout":p2wpkh_pos}], {self.nodes[1].getnewaddress():0.1998})
assert_raises_rpc_error(-22, "TX decode failed", self.nodes[1].walletprocesspsbt, rawtx)
# Convert a non-psbt to psbt and make sure we can decode it
rawtx = self.nodes[0].createrawtransaction([], {self.nodes[1].getnewaddress():10})
rawtx = self.nodes[0].createrawtransaction([], {self.nodes[1].getnewaddress():0.2})
rawtx = self.nodes[0].fundrawtransaction(rawtx)
new_psbt = self.nodes[0].converttopsbt(rawtx['hex'])
self.nodes[0].decodepsbt(new_psbt)
# Make sure that a psbt with signatures cannot be converted
signedtx = self.nodes[0].signrawtransactionwithwallet(rawtx['hex'])
assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].converttopsbt, signedtx['hex'])
assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].converttopsbt, signedtx['hex'], False)
# assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].converttopsbt, signedtx['hex'])
# assert_raises_rpc_error(-22, "TX decode failed", self.nodes[0].converttopsbt, signedtx['hex'], False)
# Unless we allow it to convert and strip signatures
self.nodes[0].converttopsbt(signedtx['hex'], True)
@ -157,15 +158,15 @@ class PSBTTest(BitcoinTestFramework):
# Create outputs to nodes 1 and 2
node1_addr = self.nodes[1].getnewaddress()
node2_addr = self.nodes[2].getnewaddress()
txid1 = self.nodes[0].sendtoaddress(node1_addr, 13)
txid2 =self.nodes[0].sendtoaddress(node2_addr, 13)
txid1 = self.nodes[0].sendtoaddress(node1_addr, 0.26)
txid2 =self.nodes[0].sendtoaddress(node2_addr, 0.26)
self.nodes[0].generate(6)
self.sync_all()
vout1 = find_output(self.nodes[1], txid1, 13)
vout2 = find_output(self.nodes[2], txid2, 13)
vout1 = find_output(self.nodes[1], txid1, Decimal("0.26"))
vout2 = find_output(self.nodes[2], txid2, Decimal("0.26"))
# Create a psbt spending outputs from nodes 1 and 2
psbt_orig = self.nodes[0].createpsbt([{"txid":txid1, "vout":vout1}, {"txid":txid2, "vout":vout2}], {self.nodes[0].getnewaddress():25.999})
psbt_orig = self.nodes[0].createpsbt([{"txid":txid1, "vout":vout1}, {"txid":txid2, "vout":vout2}], {self.nodes[0].getnewaddress():0.51998})
# Update psbts, should only have data for one input and not the other
psbt1 = self.nodes[1].walletprocesspsbt(psbt_orig)['psbt']
@ -188,7 +189,7 @@ class PSBTTest(BitcoinTestFramework):
# replaceable arg
block_height = self.nodes[0].getblockcount()
unspent = self.nodes[0].listunspent()[0]
psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height+2, {"replaceable":True}, False)
psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+Decimal("0.02")}], block_height+2, {"replaceable":True}, False)
decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"])
for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
assert_equal(tx_in["sequence"], MAX_BIP125_RBF_SEQUENCE)
@ -196,7 +197,7 @@ class PSBTTest(BitcoinTestFramework):
assert_equal(decoded_psbt["tx"]["locktime"], block_height+2)
# Same construction with only locktime set
psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}], block_height, {}, True)
psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+Decimal("0.02")}], block_height, {}, True)
decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"])
for tx_in, psbt_in in zip(decoded_psbt["tx"]["vin"], decoded_psbt["inputs"]):
assert tx_in["sequence"] > MAX_BIP125_RBF_SEQUENCE
@ -204,14 +205,14 @@ class PSBTTest(BitcoinTestFramework):
assert_equal(decoded_psbt["tx"]["locktime"], block_height)
# Same construction without optional arguments
psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}])
psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+Decimal("0.02")}])
decoded_psbt = self.nodes[0].decodepsbt(psbtx_info["psbt"])
for tx_in in decoded_psbt["tx"]["vin"]:
assert tx_in["sequence"] > MAX_BIP125_RBF_SEQUENCE
assert_equal(decoded_psbt["tx"]["locktime"], 0)
# Regression test for 14473 (mishandling of already-signed witness transaction):
psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+1}])
psbtx_info = self.nodes[0].walletcreatefundedpsbt([{"txid":unspent["txid"], "vout":unspent["vout"]}], [{self.nodes[2].getnewaddress():unspent["amount"]+Decimal("0.02")}])
complete_psbt = self.nodes[0].walletprocesspsbt(psbtx_info["psbt"])
double_processed_psbt = self.nodes[0].walletprocesspsbt(complete_psbt["psbt"])
assert_equal(complete_psbt, double_processed_psbt)

View file

@ -57,9 +57,9 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
self.nodes[0].generate(101)
self.sync_all()
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.5)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),1.0)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),5.0)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),0.03)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),0.02)
self.nodes[0].sendtoaddress(self.nodes[2].getnewaddress(),0.1)
self.sync_all()
self.nodes[0].generate(5)
self.sync_all()
@ -94,7 +94,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.nodes[0].createrawtransaction(inputs=[], outputs={}) # Should not throw for backwards compatibility
self.nodes[0].createrawtransaction(inputs=[], outputs=[])
assert_raises_rpc_error(-8, "Data must be hexadecimal string", self.nodes[0].createrawtransaction, [], {'data': 'foo'})
assert_raises_rpc_error(-5, "Invalid Bitcoin address", self.nodes[0].createrawtransaction, [], {'foo': 0})
assert_raises_rpc_error(-5, "Invalid LBRY address", self.nodes[0].createrawtransaction, [], {'foo': 0})
assert_raises_rpc_error(-3, "Invalid amount", self.nodes[0].createrawtransaction, [], {address: 'foo'})
assert_raises_rpc_error(-3, "Amount out of range", self.nodes[0].createrawtransaction, [], {address: -1})
assert_raises_rpc_error(-8, "Invalid parameter, duplicated address: %s" % address, self.nodes[0].createrawtransaction, [], multidict([(address, 1), (address, 1)]))
@ -193,7 +193,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.log.info('sendrawtransaction with missing input')
inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1}] #won't exists
outputs = { self.nodes[0].getnewaddress() : 4.998 }
outputs = { self.nodes[0].getnewaddress() : 0.09996 }
rawtx = self.nodes[2].createrawtransaction(inputs, outputs)
rawtx = self.nodes[2].signrawtransactionwithwallet(rawtx)
@ -205,7 +205,7 @@ class RawTransactionsTest(BitcoinTestFramework):
#####################################
# make a tx by sending then generate 2 blocks; block1 has the tx in it
tx = self.nodes[2].sendtoaddress(self.nodes[1].getnewaddress(), 1)
tx = self.nodes[2].sendtoaddress(self.nodes[1].getnewaddress(), 0.02)
block1, block2 = self.nodes[2].generate(2)
self.sync_all()
# We should be able to get the raw transaction by providing the correct block
@ -251,11 +251,11 @@ class RawTransactionsTest(BitcoinTestFramework):
bal = self.nodes[2].getbalance()
# send 1.2 BTC to msig adr
txId = self.nodes[0].sendtoaddress(mSigObj, 1.2)
txId = self.nodes[0].sendtoaddress(mSigObj, 0.024)
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
assert_equal(self.nodes[2].getbalance(), bal+Decimal('1.20000000')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance
assert_equal(self.nodes[2].getbalance(), bal+Decimal('0.024')) #node2 has both keys of the 2of2 ms addr., tx should affect the balance
# 2of3 test from different nodes
@ -270,7 +270,7 @@ class RawTransactionsTest(BitcoinTestFramework):
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey'], addr3Obj['pubkey']])['address']
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
txId = self.nodes[0].sendtoaddress(mSigObj, 0.044)
decTx = self.nodes[0].gettransaction(txId)
rawTx = self.nodes[0].decoderawtransaction(decTx['hex'])
self.sync_all()
@ -285,13 +285,13 @@ class RawTransactionsTest(BitcoinTestFramework):
rawTx = self.nodes[0].decoderawtransaction(txDetails['hex'])
vout = False
for outpoint in rawTx['vout']:
if outpoint['value'] == Decimal('2.20000000'):
if outpoint['value'] == Decimal('0.044'):
vout = outpoint
break
bal = self.nodes[0].getbalance()
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "amount" : vout['value']}]
outputs = { self.nodes[0].getnewaddress() : 2.19 }
outputs = { self.nodes[0].getnewaddress() : 0.0438 }
rawTx = self.nodes[2].createrawtransaction(inputs, outputs)
rawTxPartialSigned = self.nodes[1].signrawtransactionwithwallet(rawTx, inputs)
assert_equal(rawTxPartialSigned['complete'], False) #node1 only has one key, can't comp. sign the tx
@ -303,7 +303,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
assert_equal(self.nodes[0].getbalance(), bal+Decimal('1')+Decimal('0.0438')) #block reward + tx
# 2of2 test for combining transactions
bal = self.nodes[2].getbalance()
@ -317,7 +317,7 @@ class RawTransactionsTest(BitcoinTestFramework):
mSigObj = self.nodes[2].addmultisigaddress(2, [addr1Obj['pubkey'], addr2Obj['pubkey']])['address']
mSigObjValid = self.nodes[2].getaddressinfo(mSigObj)
txId = self.nodes[0].sendtoaddress(mSigObj, 2.2)
txId = self.nodes[0].sendtoaddress(mSigObj, 0.044)
decTx = self.nodes[0].gettransaction(txId)
rawTx2 = self.nodes[0].decoderawtransaction(decTx['hex'])
self.sync_all()
@ -330,13 +330,13 @@ class RawTransactionsTest(BitcoinTestFramework):
rawTx2 = self.nodes[0].decoderawtransaction(txDetails['hex'])
vout = False
for outpoint in rawTx2['vout']:
if outpoint['value'] == Decimal('2.20000000'):
if outpoint['value'] == Decimal('0.044'):
vout = outpoint
break
bal = self.nodes[0].getbalance()
inputs = [{ "txid" : txId, "vout" : vout['n'], "scriptPubKey" : vout['scriptPubKey']['hex'], "redeemScript" : mSigObjValid['hex'], "amount" : vout['value']}]
outputs = { self.nodes[0].getnewaddress() : 2.19 }
outputs = { self.nodes[0].getnewaddress() : 0.0438 }
rawTx2 = self.nodes[2].createrawtransaction(inputs, outputs)
rawTxPartialSigned1 = self.nodes[1].signrawtransactionwithwallet(rawTx2, inputs)
self.log.debug(rawTxPartialSigned1)
@ -352,7 +352,7 @@ class RawTransactionsTest(BitcoinTestFramework):
self.sync_all()
self.nodes[0].generate(1)
self.sync_all()
assert_equal(self.nodes[0].getbalance(), bal+Decimal('50.00000000')+Decimal('2.19000000')) #block reward + tx
assert_equal(self.nodes[0].getbalance(), bal+Decimal('1')+Decimal('0.0438')) #block reward + tx
# decoderawtransaction tests
# witness transaction
@ -393,23 +393,23 @@ class RawTransactionsTest(BitcoinTestFramework):
assert_raises_rpc_error(-1, "not a boolean", self.nodes[0].getrawtransaction, txHash, {})
inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 1000}]
outputs = { self.nodes[0].getnewaddress() : 1 }
outputs = { self.nodes[0].getnewaddress() : 0.02 }
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
decrawtx= self.nodes[0].decoderawtransaction(rawtx)
assert_equal(decrawtx['vin'][0]['sequence'], 1000)
# 9. invalid parameters - sequence number out of range
inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : -1}]
outputs = { self.nodes[0].getnewaddress() : 1 }
outputs = { self.nodes[0].getnewaddress() : 0.02 }
assert_raises_rpc_error(-8, 'Invalid parameter, sequence number is out of range', self.nodes[0].createrawtransaction, inputs, outputs)
# 10. invalid parameters - sequence number out of range
inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967296}]
outputs = { self.nodes[0].getnewaddress() : 1 }
outputs = { self.nodes[0].getnewaddress() : 0.02}
assert_raises_rpc_error(-8, 'Invalid parameter, sequence number is out of range', self.nodes[0].createrawtransaction, inputs, outputs)
inputs = [ {'txid' : "1d1d4e24ed99057e84c3f80fd8fbec79ed9e1acee37da269356ecea000000000", 'vout' : 1, 'sequence' : 4294967294}]
outputs = { self.nodes[0].getnewaddress() : 1 }
outputs = { self.nodes[0].getnewaddress() : 0.02 }
rawtx = self.nodes[0].createrawtransaction(inputs, outputs)
decrawtx= self.nodes[0].decoderawtransaction(rawtx)
assert_equal(decrawtx['vin'][0]['sequence'], 4294967294)

View file

@ -28,23 +28,23 @@ class ScantxoutsetTest(BitcoinTestFramework):
pubk2 = self.nodes[0].getaddressinfo(addr_LEGACY)['pubkey']
addr_BECH32 = self.nodes[0].getnewaddress("", "bech32")
pubk3 = self.nodes[0].getaddressinfo(addr_BECH32)['pubkey']
self.nodes[0].sendtoaddress(addr_P2SH_SEGWIT, 0.001)
self.nodes[0].sendtoaddress(addr_LEGACY, 0.002)
self.nodes[0].sendtoaddress(addr_BECH32, 0.004)
self.nodes[0].sendtoaddress(addr_P2SH_SEGWIT, 0.00002)
self.nodes[0].sendtoaddress(addr_LEGACY, 0.00004)
self.nodes[0].sendtoaddress(addr_BECH32, 0.00008)
#send to child keys of tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK
self.nodes[0].sendtoaddress("mkHV1C6JLheLoUSSZYk7x3FH5tnx9bu7yc", 0.008) # (m/0'/0'/0')
self.nodes[0].sendtoaddress("mipUSRmJAj2KrjSvsPQtnP8ynUon7FhpCR", 0.016) # (m/0'/0'/1')
self.nodes[0].sendtoaddress("n37dAGe6Mq1HGM9t4b6rFEEsDGq7Fcgfqg", 0.032) # (m/0'/0'/1500')
self.nodes[0].sendtoaddress("mqS9Rpg8nNLAzxFExsgFLCnzHBsoQ3PRM6", 0.064) # (m/0'/0'/0)
self.nodes[0].sendtoaddress("mnTg5gVWr3rbhHaKjJv7EEEc76ZqHgSj4S", 0.128) # (m/0'/0'/1)
self.nodes[0].sendtoaddress("mketCd6B9U9Uee1iCsppDJJBHfvi6U6ukC", 0.256) # (m/0'/0'/1500)
self.nodes[0].sendtoaddress("mj8zFzrbBcdaWXowCQ1oPZ4qioBVzLzAp7", 0.512) # (m/1/1/0')
self.nodes[0].sendtoaddress("mfnKpKQEftniaoE1iXuMMePQU3PUpcNisA", 1.024) # (m/1/1/1')
self.nodes[0].sendtoaddress("mou6cB1kaP1nNJM1sryW6YRwnd4shTbXYQ", 2.048) # (m/1/1/1500')
self.nodes[0].sendtoaddress("mtfUoUax9L4tzXARpw1oTGxWyoogp52KhJ", 4.096) # (m/1/1/0)
self.nodes[0].sendtoaddress("mxp7w7j8S1Aq6L8StS2PqVvtt4HGxXEvdy", 8.192) # (m/1/1/1)
self.nodes[0].sendtoaddress("mpQ8rokAhp1TAtJQR6F6TaUmjAWkAWYYBq", 16.384) # (m/1/1/1500)
self.nodes[0].sendtoaddress("mkHV1C6JLheLoUSSZYk7x3FH5tnx9bu7yc", 0.00016) # (m/0'/0'/0')
self.nodes[0].sendtoaddress("mipUSRmJAj2KrjSvsPQtnP8ynUon7FhpCR", 0.00032) # (m/0'/0'/1')
self.nodes[0].sendtoaddress("n37dAGe6Mq1HGM9t4b6rFEEsDGq7Fcgfqg", 0.00064) # (m/0'/0'/1500')
self.nodes[0].sendtoaddress("mqS9Rpg8nNLAzxFExsgFLCnzHBsoQ3PRM6", 0.00128) # (m/0'/0'/0)
self.nodes[0].sendtoaddress("mnTg5gVWr3rbhHaKjJv7EEEc76ZqHgSj4S", 0.00256) # (m/0'/0'/1)
self.nodes[0].sendtoaddress("mketCd6B9U9Uee1iCsppDJJBHfvi6U6ukC", 0.00512) # (m/0'/0'/1500)
self.nodes[0].sendtoaddress("mj8zFzrbBcdaWXowCQ1oPZ4qioBVzLzAp7", 0.01024) # (m/1/1/0')
self.nodes[0].sendtoaddress("mfnKpKQEftniaoE1iXuMMePQU3PUpcNisA", 0.02048) # (m/1/1/1')
self.nodes[0].sendtoaddress("mou6cB1kaP1nNJM1sryW6YRwnd4shTbXYQ", 0.04096) # (m/1/1/1500')
self.nodes[0].sendtoaddress("mtfUoUax9L4tzXARpw1oTGxWyoogp52KhJ", 0.08192) # (m/1/1/0)
self.nodes[0].sendtoaddress("mxp7w7j8S1Aq6L8StS2PqVvtt4HGxXEvdy", 0.16384) # (m/1/1/1)
self.nodes[0].sendtoaddress("mpQ8rokAhp1TAtJQR6F6TaUmjAWkAWYYBq", 0.32768) # (m/1/1/1500)
self.nodes[0].generate(1)
@ -57,39 +57,39 @@ class ScantxoutsetTest(BitcoinTestFramework):
self.restart_node(0, ['-nowallet'])
self.log.info("Test if we have found the non HD unspent outputs.")
assert_equal(self.nodes[0].scantxoutset("start", [ "pkh(" + pubk1 + ")", "pkh(" + pubk2 + ")", "pkh(" + pubk3 + ")"])['total_amount'], Decimal("0.002"))
assert_equal(self.nodes[0].scantxoutset("start", [ "wpkh(" + pubk1 + ")", "wpkh(" + pubk2 + ")", "wpkh(" + pubk3 + ")"])['total_amount'], Decimal("0.004"))
assert_equal(self.nodes[0].scantxoutset("start", [ "sh(wpkh(" + pubk1 + "))", "sh(wpkh(" + pubk2 + "))", "sh(wpkh(" + pubk3 + "))"])['total_amount'], Decimal("0.001"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(" + pubk1 + ")", "combo(" + pubk2 + ")", "combo(" + pubk3 + ")"])['total_amount'], Decimal("0.007"))
assert_equal(self.nodes[0].scantxoutset("start", [ "addr(" + addr_P2SH_SEGWIT + ")", "addr(" + addr_LEGACY + ")", "addr(" + addr_BECH32 + ")"])['total_amount'], Decimal("0.007"))
assert_equal(self.nodes[0].scantxoutset("start", [ "addr(" + addr_P2SH_SEGWIT + ")", "addr(" + addr_LEGACY + ")", "combo(" + pubk3 + ")"])['total_amount'], Decimal("0.007"))
assert_equal(self.nodes[0].scantxoutset("start", [ "pkh(" + pubk1 + ")", "pkh(" + pubk2 + ")", "pkh(" + pubk3 + ")"])['total_amount'], Decimal("0.00004"))
assert_equal(self.nodes[0].scantxoutset("start", [ "wpkh(" + pubk1 + ")", "wpkh(" + pubk2 + ")", "wpkh(" + pubk3 + ")"])['total_amount'], Decimal("0.00008"))
assert_equal(self.nodes[0].scantxoutset("start", [ "sh(wpkh(" + pubk1 + "))", "sh(wpkh(" + pubk2 + "))", "sh(wpkh(" + pubk3 + "))"])['total_amount'], Decimal("0.00002"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(" + pubk1 + ")", "combo(" + pubk2 + ")", "combo(" + pubk3 + ")"])['total_amount'], Decimal("0.00014"))
assert_equal(self.nodes[0].scantxoutset("start", [ "addr(" + addr_P2SH_SEGWIT + ")", "addr(" + addr_LEGACY + ")", "addr(" + addr_BECH32 + ")"])['total_amount'], Decimal("0.00014"))
assert_equal(self.nodes[0].scantxoutset("start", [ "addr(" + addr_P2SH_SEGWIT + ")", "addr(" + addr_LEGACY + ")", "combo(" + pubk3 + ")"])['total_amount'], Decimal("0.00014"))
self.log.info("Test extended key derivation.")
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0h/0h)"])['total_amount'], Decimal("0.008"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0'/1h)"])['total_amount'], Decimal("0.016"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0'/1500')"])['total_amount'], Decimal("0.032"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0h/0)"])['total_amount'], Decimal("0.064"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0h/1)"])['total_amount'], Decimal("0.128"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0'/1500)"])['total_amount'], Decimal("0.256"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0h/*h)", "range": 1499}])['total_amount'], Decimal("0.024"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0'/*h)", "range": 1500}])['total_amount'], Decimal("0.056"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0'/*)", "range": 1499}])['total_amount'], Decimal("0.192"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0h/*)", "range": 1500}])['total_amount'], Decimal("0.448"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0')"])['total_amount'], Decimal("0.512"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1')"])['total_amount'], Decimal("1.024"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1500h)"])['total_amount'], Decimal("2.048"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)"])['total_amount'], Decimal("4.096"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1)"])['total_amount'], Decimal("8.192"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1500)"])['total_amount'], Decimal("16.384"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/0)"])['total_amount'], Decimal("4.096"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/1)"])['total_amount'], Decimal("8.192"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/1500)"])['total_amount'], Decimal("16.384"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*')", "range": 1499}])['total_amount'], Decimal("1.536"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*')", "range": 1500}])['total_amount'], Decimal("3.584"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)", "range": 1499}])['total_amount'], Decimal("12.288"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)", "range": 1500}])['total_amount'], Decimal("28.672"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*)", "range": 1499}])['total_amount'], Decimal("12.288"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*)", "range": 1500}])['total_amount'], Decimal("28.672"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0h/0h)"])['total_amount'], Decimal("0.00016"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0'/1h)"])['total_amount'], Decimal("0.00032"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0'/1500')"])['total_amount'], Decimal("0.00064"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0h/0)"])['total_amount'], Decimal("0.00128"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0h/1)"])['total_amount'], Decimal("0.00256"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0'/1500)"])['total_amount'], Decimal("0.00512"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0h/*h)", "range": 1499}])['total_amount'], Decimal("0.00048"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0'/*h)", "range": 1500}])['total_amount'], Decimal("0.00112"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0h/0'/*)", "range": 1499}])['total_amount'], Decimal("0.00384"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/0'/0h/*)", "range": 1500}])['total_amount'], Decimal("0.00896"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0')"])['total_amount'], Decimal("0.01024"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1')"])['total_amount'], Decimal("0.02048"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1500h)"])['total_amount'], Decimal("0.04096"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/0)"])['total_amount'], Decimal("0.08192"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1)"])['total_amount'], Decimal("0.16384"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/1500)"])['total_amount'], Decimal("0.32768"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/0)"])['total_amount'], Decimal("0.08192"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/1)"])['total_amount'], Decimal("0.16384"))
assert_equal(self.nodes[0].scantxoutset("start", [ "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/1500)"])['total_amount'], Decimal("0.32768"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*')", "range": 1499}])['total_amount'], Decimal("0.03072"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*')", "range": 1500}])['total_amount'], Decimal("0.07168"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)", "range": 1499}])['total_amount'], Decimal("0.24576"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tprv8ZgxMBicQKsPd7Uf69XL1XwhmjHopUGep8GuEiJDZmbQz6o58LninorQAfcKZWARbtRtfnLcJ5MQ2AtHcQJCCRUcMRvmDUjyEmNUWwx8UbK/1/1/*)", "range": 1500}])['total_amount'], Decimal("0.57344"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*)", "range": 1499}])['total_amount'], Decimal("0.24576"))
assert_equal(self.nodes[0].scantxoutset("start", [ {"desc": "combo(tpubD6NzVbkrYhZ4WaWSyoBvQwbpLkojyoTZPRsgXELWz3Popb3qkjcJyJUGLnL4qHHoQvao8ESaAstxYSnhyswJ76uZPStJRJCTKvosUCJZL5B/1/1/*)", "range": 1500}])['total_amount'], Decimal("0.57344"))
if __name__ == '__main__':
ScantxoutsetTest().main()

View file

@ -22,7 +22,7 @@ class SignMessagesTest(BitcoinTestFramework):
self.log.info('test signing with priv_key')
priv_key = 'cUeKHd5orzT3mz8P9pxyREHfsWtVfgsfDjiZZBcjUBAaGk1BTj7N'
address = 'mpLQjfK79b7CCV4VMJWEWAj5Mpx8Up5zxB'
expected_signature = 'INbVnW4e6PeRmsv2Qgu8NuopvrVjkcxob+sX8OcZG0SALhWybUjzMLPdAsXI46YZGb0KQTRii+wWIQzRpG/U+S0='
expected_signature = 'H4fEJyZBIV1i3E/oVyaf11SyA2Qufqe7WcyYQpaTW6xWZ7K0CWZX3Qx63cDxuM5kYXjg0vzzbkPWgAj5dONEDTc='
signature = self.nodes[0].signmessagewithprivkey(priv_key, message)
assert_equal(expected_signature, signature)
assert(self.nodes[0].verifymessage(address, signature, message))

Some files were not shown because too many files have changed in this diff Show more