Compare commits
6 commits
master
...
add_signat
Author | SHA1 | Date | |
---|---|---|---|
|
afe3eec551 | ||
|
eb810178e5 | ||
|
30f8402629 | ||
|
50f32d0e66 | ||
|
6697207ac1 | ||
|
92a3df1571 |
132 changed files with 1477 additions and 5144 deletions
8
.github/ISSUE_TEMPLATE.md
vendored
8
.github/ISSUE_TEMPLATE.md
vendored
|
@ -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)? -->
|
||||
|
||||
|
|
25
.travis.yml
25
.travis.yml
|
@ -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
113
README.md
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/])
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}"
|
||||
|
|
|
@ -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.
|
|
@ -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}"
|
||||
|
|
|
@ -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
|
@ -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
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -27,5 +27,4 @@ define $(package)_stage_cmds
|
|||
endef
|
||||
|
||||
define $(package)_postprocess_cmds
|
||||
rm lib/*.la
|
||||
endef
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
12
src/init.cpp
12
src/init.cpp
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
|
@ -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
14
test/functional/feature_block.py
Executable file → Normal 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)
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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'}],
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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])
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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",[])]
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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
Loading…
Reference in a new issue