Merge branch 'master' into rustfmt
Conflicts: ethash/src/sizes.rs util/src/uint.rs
This commit is contained in:
commit
a0db1d5416
4
.gitignore
vendored
4
.gitignore
vendored
@ -26,3 +26,7 @@
|
|||||||
|
|
||||||
# jetbrains ide stuff
|
# jetbrains ide stuff
|
||||||
.idea
|
.idea
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# Build artifacts
|
||||||
|
out/
|
||||||
|
75
.travis.yml
75
.travis.yml
@ -8,56 +8,79 @@ branches:
|
|||||||
- /^stable-.*$/
|
- /^stable-.*$/
|
||||||
- /^beta$/
|
- /^beta$/
|
||||||
- /^stable$/
|
- /^stable$/
|
||||||
|
git:
|
||||||
|
depth: 3
|
||||||
matrix:
|
matrix:
|
||||||
fast_finish: true
|
fast_finish: true
|
||||||
include:
|
allow_failures:
|
||||||
- rust: nightly
|
- rust: nightly
|
||||||
env: FEATURES="--features ethcore/json-tests" KCOV_FEATURES="" TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity" ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}"
|
include:
|
||||||
|
- rust: stable
|
||||||
|
env: FEATURES="--features travis-beta" RUN_TESTS="true"
|
||||||
|
# - rust: beta
|
||||||
|
# env: FEATURES="--features travis-beta" RUN_TESTS="true"
|
||||||
|
- rust: stable
|
||||||
|
env: FEATURES="--features travis-beta" RUN_BUILD="true"
|
||||||
|
- rust: beta
|
||||||
|
env: FEATURES="--features travis-beta" RUN_BUILD="true"
|
||||||
|
- rust: stable
|
||||||
|
env: FEATURES="--features travis-beta" RUN_COVERAGE="true"
|
||||||
|
# - rust: nightly
|
||||||
|
# env: FEATURES="--features travis-nightly" RUN_BENCHES="true"
|
||||||
|
- rust: nightly
|
||||||
|
env: FEATURES="--features travis-nightly" RUN_TESTS="true"
|
||||||
|
env:
|
||||||
|
global:
|
||||||
|
# GH_TOKEN
|
||||||
|
- secure: bumJASbZSU8bxJ0EyPUJmu16AiV9EXOpyOj86Jlq/Ty9CfwGqsSXt96uDyE+OUJf34RUFQMsw0nk37/zC4lcn6kqk2wpuH3N/o85Zo/cVZY/NusBWLQqtT5VbYWsV+u2Ua4Tmmsw8yVYQhYwU2ZOejNpflL+Cs9XGgORp1L+/gMRMC2y5Se6ZhwnKPQlRJ8LGsG1dzjQULxzADIt3/zuspNBS8a2urJwlHfGMkvHDoUWCviP/GXoSqw3TZR7FmKyxE19I8n9+iSvm9+oZZquvcgfUxMHn8Gq/b44UbPvjtFOg2yam4xdWXF/RyWCHdc/R9EHorSABeCbefIsm+zcUF3/YQxwpSxM4IZEeH2rTiC7dcrsKw3XsO16xFQz5YI5Bay+CT/wTdMmJd7DdYz7Dyf+pOvcM9WOf/zorxYWSBOMYy0uzbusU2iyIghQ82s7E/Ahg+WARtPgkuTLSB5aL1oCTBKHqQscMr7lo5Ti6RpWLxEdTQMBznc+bMr+6dEtkEcG9zqc6cE9XX+ox3wTU6+HVMfQ1ltCntJ4UKcw3A6INEbw9wgocQa812CIASQ2fE+SCAbz6JxBjIAlFUnD1lUB7S8PdMPwn9plfQgKQ2A5YZqg6FnBdf0rQXIJYxQWKHXj/rBHSUCT0tHACDlzTA+EwWggvkP5AGIxRxm8jhw=
|
||||||
|
- TARGETS="-p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethminer -p ethjson"
|
||||||
|
- ARCHIVE_SUFFIX="-${TRAVIS_OS_NAME}-${TRAVIS_TAG}"
|
||||||
|
- KCOV_FEATURES=""
|
||||||
|
- KCOV_CMD="./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /usr/,/.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests target/kcov"
|
||||||
|
- RUN_TESTS="false"
|
||||||
|
- RUN_COVERAGE="false"
|
||||||
|
- RUN_BUILD="false"
|
||||||
|
- RUN_BENCHES="false"
|
||||||
|
- RUST_BACKTRACE="1"
|
||||||
cache:
|
cache:
|
||||||
apt: true
|
apt: true
|
||||||
directories:
|
directories:
|
||||||
- target/debug/deps
|
- $TRAVIS_BUILD_DIR/target
|
||||||
- target/debug/build
|
- $HOME/.cargo
|
||||||
- target/release/deps
|
|
||||||
- target/release/build
|
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
packages:
|
packages:
|
||||||
- libcurl4-openssl-dev
|
- libcurl4-openssl-dev
|
||||||
- libelf-dev
|
- libelf-dev
|
||||||
- libdw-dev
|
- libdw-dev
|
||||||
before_script: |
|
|
||||||
sudo add-apt-repository "deb http://ppa.launchpad.net/giskou/librocksdb/ubuntu trusty main" &&
|
|
||||||
sudo apt-get update &&
|
|
||||||
sudo apt-get install -y --force-yes librocksdb
|
|
||||||
script:
|
script:
|
||||||
- cargo build --release --verbose ${FEATURES}
|
- if [ "$RUN_TESTS" = "true" ]; then cargo test --release --verbose ${FEATURES} ${TARGETS}; fi
|
||||||
- cargo test --release --verbose ${FEATURES} ${TARGETS}
|
- if [ "$RUN_BENCHES" = "true" ]; then cargo bench --no-run ${FEATURES} ${TARGETS}; fi
|
||||||
- cargo bench --no-run ${FEATURES} ${TARGETS}
|
- if [ "$RUN_BUILD" = "true" ]; then cargo build --release --verbose ${FEATURES}; fi
|
||||||
- tar cvzf parity${ARCHIVE_SUFFIX}.tar.gz -C target/release parity
|
- if [ "$RUN_BUILD" = "true" ]; then tar cvzf parity${ARCHIVE_SUFFIX}.tar.gz -C target/release parity; fi
|
||||||
|
|
||||||
after_success: |
|
after_success: |
|
||||||
|
[ "$RUN_COVERAGE" = "true" ] &&
|
||||||
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
|
wget https://github.com/SimonKagstrom/kcov/archive/master.tar.gz &&
|
||||||
tar xzf master.tar.gz && mkdir kcov-master/build && cd kcov-master/build && cmake .. && make && make install DESTDIR=../tmp && cd ../.. &&
|
tar xzf master.tar.gz && mkdir kcov-master/build && cd kcov-master/build && cmake .. && make && make install DESTDIR=../tmp && cd ../.. &&
|
||||||
cargo test --no-run ${KCOV_FEATURES} ${TARGETS} &&
|
cargo test --no-run ${KCOV_FEATURES} ${TARGETS} &&
|
||||||
./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests target/kcov target/debug/deps/ethcore_util-* &&
|
$KCOV_CMD target/debug/deps/ethcore_util-* &&
|
||||||
./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests target/kcov target/debug/deps/ethash-* &&
|
$KCOV_CMD target/debug/deps/ethash-* &&
|
||||||
./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests target/kcov target/debug/deps/ethcore-* &&
|
$KCOV_CMD target/debug/deps/ethcore-* &&
|
||||||
./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests target/kcov target/debug/deps/ethsync-* &&
|
$KCOV_CMD target/debug/deps/ethsync-* &&
|
||||||
./kcov-master/tmp/usr/local/bin/kcov --exclude-pattern /.cargo,/root/.multirust,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests target/kcov target/debug/deps/ethcore_rpc-* &&
|
$KCOV_CMD target/debug/deps/ethcore_rpc-* &&
|
||||||
./kcov-master/tmp/usr/local/bin/kcov --coveralls-id=${TRAVIS_JOB_ID} --exclude-pattern /.cargo,/root/.multirust target/kcov target/debug/parity-* &&
|
$KCOV_CMD target/debug/deps/ethminer-* &&
|
||||||
|
$KCOV_CMD target/debug/deps/ethjson-* &&
|
||||||
|
$KCOV_CMD target/debug/parity-* &&
|
||||||
[ $TRAVIS_BRANCH = master ] &&
|
[ $TRAVIS_BRANCH = master ] &&
|
||||||
[ $TRAVIS_PULL_REQUEST = false ] &&
|
[ $TRAVIS_PULL_REQUEST = false ] &&
|
||||||
[ $TRAVIS_RUST_VERSION = nightly ] &&
|
[ $TRAVIS_RUST_VERSION = stable ] &&
|
||||||
cargo doc --no-deps --verbose ${KCOV_FEATURES} ${TARGETS} &&
|
cargo doc --no-deps --verbose ${KCOV_FEATURES} ${TARGETS} &&
|
||||||
echo '<meta http-equiv=refresh content=0;url=ethcore/index.html>' > target/doc/index.html &&
|
echo '<meta http-equiv=refresh content=0;url=ethcore/index.html>' > target/doc/index.html &&
|
||||||
pip install --user ghp-import &&
|
pip install --user ghp-import &&
|
||||||
/home/travis/.local/bin/ghp-import -n target/doc &&
|
/home/travis/.local/bin/ghp-import -n target/doc &&
|
||||||
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
|
git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages
|
||||||
env:
|
|
||||||
global:
|
|
||||||
- secure: 3sUjNi9mhdL5h1GTm8LONnDN/SYvUHT+WSkMl93h3nYiLCQXk8eZaPS98AS7oOaTsfW4UvnwckVFCFl49ttInsv4cd/TkAxmrJHe6kPyS9/4NWUdmP8BjicbBvL/ioSdXMECMEYzPDLV+I3KhtC2LcB6ceDEl/XwMOJlzbGf7RbtcXGVQgMLqSYY1YKjQA4vbT5nFgIS/sZu3Z9yFgN0GafnihKcizqoHhdJjs/zxmX+qJepnC6o3V6KcFnS7QHhM1JOr85twE6S422UlvNaEb5ovwLPqmOl5+fA+6shbx4AxFTY6E9Iors+OVY/JliFhrqOdCt0i2P1FUHN4kbGZQkf0rphN/ZOI2uKNFTOyXiPvppfo/ZemKmcqkwkqP9+lf5QqYmtE6hsAYagxn49xJZILl8tAYbdqxF5gxa+TEVrfsBFtz/Sv3q8QhKQNPAmjEcKyMatyEreLUIFEpFTGIco8jN4eXeSoLRdJ+Z75ihttfQWhNfUDgNL30iQLy0AgFSsh/cyb5M8y9lxrGDzDTogvaiKGwr/V45sPkcXWCkmOgMdINqBB6ZtdL3bGHdyjmYj+y3btjf3aP11k++BL0fXIaKn25aS/p/9iyGb1FyGCM03o4ZRQ3YhTOvfMRfRGf6nWbaMx9upv8o5ShSdysewhrnh3082r7u896ny1Ho=
|
|
||||||
- secure: 0/FeVvFl3AhBW0TCPoujY9zOAYoUNMlAz3XjC04vlc4Ksfx0lGU3KFi97LlALxMWV0lfwQc7ixSe2vTgQVQuLVSU9XEW40fQgEjJlmLca2RcRx1kfzJDypuWSiCME7MWmLPH0ac4COdTDS1z5WGggv5YB7GQPCzFvcmOOaPYtF29ngCtkyB2HmNkY/W3omHFEk7Si6bsmOSHZiOAhivPl6ixnGpFyTEKPyraMMqPIj5rbEGkzgeLTiXf2ur143n/tnSr8tmP1MfQi9yS8/ONidMqnxUeuLkeNnb82zj9pVJhVXq0xF44WXJ8Za1jm0ByiTakgqpm8Juk822qjvtNulJ1XZW/fyZQZaN1dy3uq5Ud3W8wS9M7VIVl8CoXozzDpIsdPeUAtkAxeHBsZqL1vAH2yC1YJA7HPySMYzCjYqkJ2r62xYk0gXmNXphfU+F/X/rHzHsTMJPONJ54HQwu12m7zVlKIYBGHgEXg/HAM/g4ljUzl6WWR/nHH/tQM8ND/8FpHluJSZJWacq/1QNhVdTq2x6cqws2fs5A7nVpccR9+6RRgYgv6+YS2LxvFzByuZveGGoKif+uMECXN876j40araUqU528Yz9i8bHJlnM3coRBndaLNWByLcUyXCB9r9IUosUu41rr+L2mVzkSDm0GicuNCzqvzYQ9Q6QY4uQ=
|
|
||||||
- secure: DglvLR27MrBKQO/8s7ZfGqfimXk1Iq5MreCTc+ZkWMkZ0sDP76YBUPq5j25hcg0Z09z09O2Q5OUOyYkhVD4AnRjoRLUplHdpDE9CBSz2vUGpMpzhgAqzBc6SDsEmWU2JlAPBraIODXQdP/Qo6tYY4zn3vwd/VFKo27GTb5b60WAkTVvT/0YPWycEXFIa7sNMgjNI0EnT+Se5USDYwb6MM1T9JxJot0q3WtOnsVyroCHJp4QDicpS8eQIu3Tl+SLE4d0EoJ4YYLOI+jWOybipuO1xM1xlHq/gpWfjKqbJh24xtAds524dN7ujfjAhyO2zQbuTOfi7QVOj/Go0tGYxNxobR4pYG783Aiq3Quj0GzSrLEAatkk5tGOcuVJ98EYIg3WPJuC93waTTXcS0xDyy09XHxWxZ/5PiXorRZjpHvnZfRF0X4Mus6jUJ7hqDuOUiF5BI1RHomHvJQQHUrLdmh7OHyrer3YUpKRs65tww6H+VM+lKNa3MnMkB5+or/co14svs7I4pni9S+aZg//bwuxGVXchK6bjLCP1X99Ar4fA5EGsTVdjp3PRqutM/P3RqNGkwTczat/PNZ8fFAD9y7pDs2L6YkqpflTC9d6vKTSl6gORGw6ltLUJs23ON6xRNIBMw1cXp67wN57vF46TPt1i3ZlIQsYn0pAVNKavbZE=
|
|
||||||
|
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
# Contributing to Parity
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
By contributing to Parity, you agree that your contributions will be
|
|
||||||
licensed under the [BSD License](LICENSE).
|
|
||||||
|
|
||||||
At the top of every source code file you alter, after the initial
|
|
||||||
licence section, please append a second section that reads:
|
|
||||||
|
|
||||||
Portions contributed by YOUR NAME are hereby placed under the BSD licence.
|
|
||||||
|
|
579
Cargo.lock
generated
579
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
32
Cargo.toml
32
Cargo.toml
@ -1,29 +1,45 @@
|
|||||||
[package]
|
[package]
|
||||||
description = "Ethcore client."
|
description = "Ethcore client."
|
||||||
name = "parity"
|
name = "parity"
|
||||||
version = "0.9.0"
|
version = "1.1.0"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
authors = ["Ethcore <admin@ethcore.io>"]
|
authors = ["Ethcore <admin@ethcore.io>"]
|
||||||
|
build = "build.rs"
|
||||||
|
|
||||||
|
[build-dependencies]
|
||||||
|
rustc_version = "0.1"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
docopt = "0.6"
|
docopt = "0.6"
|
||||||
docopt_macros = "0.6"
|
time = "0.1"
|
||||||
ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" }
|
ctrlc = { git = "https://github.com/tomusdrw/rust-ctrlc.git" }
|
||||||
clippy = "0.0.41"
|
|
||||||
ethcore-util = { path = "util" }
|
|
||||||
ethcore = { path = "ethcore" }
|
|
||||||
ethsync = { path = "sync" }
|
|
||||||
ethcore-rpc = { path = "rpc", optional = true }
|
|
||||||
fdlimit = { path = "util/fdlimit" }
|
fdlimit = { path = "util/fdlimit" }
|
||||||
target_info = "0.1"
|
daemonize = "0.2"
|
||||||
|
num_cpus = "0.2"
|
||||||
|
number_prefix = "0.2"
|
||||||
|
rpassword = "0.1"
|
||||||
|
clippy = { version = "0.0.54", optional = true }
|
||||||
|
ethcore = { path = "ethcore" }
|
||||||
|
ethcore-util = { path = "util" }
|
||||||
|
ethsync = { path = "sync" }
|
||||||
|
ethminer = { path = "miner" }
|
||||||
|
ethcore-devtools = { path = "devtools" }
|
||||||
|
ethcore-rpc = { path = "rpc", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["rpc"]
|
default = ["rpc"]
|
||||||
rpc = ["ethcore-rpc"]
|
rpc = ["ethcore-rpc"]
|
||||||
|
dev = ["clippy", "ethcore/dev", "ethcore-util/dev", "ethsync/dev", "ethcore-rpc/dev", "ethminer/dev"]
|
||||||
|
travis-beta = ["ethcore/json-tests"]
|
||||||
|
travis-nightly = ["ethcore/json-tests", "dev"]
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
path = "parity/main.rs"
|
path = "parity/main.rs"
|
||||||
name = "parity"
|
name = "parity"
|
||||||
|
|
||||||
|
[profile.release]
|
||||||
|
debug = false
|
||||||
|
lto = false
|
||||||
|
63
README.md
63
README.md
@ -1,6 +1,6 @@
|
|||||||
# ethcore
|
# ethcore
|
||||||
|
|
||||||
[![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Join the chat at https://gitter.im/trogdoro/xiki][gitter-image]][gitter-url]
|
[![Build Status][travis-image]][travis-url] [![Coverage Status][coveralls-image]][coveralls-url] [![Join the chat at https://gitter.im/trogdoro/xiki][gitter-image]][gitter-url] [![GPLv3][license-image]][license-url]
|
||||||
|
|
||||||
[travis-image]: https://travis-ci.org/ethcore/parity.svg?branch=master
|
[travis-image]: https://travis-ci.org/ethcore/parity.svg?branch=master
|
||||||
[travis-url]: https://travis-ci.org/ethcore/parity
|
[travis-url]: https://travis-ci.org/ethcore/parity
|
||||||
@ -8,70 +8,33 @@
|
|||||||
[coveralls-url]: https://coveralls.io/github/ethcore/parity?branch=master
|
[coveralls-url]: https://coveralls.io/github/ethcore/parity?branch=master
|
||||||
[gitter-image]: https://badges.gitter.im/Join%20Chat.svg
|
[gitter-image]: https://badges.gitter.im/Join%20Chat.svg
|
||||||
[gitter-url]: https://gitter.im/ethcore/parity?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
[gitter-url]: https://gitter.im/ethcore/parity?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge
|
||||||
|
[license-image]: https://img.shields.io/badge/license-GPL%20v3-green.svg
|
||||||
|
[license-url]: http://www.gnu.org/licenses/gpl-3.0.en.html
|
||||||
|
|
||||||
[Documentation](http://ethcore.github.io/parity/ethcore/index.html)
|
[Documentation](http://ethcore.github.io/parity/ethcore/index.html)
|
||||||
|
|
||||||
### Building from source
|
### Building from source
|
||||||
|
|
||||||
##### Ubuntu 14.04, 15.04, 15.10
|
First (if you don't already have it) get multirust:
|
||||||
|
|
||||||
|
- Linux:
|
||||||
```bash
|
```bash
|
||||||
# install rocksdb
|
curl -sf https://raw.githubusercontent.com/brson/multirust/master/quick-install.sh | sudo sh -s -- --yes
|
||||||
add-apt-repository ppa:ethcore/ethcore
|
|
||||||
apt-get update
|
|
||||||
apt-get install -y --force-yes librocksdb-dev
|
|
||||||
|
|
||||||
# install multirust
|
|
||||||
curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
|
||||||
|
|
||||||
# install nightly and make it default
|
|
||||||
multirust update nightly
|
|
||||||
multirust default nightly
|
|
||||||
|
|
||||||
# download and build parity
|
|
||||||
git clone https://github.com/ethcore/parity
|
|
||||||
cd parity
|
|
||||||
cargo build --release
|
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Other Linux
|
- OSX with Homebrew:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# install rocksdb
|
brew update && brew install multirust
|
||||||
git clone --tag v4.1 --depth=1 https://github.com/facebook/rocksdb.git
|
multirust default stable
|
||||||
cd rocksdb
|
|
||||||
make shared_lib
|
|
||||||
sudo cp -a librocksdb.so* /usr/lib
|
|
||||||
sudo ldconfig
|
|
||||||
cd ..
|
|
||||||
|
|
||||||
# install rust nightly
|
|
||||||
curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sudo sh -s -- --yes
|
|
||||||
|
|
||||||
# install nightly and make it default
|
|
||||||
sudo multirust update nightly
|
|
||||||
sudo multirust default nightly
|
|
||||||
|
|
||||||
# download and build parity
|
|
||||||
git clone https://github.com/ethcore/parity
|
|
||||||
cd parity
|
|
||||||
cargo build --release
|
|
||||||
```
|
```
|
||||||
|
|
||||||
##### OSX with Homebrew
|
Then, download and build Parity:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# install rocksdb && multirust
|
# download Parity code
|
||||||
brew update
|
|
||||||
brew install rocksdb
|
|
||||||
brew install multirust
|
|
||||||
|
|
||||||
# install nightly and make it default
|
|
||||||
multirust update nightly && multirust default nightly
|
|
||||||
|
|
||||||
# download and build parity
|
|
||||||
git clone https://github.com/ethcore/parity
|
git clone https://github.com/ethcore/parity
|
||||||
cd parity
|
cd parity
|
||||||
|
|
||||||
|
# build in release mode
|
||||||
cargo build --release
|
cargo build --release
|
||||||
```
|
```
|
||||||
|
|
||||||
|
25
build.rs
Normal file
25
build.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
extern crate rustc_version;
|
||||||
|
|
||||||
|
use rustc_version::{version_meta, Channel};
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
if let Channel::Nightly = version_meta().channel {
|
||||||
|
println!("cargo:rustc-cfg=nightly");
|
||||||
|
}
|
||||||
|
}
|
23
cov.sh
23
cov.sh
@ -15,12 +15,23 @@ if ! type kcov > /dev/null; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cargo test -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity --no-run || exit $?
|
cargo test \
|
||||||
|
-p ethash \
|
||||||
|
-p ethcore-util \
|
||||||
|
-p ethcore \
|
||||||
|
-p ethsync \
|
||||||
|
-p ethcore-rpc \
|
||||||
|
-p parity \
|
||||||
|
-p ethminer \
|
||||||
|
--no-run || exit $?
|
||||||
rm -rf target/coverage
|
rm -rf target/coverage
|
||||||
mkdir -p target/coverage
|
mkdir -p target/coverage
|
||||||
kcov --exclude-pattern ~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests --include-pattern src --verify target/coverage target/debug/deps/ethcore-*
|
|
||||||
kcov --exclude-pattern ~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests --include-pattern src --verify target/coverage target/debug/deps/ethash-*
|
EXCLUDE="~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests"
|
||||||
kcov --exclude-pattern ~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests --include-pattern src --verify target/coverage target/debug/deps/ethcore_util-*
|
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore-*
|
||||||
kcov --exclude-pattern ~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests --include-pattern src --verify target/coverage target/debug/deps/ethsync-*
|
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethash-*
|
||||||
kcov --exclude-pattern ~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests --include-pattern src --verify target/coverage target/debug/deps/ethcore_rpc-*
|
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_util-*
|
||||||
|
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethsync-*
|
||||||
|
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_rpc-*
|
||||||
|
kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethminer-*
|
||||||
xdg-open target/coverage/index.html
|
xdg-open target/coverage/index.html
|
||||||
|
16
devtools/Cargo.toml
Normal file
16
devtools/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
[package]
|
||||||
|
description = "Ethcore development/test/build tools"
|
||||||
|
homepage = "http://ethcore.io"
|
||||||
|
license = "GPL-3.0"
|
||||||
|
name = "ethcore-devtools"
|
||||||
|
version = "1.1.0"
|
||||||
|
authors = ["Ethcore <admin@ethcore.io>"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
rand = "0.3"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
path = "src/lib.rs"
|
||||||
|
test = true
|
1
devtools/README.md
Normal file
1
devtools/README.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
# ethcore dev tools
|
24
devtools/src/lib.rs
Normal file
24
devtools/src/lib.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! dev-tools
|
||||||
|
|
||||||
|
|
||||||
|
extern crate rand;
|
||||||
|
|
||||||
|
pub mod random_path;
|
||||||
|
|
||||||
|
pub use random_path::*;
|
89
devtools/src/random_path.rs
Normal file
89
devtools/src/random_path.rs
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Random path
|
||||||
|
|
||||||
|
use std::path::*;
|
||||||
|
use std::fs;
|
||||||
|
use std::env;
|
||||||
|
use rand::random;
|
||||||
|
|
||||||
|
pub struct RandomTempPath {
|
||||||
|
path: PathBuf
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn random_filename() -> String {
|
||||||
|
(0..8).map(|_| ((random::<f32>() * 26.0) as u8 + 97) as char).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RandomTempPath {
|
||||||
|
pub fn new() -> RandomTempPath {
|
||||||
|
let mut dir = env::temp_dir();
|
||||||
|
dir.push(random_filename());
|
||||||
|
RandomTempPath {
|
||||||
|
path: dir.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_dir() -> RandomTempPath {
|
||||||
|
let mut dir = env::temp_dir();
|
||||||
|
dir.push(random_filename());
|
||||||
|
fs::create_dir_all(dir.as_path()).unwrap();
|
||||||
|
RandomTempPath {
|
||||||
|
path: dir.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_path(&self) -> &PathBuf {
|
||||||
|
&self.path
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
self.path.to_str().unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for RandomTempPath {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
if let Err(e) = fs::remove_dir_all(self.as_path()) {
|
||||||
|
panic!("failed to remove temp directory, probably something failed to destroyed ({})", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn creates_dir() {
|
||||||
|
let temp = RandomTempPath::create_dir();
|
||||||
|
assert!(fs::metadata(temp.as_path()).unwrap().is_dir());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn destroys_dir() {
|
||||||
|
let path_buf = {
|
||||||
|
let temp = RandomTempPath::create_dir();
|
||||||
|
assert!(fs::metadata(temp.as_path()).unwrap().is_dir());
|
||||||
|
let path_buf = temp.as_path().to_path_buf();
|
||||||
|
path_buf
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(fs::metadata(&path_buf).is_err());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn provides_random() {
|
||||||
|
let temp = RandomTempPath::create_dir();
|
||||||
|
assert!(temp.as_path().to_str().is_some());
|
||||||
|
}
|
9
doc.sh
9
doc.sh
@ -1,4 +1,11 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# generate documentation only for partiy and ethcore libraries
|
# generate documentation only for partiy and ethcore libraries
|
||||||
|
|
||||||
cargo doc --no-deps --verbose -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity
|
cargo doc --no-deps --verbose \
|
||||||
|
-p ethash \
|
||||||
|
-p ethcore-util \
|
||||||
|
-p ethcore \
|
||||||
|
-p ethsync \
|
||||||
|
-p ethcore-rpc \
|
||||||
|
-p parity \
|
||||||
|
-p ethminer
|
||||||
|
@ -8,8 +8,8 @@ RUN apt-get update && \
|
|||||||
# add-apt-repository
|
# add-apt-repository
|
||||||
software-properties-common \
|
software-properties-common \
|
||||||
curl \
|
curl \
|
||||||
gcc \
|
g++ \
|
||||||
wget \
|
wget \
|
||||||
git \
|
git \
|
||||||
# evmjit dependencies
|
# evmjit dependencies
|
||||||
zlib1g-dev \
|
zlib1g-dev \
|
||||||
@ -18,9 +18,8 @@ RUN apt-get update && \
|
|||||||
# cmake, llvm and rocksdb ppas. then update ppas
|
# cmake, llvm and rocksdb ppas. then update ppas
|
||||||
RUN add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
|
RUN add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
|
||||||
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
|
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
|
||||||
add-apt-repository "deb http://ppa.launchpad.net/giskou/librocksdb/ubuntu trusty main" && \
|
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get install -y --force-yes cmake llvm-3.7-dev librocksdb
|
apt-get install -y --force-yes cmake llvm-3.7-dev
|
||||||
|
|
||||||
# install evmjit
|
# install evmjit
|
||||||
RUN git clone https://github.com/debris/evmjit && \
|
RUN git clone https://github.com/debris/evmjit && \
|
||||||
@ -31,9 +30,6 @@ RUN git clone https://github.com/debris/evmjit && \
|
|||||||
# install multirust
|
# install multirust
|
||||||
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
||||||
|
|
||||||
# install nightly and make it default
|
|
||||||
RUN multirust update nightly && multirust default nightly
|
|
||||||
|
|
||||||
# export rust LIBRARY_PATH
|
# export rust LIBRARY_PATH
|
||||||
ENV LIBRARY_PATH /usr/local/lib
|
ENV LIBRARY_PATH /usr/local/lib
|
||||||
|
|
||||||
|
@ -8,9 +8,9 @@ RUN apt-get update && \
|
|||||||
# add-apt-repository
|
# add-apt-repository
|
||||||
software-properties-common \
|
software-properties-common \
|
||||||
curl \
|
curl \
|
||||||
wget \
|
wget \
|
||||||
git \
|
git \
|
||||||
gcc \
|
g++ \
|
||||||
# evmjit dependencies
|
# evmjit dependencies
|
||||||
zlib1g-dev \
|
zlib1g-dev \
|
||||||
libedit-dev
|
libedit-dev
|
||||||
@ -18,9 +18,8 @@ RUN apt-get update && \
|
|||||||
# cmake, llvm and rocksdb ppas. then update ppas
|
# cmake, llvm and rocksdb ppas. then update ppas
|
||||||
RUN add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
|
RUN add-apt-repository -y "ppa:george-edison55/cmake-3.x" && \
|
||||||
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
|
add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \
|
||||||
add-apt-repository "deb http://ppa.launchpad.net/giskou/librocksdb/ubuntu trusty main" && \
|
|
||||||
apt-get update && \
|
apt-get update && \
|
||||||
apt-get install -y --force-yes cmake llvm-3.7-dev librocksdb
|
apt-get install -y --force-yes cmake llvm-3.7-dev
|
||||||
|
|
||||||
# install evmjit
|
# install evmjit
|
||||||
RUN git clone https://github.com/debris/evmjit && \
|
RUN git clone https://github.com/debris/evmjit && \
|
||||||
@ -31,9 +30,6 @@ RUN git clone https://github.com/debris/evmjit && \
|
|||||||
# install multirust
|
# install multirust
|
||||||
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
||||||
|
|
||||||
# install nightly and make it default
|
|
||||||
RUN multirust update nightly && multirust default nightly
|
|
||||||
|
|
||||||
# export rust LIBRARY_PATH
|
# export rust LIBRARY_PATH
|
||||||
ENV LIBRARY_PATH /usr/local/lib
|
ENV LIBRARY_PATH /usr/local/lib
|
||||||
|
|
||||||
@ -41,7 +37,6 @@ ENV LIBRARY_PATH /usr/local/lib
|
|||||||
ENV RUST_BACKTRACE 1
|
ENV RUST_BACKTRACE 1
|
||||||
|
|
||||||
# build parity
|
# build parity
|
||||||
# TODO: add jit feature
|
|
||||||
RUN git clone https://github.com/ethcore/parity && \
|
RUN git clone https://github.com/ethcore/parity && \
|
||||||
cd parity && \
|
cd parity && \
|
||||||
cargo install --features rpc
|
cargo build --release --features ethcore/jit
|
||||||
|
@ -3,23 +3,14 @@ FROM ubuntu:14.04
|
|||||||
# install tools and dependencies
|
# install tools and dependencies
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y \
|
apt-get install -y \
|
||||||
gcc \
|
g++ \
|
||||||
curl \
|
curl \
|
||||||
git \
|
git \
|
||||||
# add-apt-repository
|
make
|
||||||
software-properties-common
|
|
||||||
|
|
||||||
# rocksdb ppas. then update ppas
|
|
||||||
RUN add-apt-repository "deb http://ppa.launchpad.net/giskou/librocksdb/ubuntu trusty main" && \
|
|
||||||
apt-get update && \
|
|
||||||
apt-get install -y --force-yes librocksdb
|
|
||||||
|
|
||||||
# install multirust
|
# install multirust
|
||||||
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
||||||
|
|
||||||
# install nightly and make it default
|
|
||||||
RUN multirust update nightly && multirust default nightly
|
|
||||||
|
|
||||||
# export rust LIBRARY_PATH
|
# export rust LIBRARY_PATH
|
||||||
ENV LIBRARY_PATH /usr/local/lib
|
ENV LIBRARY_PATH /usr/local/lib
|
||||||
|
|
||||||
@ -29,4 +20,4 @@ ENV RUST_BACKTRACE 1
|
|||||||
# build parity
|
# build parity
|
||||||
RUN git clone https://github.com/ethcore/parity && \
|
RUN git clone https://github.com/ethcore/parity && \
|
||||||
cd parity && \
|
cd parity && \
|
||||||
cargo install --features rpc
|
cargo build --release
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "ethash"
|
name = "ethash"
|
||||||
version = "0.1.0"
|
version = "1.1.0"
|
||||||
authors = ["arkpar <arkadiy@ethcore.io"]
|
authors = ["arkpar <arkadiy@ethcore.io"]
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
lru-cache = "0.0"
|
|
||||||
sha3 = { path = "../util/sha3" }
|
sha3 = { path = "../util/sha3" }
|
||||||
|
primal = "0.2.3"
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
|
|
||||||
// TODO: fix endianess for big endian
|
// TODO: fix endianess for big endian
|
||||||
|
|
||||||
|
use primal::is_prime;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use sizes::{CACHE_SIZES, DAG_SIZES};
|
|
||||||
use sha3;
|
use sha3;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -31,9 +31,13 @@ use std::fs::{self, File};
|
|||||||
pub const ETHASH_EPOCH_LENGTH: u64 = 30000;
|
pub const ETHASH_EPOCH_LENGTH: u64 = 30000;
|
||||||
pub const ETHASH_CACHE_ROUNDS: usize = 3;
|
pub const ETHASH_CACHE_ROUNDS: usize = 3;
|
||||||
pub const ETHASH_MIX_BYTES: usize = 128;
|
pub const ETHASH_MIX_BYTES: usize = 128;
|
||||||
pub const ETHASH_ACCESSES:usize = 64;
|
pub const ETHASH_ACCESSES: usize = 64;
|
||||||
pub const ETHASH_DATASET_PARENTS:u32 = 256;
|
pub const ETHASH_DATASET_PARENTS: u32 = 256;
|
||||||
|
|
||||||
|
const DATASET_BYTES_INIT: u64 = 1 << 30;
|
||||||
|
const DATASET_BYTES_GROWTH: u64 = 1 << 23;
|
||||||
|
const CACHE_BYTES_INIT: u64 = 1 << 24;
|
||||||
|
const CACHE_BYTES_GROWTH: u64 = 1 << 17;
|
||||||
const NODE_WORDS: usize = 64 / 4;
|
const NODE_WORDS: usize = 64 / 4;
|
||||||
const NODE_BYTES: usize = 64;
|
const NODE_BYTES: usize = 64;
|
||||||
const MIX_WORDS: usize = ETHASH_MIX_BYTES / 4;
|
const MIX_WORDS: usize = ETHASH_MIX_BYTES / 4;
|
||||||
@ -53,7 +57,7 @@ struct Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Node {
|
impl Default for Node {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Node { bytes: [0u8; NODE_BYTES] }
|
Node { bytes: [0u8; NODE_BYTES] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -109,7 +113,7 @@ impl Light {
|
|||||||
pub fn from_file(block_number: u64) -> io::Result<Light> {
|
pub fn from_file(block_number: u64) -> io::Result<Light> {
|
||||||
let path = Light::file_path(block_number);
|
let path = Light::file_path(block_number);
|
||||||
let mut file = try!(File::open(path));
|
let mut file = try!(File::open(path));
|
||||||
|
|
||||||
let cache_size = get_cache_size(block_number);
|
let cache_size = get_cache_size(block_number);
|
||||||
if try!(file.metadata()).len() != cache_size as u64 {
|
if try!(file.metadata()).len() != cache_size as u64 {
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "Cache file size mismatch"));
|
return Err(io::Error::new(io::ErrorKind::Other, "Cache file size mismatch"));
|
||||||
@ -129,10 +133,10 @@ impl Light {
|
|||||||
let path = Light::file_path(self.block_number);
|
let path = Light::file_path(self.block_number);
|
||||||
try!(fs::create_dir_all(path.parent().unwrap()));
|
try!(fs::create_dir_all(path.parent().unwrap()));
|
||||||
let mut file = try!(File::create(path));
|
let mut file = try!(File::create(path));
|
||||||
|
|
||||||
let cache_size = self.cache.len() * NODE_BYTES;
|
let cache_size = self.cache.len() * NODE_BYTES;
|
||||||
let buf = unsafe { slice::from_raw_parts(self.cache.as_ptr() as *const u8, cache_size) };
|
let buf = unsafe { slice::from_raw_parts(self.cache.as_ptr() as *const u8, cache_size) };
|
||||||
try!(file.write(buf));
|
try!(file.write(buf));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -149,18 +153,27 @@ fn sha3_512(input: &[u8], output: &mut [u8]) {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_cache_size(block_number: u64) -> usize {
|
fn get_cache_size(block_number: u64) -> usize {
|
||||||
assert!(block_number / ETHASH_EPOCH_LENGTH < 2048);
|
let mut sz: u64 = CACHE_BYTES_INIT + CACHE_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH);
|
||||||
return CACHE_SIZES[(block_number / ETHASH_EPOCH_LENGTH) as usize] as usize;
|
sz = sz - NODE_BYTES as u64;
|
||||||
|
while !is_prime(sz / NODE_BYTES as u64) {
|
||||||
|
sz = sz - 2 * NODE_BYTES as u64;
|
||||||
|
}
|
||||||
|
sz as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_data_size(block_number: u64) -> usize {
|
fn get_data_size(block_number: u64) -> usize {
|
||||||
assert!(block_number / ETHASH_EPOCH_LENGTH < 2048);
|
let mut sz: u64 = DATASET_BYTES_INIT + DATASET_BYTES_GROWTH * (block_number / ETHASH_EPOCH_LENGTH);
|
||||||
return DAG_SIZES[(block_number / ETHASH_EPOCH_LENGTH) as usize] as usize;
|
sz = sz - ETHASH_MIX_BYTES as u64;
|
||||||
|
while !is_prime(sz / ETHASH_MIX_BYTES as u64) {
|
||||||
|
sz = sz - 2 * ETHASH_MIX_BYTES as u64;
|
||||||
|
}
|
||||||
|
sz as usize
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn get_seedhash(block_number: u64) -> H256 {
|
/// Given the `block_number`, determine the seed hash for Ethash.
|
||||||
|
pub fn get_seedhash(block_number: u64) -> H256 {
|
||||||
let epochs = block_number / ETHASH_EPOCH_LENGTH;
|
let epochs = block_number / ETHASH_EPOCH_LENGTH;
|
||||||
let mut ret: H256 = [0u8; 32];
|
let mut ret: H256 = [0u8; 32];
|
||||||
for _ in 0..epochs {
|
for _ in 0..epochs {
|
||||||
@ -289,7 +302,7 @@ fn light_new(block_number: u64) -> Light {
|
|||||||
for i in 1..num_nodes {
|
for i in 1..num_nodes {
|
||||||
sha3::sha3_512(nodes.get_unchecked_mut(i).bytes.as_mut_ptr(), NODE_BYTES, nodes.get_unchecked(i - 1).bytes.as_ptr(), NODE_BYTES);
|
sha3::sha3_512(nodes.get_unchecked_mut(i).bytes.as_mut_ptr(), NODE_BYTES, nodes.get_unchecked(i - 1).bytes.as_ptr(), NODE_BYTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
for _ in 0..ETHASH_CACHE_ROUNDS {
|
for _ in 0..ETHASH_CACHE_ROUNDS {
|
||||||
for i in 0..num_nodes {
|
for i in 0..num_nodes {
|
||||||
let idx = *nodes.get_unchecked_mut(i).as_words().get_unchecked(0) as usize % num_nodes;
|
let idx = *nodes.get_unchecked_mut(i).as_words().get_unchecked(0) as usize % num_nodes;
|
||||||
@ -321,10 +334,35 @@ fn to_hex(bytes: &[u8]) -> String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_cache_size() {
|
||||||
|
// https://github.com/ethereum/wiki/wiki/Ethash/ef6b93f9596746a088ea95d01ca2778be43ae68f#data-sizes
|
||||||
|
assert_eq!(16776896usize, get_cache_size(0));
|
||||||
|
assert_eq!(16776896usize, get_cache_size(1));
|
||||||
|
assert_eq!(16776896usize, get_cache_size(ETHASH_EPOCH_LENGTH - 1));
|
||||||
|
assert_eq!(16907456usize, get_cache_size(ETHASH_EPOCH_LENGTH));
|
||||||
|
assert_eq!(16907456usize, get_cache_size(ETHASH_EPOCH_LENGTH + 1));
|
||||||
|
assert_eq!(284950208usize, get_cache_size(2046 * ETHASH_EPOCH_LENGTH));
|
||||||
|
assert_eq!(285081536usize, get_cache_size(2047 * ETHASH_EPOCH_LENGTH));
|
||||||
|
assert_eq!(285081536usize, get_cache_size(2048 * ETHASH_EPOCH_LENGTH - 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_get_data_size() {
|
||||||
|
// https://github.com/ethereum/wiki/wiki/Ethash/ef6b93f9596746a088ea95d01ca2778be43ae68f#data-sizes
|
||||||
|
assert_eq!(1073739904usize, get_data_size(0));
|
||||||
|
assert_eq!(1073739904usize, get_data_size(1));
|
||||||
|
assert_eq!(1073739904usize, get_data_size(ETHASH_EPOCH_LENGTH - 1));
|
||||||
|
assert_eq!(1082130304usize, get_data_size(ETHASH_EPOCH_LENGTH));
|
||||||
|
assert_eq!(1082130304usize, get_data_size(ETHASH_EPOCH_LENGTH + 1));
|
||||||
|
assert_eq!(18236833408usize, get_data_size(2046 * ETHASH_EPOCH_LENGTH));
|
||||||
|
assert_eq!(18245220736usize, get_data_size(2047 * ETHASH_EPOCH_LENGTH));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_difficulty_test() {
|
fn test_difficulty_test() {
|
||||||
let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72];
|
let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72];
|
||||||
let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d ];
|
let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d ];
|
||||||
let nonce = 0xd7b3ac70a301a249;
|
let nonce = 0xd7b3ac70a301a249;
|
||||||
let boundary_good = [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84];
|
let boundary_good = [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84];
|
||||||
assert_eq!(quick_get_difficulty(&hash, nonce, &mix_hash)[..], boundary_good[..]);
|
assert_eq!(quick_get_difficulty(&hash, nonce, &mix_hash)[..], boundary_good[..]);
|
||||||
@ -335,7 +373,7 @@ fn test_difficulty_test() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_light_compute() {
|
fn test_light_compute() {
|
||||||
let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72];
|
let hash = [0xf5, 0x7e, 0x6f, 0x3a, 0xcf, 0xc0, 0xdd, 0x4b, 0x5b, 0xf2, 0xbe, 0xe4, 0x0a, 0xb3, 0x35, 0x8a, 0xa6, 0x87, 0x73, 0xa8, 0xd0, 0x9f, 0x5e, 0x59, 0x5e, 0xab, 0x55, 0x94, 0x05, 0x52, 0x7d, 0x72];
|
||||||
let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d ];
|
let mix_hash = [0x1f, 0xff, 0x04, 0xce, 0xc9, 0x41, 0x73, 0xfd, 0x59, 0x1e, 0x3d, 0x89, 0x60, 0xce, 0x6b, 0xdf, 0x8b, 0x19, 0x71, 0x04, 0x8c, 0x71, 0xff, 0x93, 0x7b, 0xb2, 0xd3, 0x2a, 0x64, 0x31, 0xab, 0x6d ];
|
||||||
let boundary = [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84];
|
let boundary = [0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3e, 0x9b, 0x6c, 0x69, 0xbc, 0x2c, 0xe2, 0xa2, 0x4a, 0x8e, 0x95, 0x69, 0xef, 0xc7, 0xd7, 0x1b, 0x33, 0x35, 0xdf, 0x36, 0x8c, 0x9a, 0xe9, 0x7e, 0x53, 0x84];
|
||||||
let nonce = 0xd7b3ac70a301a249;
|
let nonce = 0xd7b3ac70a301a249;
|
||||||
// difficulty = 0x085657254bd9u64;
|
// difficulty = 0x085657254bd9u64;
|
||||||
|
@ -16,29 +16,40 @@
|
|||||||
|
|
||||||
//! Ethash implementation
|
//! Ethash implementation
|
||||||
//! See https://github.com/ethereum/wiki/wiki/Ethash
|
//! See https://github.com/ethereum/wiki/wiki/Ethash
|
||||||
|
extern crate primal;
|
||||||
extern crate sha3;
|
extern crate sha3;
|
||||||
extern crate lru_cache;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
mod sizes;
|
|
||||||
mod compute;
|
mod compute;
|
||||||
|
|
||||||
use lru_cache::LruCache;
|
use std::mem;
|
||||||
use compute::Light;
|
use compute::Light;
|
||||||
pub use compute::{quick_get_difficulty, H256, ProofOfWork, ETHASH_EPOCH_LENGTH};
|
pub use compute::{get_seedhash, quick_get_difficulty, H256, ProofOfWork, ETHASH_EPOCH_LENGTH};
|
||||||
|
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
/// Lighy/Full cache manager
|
struct LightCache {
|
||||||
|
recent_epoch: Option<u64>,
|
||||||
|
recent: Option<Arc<Light>>,
|
||||||
|
prev_epoch: Option<u64>,
|
||||||
|
prev: Option<Arc<Light>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Light/Full cache manager.
|
||||||
pub struct EthashManager {
|
pub struct EthashManager {
|
||||||
lights: Mutex<LruCache<u64, Arc<Light>>>
|
cache: Mutex<LightCache>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EthashManager {
|
impl EthashManager {
|
||||||
/// Create a new new instance of ethash manager
|
/// Create a new new instance of ethash manager
|
||||||
pub fn new() -> EthashManager {
|
pub fn new() -> EthashManager {
|
||||||
EthashManager {
|
EthashManager {
|
||||||
lights: Mutex::new(LruCache::new(2))
|
cache: Mutex::new(LightCache {
|
||||||
|
recent_epoch: None,
|
||||||
|
recent: None,
|
||||||
|
prev_epoch: None,
|
||||||
|
prev: None,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,12 +61,28 @@ impl EthashManager {
|
|||||||
pub fn compute_light(&self, block_number: u64, header_hash: &H256, nonce: u64) -> ProofOfWork {
|
pub fn compute_light(&self, block_number: u64, header_hash: &H256, nonce: u64) -> ProofOfWork {
|
||||||
let epoch = block_number / ETHASH_EPOCH_LENGTH;
|
let epoch = block_number / ETHASH_EPOCH_LENGTH;
|
||||||
let light = {
|
let light = {
|
||||||
let mut lights = self.lights.lock().unwrap();
|
let mut lights = self.cache.lock().unwrap();
|
||||||
match lights.get_mut(&epoch).map(|l| l.clone()) {
|
let light = match lights.recent_epoch.clone() {
|
||||||
|
Some(ref e) if *e == epoch => lights.recent.clone(),
|
||||||
|
_ => match lights.prev_epoch.clone() {
|
||||||
|
Some(e) if e == epoch => {
|
||||||
|
// swap
|
||||||
|
let t = lights.prev_epoch;
|
||||||
|
lights.prev_epoch = lights.recent_epoch;
|
||||||
|
lights.recent_epoch = t;
|
||||||
|
let t = lights.prev.clone();
|
||||||
|
lights.prev = lights.recent.clone();
|
||||||
|
lights.recent = t;
|
||||||
|
lights.recent.clone()
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
match light {
|
||||||
None => {
|
None => {
|
||||||
let light = match Light::from_file(block_number) {
|
let light = match Light::from_file(block_number) {
|
||||||
Ok(light) => Arc::new(light),
|
Ok(light) => Arc::new(light),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!("Light cache file not found for {}:{}", block_number, e);
|
debug!("Light cache file not found for {}:{}", block_number, e);
|
||||||
let light = Light::new(block_number);
|
let light = Light::new(block_number);
|
||||||
if let Err(e) = light.to_file() {
|
if let Err(e) = light.to_file() {
|
||||||
@ -64,7 +91,8 @@ impl EthashManager {
|
|||||||
Arc::new(light)
|
Arc::new(light)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
lights.insert(epoch, light.clone());
|
lights.prev_epoch = mem::replace(&mut lights.recent_epoch, Some(epoch));
|
||||||
|
lights.prev = mem::replace(&mut lights.recent, Some(light.clone()));
|
||||||
light
|
light
|
||||||
}
|
}
|
||||||
Some(light) => light
|
Some(light) => light
|
||||||
@ -73,3 +101,19 @@ impl EthashManager {
|
|||||||
light.compute(header_hash, nonce)
|
light.compute(header_hash, nonce)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_lru() {
|
||||||
|
let ethash = EthashManager::new();
|
||||||
|
let hash = [0u8; 32];
|
||||||
|
ethash.compute_light(1, &hash, 1);
|
||||||
|
ethash.compute_light(50000, &hash, 1);
|
||||||
|
assert_eq!(ethash.cache.lock().unwrap().recent_epoch.unwrap(), 1);
|
||||||
|
assert_eq!(ethash.cache.lock().unwrap().prev_epoch.unwrap(), 0);
|
||||||
|
ethash.compute_light(1, &hash, 1);
|
||||||
|
assert_eq!(ethash.cache.lock().unwrap().recent_epoch.unwrap(), 0);
|
||||||
|
assert_eq!(ethash.cache.lock().unwrap().prev_epoch.unwrap(), 1);
|
||||||
|
ethash.compute_light(70000, &hash, 1);
|
||||||
|
assert_eq!(ethash.cache.lock().unwrap().recent_epoch.unwrap(), 2);
|
||||||
|
assert_eq!(ethash.cache.lock().unwrap().prev_epoch.unwrap(), 0);
|
||||||
|
}
|
||||||
|
@ -3,27 +3,30 @@ description = "Ethcore library"
|
|||||||
homepage = "http://ethcore.io"
|
homepage = "http://ethcore.io"
|
||||||
license = "GPL-3.0"
|
license = "GPL-3.0"
|
||||||
name = "ethcore"
|
name = "ethcore"
|
||||||
version = "0.9.0"
|
version = "1.1.0"
|
||||||
authors = ["Ethcore <admin@ethcore.io>"]
|
authors = ["Ethcore <admin@ethcore.io>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
log = "0.3"
|
log = "0.3"
|
||||||
env_logger = "0.3"
|
env_logger = "0.3"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
rocksdb = "0.3"
|
heapsize = "0.3"
|
||||||
heapsize = "0.2.0"
|
|
||||||
rust-crypto = "0.2.34"
|
rust-crypto = "0.2.34"
|
||||||
time = "0.1"
|
time = "0.1"
|
||||||
ethcore-util = { path = "../util" }
|
ethcore-util = { path = "../util" }
|
||||||
evmjit = { path = "../evmjit", optional = true }
|
evmjit = { path = "../evmjit", optional = true }
|
||||||
ethash = { path = "../ethash" }
|
ethash = { path = "../ethash" }
|
||||||
num_cpus = "0.2"
|
num_cpus = "0.2"
|
||||||
clippy = "0.0.41"
|
clippy = { version = "0.0.54", optional = true }
|
||||||
crossbeam = "0.1.5"
|
crossbeam = "0.1.5"
|
||||||
lazy_static = "0.1"
|
lazy_static = "0.1"
|
||||||
|
ethcore-devtools = { path = "../devtools" }
|
||||||
|
ethjson = { path = "../json" }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
jit = ["evmjit"]
|
jit = ["evmjit"]
|
||||||
evm-debug = []
|
evm-debug = []
|
||||||
json-tests = []
|
json-tests = []
|
||||||
test-heavy = []
|
test-heavy = []
|
||||||
|
dev = ["clippy"]
|
||||||
|
default = []
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"name": "Frontier",
|
"name": "Frontier/Homestead",
|
||||||
"engineName": "Ethash",
|
"engineName": "Ethash",
|
||||||
"params": {
|
"params": {
|
||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
"frontierCompatibilityModeLimit": "0x10c8e0",
|
"frontierCompatibilityModeLimit": "0x118c30",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"tieBreakingGas": false,
|
"tieBreakingGas": false,
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
@ -33,10 +33,10 @@
|
|||||||
"enode://248f12bc8b18d5289358085520ac78cd8076485211e6d96ab0bc93d6cd25442db0ce3a937dc404f64f207b0b9aed50e25e98ce32af5ac7cb321ff285b97de485@parity-node-zero.ethcore.io:30303"
|
"enode://248f12bc8b18d5289358085520ac78cd8076485211e6d96ab0bc93d6cd25442db0ce3a937dc404f64f207b0b9aed50e25e98ce32af5ac7cb321ff285b97de485@parity-node-zero.ethcore.io:30303"
|
||||||
],
|
],
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
|
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||||
"3282791d6fd713f1e94f4bfd565eaa78b3a0599d": {
|
"3282791d6fd713f1e94f4bfd565eaa78b3a0599d": {
|
||||||
"balance": "1337000000000000000000"
|
"balance": "1337000000000000000000"
|
||||||
},
|
},
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
{
|
{
|
||||||
"engineName": "Frontier (Test)",
|
"name": "Frontier (Test)",
|
||||||
"engineName": "Ethash",
|
"engineName": "Ethash",
|
||||||
"params": {
|
"params": {
|
||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
"frontierCompatibilityModeLimit": "0x10c8e0",
|
"frontierCompatibilityModeLimit": "0x118c30",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"tieBreakingGas": false,
|
"tieBreakingGas": false,
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
@ -26,9 +26,9 @@
|
|||||||
"gasLimit": "0x1388"
|
"gasLimit": "0x1388"
|
||||||
},
|
},
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }
|
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"engineName": "Frontier (Test)",
|
"name": "Frontier (Test)",
|
||||||
"engineName": "Ethash",
|
"engineName": "Ethash",
|
||||||
"params": {
|
"params": {
|
||||||
"accountStartNonce": "0x00",
|
"accountStartNonce": "0x00",
|
||||||
@ -26,9 +26,9 @@
|
|||||||
"gasLimit": "0x1388"
|
"gasLimit": "0x1388"
|
||||||
},
|
},
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }
|
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,9 @@
|
|||||||
"gasLimit": "0x1388"
|
"gasLimit": "0x1388"
|
||||||
},
|
},
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } }
|
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"engineName": "Ethash",
|
"engineName": "Ethash",
|
||||||
"params": {
|
"params": {
|
||||||
"accountStartNonce": "0x0100000",
|
"accountStartNonce": "0x0100000",
|
||||||
"frontierCompatibilityModeLimit": "0x10c8e0",
|
"frontierCompatibilityModeLimit": "0x789b0",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"tieBreakingGas": false,
|
"tieBreakingGas": false,
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
@ -25,11 +25,14 @@
|
|||||||
"extraData": "0x",
|
"extraData": "0x",
|
||||||
"gasLimit": "0x2fefd8"
|
"gasLimit": "0x2fefd8"
|
||||||
},
|
},
|
||||||
|
"nodes": [
|
||||||
|
"enode://b1217cbaa440e35ed471157123fe468e19e8b5ad5bedb4b1fdbcbdab6fb2f5ed3e95dd9c24a22a79fdb2352204cea207df27d92bfd21bfd41545e8b16f637499@104.44.138.37:30303"
|
||||||
|
],
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
|
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||||
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
|
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
"gasLimit": "0x2fefd8"
|
"gasLimit": "0x2fefd8"
|
||||||
},
|
},
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
|
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||||
"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
"dbdbdb2cbd23b783741e8d7fcf51e459b497e4a6": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
||||||
"e6716f9544a56c530d868e4bfbacb172315bdead": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
"e6716f9544a56c530d868e4bfbacb172315bdead": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
||||||
"b9c015918bdaba24b4ff057a92a3873d6eb201be": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
"b9c015918bdaba24b4ff057a92a3873d6eb201be": { "balance": "1606938044258990275541962092341162602522202993782792835301376" },
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 3116f85a499ceaf4dfdc46726060fc056e2d7829
|
Subproject commit 99afe8f5aad7bca5d0f1b1685390a4dea32d73c3
|
35
ethcore/res/null_homestead_morden.json
Normal file
35
ethcore/res/null_homestead_morden.json
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"name": "Morden",
|
||||||
|
"engineName": "NullEngine",
|
||||||
|
"params": {
|
||||||
|
"accountStartNonce": "0x0100000",
|
||||||
|
"frontierCompatibilityModeLimit": "0x0",
|
||||||
|
"maximumExtraDataSize": "0x20",
|
||||||
|
"tieBreakingGas": false,
|
||||||
|
"minGasLimit": "0x1388",
|
||||||
|
"gasLimitBoundDivisor": "0x0400",
|
||||||
|
"minimumDifficulty": "0x020000",
|
||||||
|
"difficultyBoundDivisor": "0x0800",
|
||||||
|
"durationLimit": "0x0d",
|
||||||
|
"blockReward": "0x4563918244F40000",
|
||||||
|
"registrar": "",
|
||||||
|
"networkID" : "0x2"
|
||||||
|
},
|
||||||
|
"genesis": {
|
||||||
|
"nonce": "0x00006d6f7264656e",
|
||||||
|
"difficulty": "0x20000",
|
||||||
|
"mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578",
|
||||||
|
"author": "0x0000000000000000000000000000000000000000",
|
||||||
|
"timestamp": "0x00",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"extraData": "0x",
|
||||||
|
"gasLimit": "0x2fefd8"
|
||||||
|
},
|
||||||
|
"accounts": {
|
||||||
|
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
|
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
|
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
|
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||||
|
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
"engineName": "NullEngine",
|
"engineName": "NullEngine",
|
||||||
"params": {
|
"params": {
|
||||||
"accountStartNonce": "0x0100000",
|
"accountStartNonce": "0x0100000",
|
||||||
"frontierCompatibilityModeLimit": "0xfffa2990",
|
"frontierCompatibilityModeLimit": "0x789b0",
|
||||||
"maximumExtraDataSize": "0x20",
|
"maximumExtraDataSize": "0x20",
|
||||||
"tieBreakingGas": false,
|
"tieBreakingGas": false,
|
||||||
"minGasLimit": "0x1388",
|
"minGasLimit": "0x1388",
|
||||||
@ -26,10 +26,10 @@
|
|||||||
"gasLimit": "0x2fefd8"
|
"gasLimit": "0x2fefd8"
|
||||||
},
|
},
|
||||||
"accounts": {
|
"accounts": {
|
||||||
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "linear": { "base": 3000, "word": 0 } } },
|
"0000000000000000000000000000000000000001": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "linear": { "base": 60, "word": 12 } } },
|
"0000000000000000000000000000000000000002": { "balance": "1", "nonce": "1048576", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "linear": { "base": 600, "word": 120 } } },
|
"0000000000000000000000000000000000000003": { "balance": "1", "nonce": "1048576", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "linear": { "base": 15, "word": 3 } } },
|
"0000000000000000000000000000000000000004": { "balance": "1", "nonce": "1048576", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } },
|
||||||
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
|
"102e61f5d8f9bc71d0ad4a084df4e65e05ce0e1c": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "1048576" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -92,10 +92,10 @@ impl Account {
|
|||||||
|
|
||||||
/// Create a new contract account.
|
/// Create a new contract account.
|
||||||
/// NOTE: make sure you use `init_code` on this before `commit`ing.
|
/// NOTE: make sure you use `init_code` on this before `commit`ing.
|
||||||
pub fn new_contract(balance: U256) -> Account {
|
pub fn new_contract(balance: U256, nonce: U256) -> Account {
|
||||||
Account {
|
Account {
|
||||||
balance: balance,
|
balance: balance,
|
||||||
nonce: U256::from(0u8),
|
nonce: nonce,
|
||||||
storage_root: SHA3_NULL_RLP,
|
storage_root: SHA3_NULL_RLP,
|
||||||
storage_overlay: RefCell::new(HashMap::new()),
|
storage_overlay: RefCell::new(HashMap::new()),
|
||||||
code_hash: None,
|
code_hash: None,
|
||||||
@ -261,7 +261,7 @@ mod tests {
|
|||||||
let mut db = MemoryDB::new();
|
let mut db = MemoryDB::new();
|
||||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||||
let rlp = {
|
let rlp = {
|
||||||
let mut a = Account::new_contract(U256::from(69u8));
|
let mut a = Account::new_contract(x!(69), x!(0));
|
||||||
a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64)));
|
a.set_storage(H256::from(&U256::from(0x00u64)), H256::from(&U256::from(0x1234u64)));
|
||||||
a.commit_storage(&mut db);
|
a.commit_storage(&mut db);
|
||||||
a.init_code(vec![]);
|
a.init_code(vec![]);
|
||||||
@ -281,7 +281,7 @@ mod tests {
|
|||||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||||
|
|
||||||
let rlp = {
|
let rlp = {
|
||||||
let mut a = Account::new_contract(U256::from(69u8));
|
let mut a = Account::new_contract(x!(69), x!(0));
|
||||||
a.init_code(vec![0x55, 0x44, 0xffu8]);
|
a.init_code(vec![0x55, 0x44, 0xffu8]);
|
||||||
a.commit_code(&mut db);
|
a.commit_code(&mut db);
|
||||||
a.rlp()
|
a.rlp()
|
||||||
@ -296,7 +296,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn commit_storage() {
|
fn commit_storage() {
|
||||||
let mut a = Account::new_contract(U256::from(69u8));
|
let mut a = Account::new_contract(x!(69), x!(0));
|
||||||
let mut db = MemoryDB::new();
|
let mut db = MemoryDB::new();
|
||||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||||
a.set_storage(x!(0), x!(0x1234));
|
a.set_storage(x!(0), x!(0x1234));
|
||||||
@ -307,7 +307,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn commit_remove_commit_storage() {
|
fn commit_remove_commit_storage() {
|
||||||
let mut a = Account::new_contract(U256::from(69u8));
|
let mut a = Account::new_contract(x!(69), x!(0));
|
||||||
let mut db = MemoryDB::new();
|
let mut db = MemoryDB::new();
|
||||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||||
a.set_storage(x!(0), x!(0x1234));
|
a.set_storage(x!(0), x!(0x1234));
|
||||||
@ -321,7 +321,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn commit_code() {
|
fn commit_code() {
|
||||||
let mut a = Account::new_contract(U256::from(69u8));
|
let mut a = Account::new_contract(x!(69), x!(0));
|
||||||
let mut db = MemoryDB::new();
|
let mut db = MemoryDB::new();
|
||||||
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||||
a.init_code(vec![0x55, 0x44, 0xffu8]);
|
a.init_code(vec![0x55, 0x44, 0xffu8]);
|
||||||
|
@ -13,17 +13,14 @@ pub struct AccountDB<'db> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn combine_key<'a>(address: &'a H256, key: &'a H256) -> H256 {
|
fn combine_key<'a>(address: &'a H256, key: &'a H256) -> H256 {
|
||||||
let mut addr_hash = address.sha3();
|
address ^ key
|
||||||
// preserve 96 bits of original key for db lookup
|
|
||||||
addr_hash[0..12].clone_from_slice(&[0u8; 12]);
|
|
||||||
&addr_hash ^ key
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'db> AccountDB<'db> {
|
impl<'db> AccountDB<'db> {
|
||||||
pub fn new(db: &'db HashDB, address: &Address) -> AccountDB<'db> {
|
pub fn new(db: &'db HashDB, address: &Address) -> AccountDB<'db> {
|
||||||
AccountDB {
|
AccountDB {
|
||||||
db: db,
|
db: db,
|
||||||
address: x!(address.clone()),
|
address: x!(address),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +67,7 @@ impl<'db> AccountDBMut<'db> {
|
|||||||
pub fn new(db: &'db mut HashDB, address: &Address) -> AccountDBMut<'db> {
|
pub fn new(db: &'db mut HashDB, address: &Address) -> AccountDBMut<'db> {
|
||||||
AccountDBMut {
|
AccountDBMut {
|
||||||
db: db,
|
db: db,
|
||||||
address: x!(address.clone()),
|
address: x!(address),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,6 +97,9 @@ impl<'db> HashDB for AccountDBMut<'db>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn insert(&mut self, value: &[u8]) -> H256 {
|
fn insert(&mut self, value: &[u8]) -> H256 {
|
||||||
|
if value == &NULL_RLP {
|
||||||
|
return SHA3_NULL_RLP.clone();
|
||||||
|
}
|
||||||
let k = value.sha3();
|
let k = value.sha3();
|
||||||
let ak = combine_key(&self.address, &k);
|
let ak = combine_key(&self.address, &k);
|
||||||
self.db.emplace(ak, value.to_vec());
|
self.db.emplace(ak, value.to_vec());
|
||||||
@ -107,11 +107,17 @@ impl<'db> HashDB for AccountDBMut<'db>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn emplace(&mut self, key: H256, value: Bytes) {
|
fn emplace(&mut self, key: H256, value: Bytes) {
|
||||||
|
if key == SHA3_NULL_RLP {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let key = combine_key(&self.address, &key);
|
let key = combine_key(&self.address, &key);
|
||||||
self.db.emplace(key, value.to_vec())
|
self.db.emplace(key, value.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn kill(&mut self, key: &H256) {
|
fn kill(&mut self, key: &H256) {
|
||||||
|
if key == &SHA3_NULL_RLP {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let key = combine_key(&self.address, key);
|
let key = combine_key(&self.address, key);
|
||||||
self.db.kill(&key)
|
self.db.kill(&key)
|
||||||
}
|
}
|
||||||
|
@ -15,9 +15,7 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
//! Evm input params.
|
//! Evm input params.
|
||||||
use util::hash::*;
|
use common::*;
|
||||||
use util::uint::*;
|
|
||||||
use util::bytes::*;
|
|
||||||
|
|
||||||
/// Transaction value
|
/// Transaction value
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
@ -24,7 +24,7 @@ pub type LogBloom = H2048;
|
|||||||
/// Constant 2048-bit datum for 0. Often used as a default.
|
/// Constant 2048-bit datum for 0. Often used as a default.
|
||||||
pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]);
|
pub static ZERO_LOGBLOOM: LogBloom = H2048([0x00; 256]);
|
||||||
|
|
||||||
#[allow(enum_variant_names)]
|
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
||||||
/// Semantic boolean for when a seal/signature is included.
|
/// Semantic boolean for when a seal/signature is included.
|
||||||
pub enum Seal {
|
pub enum Seal {
|
||||||
/// The seal/signature is included.
|
/// The seal/signature is included.
|
||||||
|
@ -16,15 +16,14 @@
|
|||||||
|
|
||||||
//! Blockchain block.
|
//! Blockchain block.
|
||||||
|
|
||||||
#![allow(ptr_arg)] // Because of &LastHashes -> &Vec<_>
|
#![cfg_attr(feature="dev", allow(ptr_arg))] // Because of &LastHashes -> &Vec<_>
|
||||||
|
|
||||||
use common::*;
|
use common::*;
|
||||||
use engine::*;
|
use engine::*;
|
||||||
use state::*;
|
use state::*;
|
||||||
use verification::PreVerifiedBlock;
|
use verification::PreverifiedBlock;
|
||||||
|
|
||||||
/// A block, encoded as it is on the block chain.
|
/// A block, encoded as it is on the block chain.
|
||||||
// TODO: rename to Block
|
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
pub struct Block {
|
pub struct Block {
|
||||||
/// The header of this block.
|
/// The header of this block.
|
||||||
@ -48,7 +47,7 @@ impl Block {
|
|||||||
if urlp.at(1).unwrap().iter().find(|i| i.as_val::<Transaction>().is_err()).is_some() {
|
if urlp.at(1).unwrap().iter().find(|i| i.as_val::<Transaction>().is_err()).is_some() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if !urlp.at(2).unwrap().is_list() { return false; }
|
if !urlp.at(2).unwrap().is_list() { return false; }
|
||||||
if urlp.at(2).unwrap().iter().find(|i| i.as_val::<Header>().is_err()).is_some() {
|
if urlp.at(2).unwrap().iter().find(|i| i.as_val::<Header>().is_err()).is_some() {
|
||||||
return false;
|
return false;
|
||||||
@ -61,7 +60,7 @@ impl Block {
|
|||||||
impl Decodable for Block {
|
impl Decodable for Block {
|
||||||
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||||
if decoder.as_raw().len() != try!(decoder.as_rlp().payload_info()).total() {
|
if decoder.as_raw().len() != try!(decoder.as_rlp().payload_info()).total() {
|
||||||
return Err(DecoderError::RlpIsTooBig);
|
return Err(DecoderError::RlpIsTooBig);
|
||||||
}
|
}
|
||||||
let d = decoder.as_rlp();
|
let d = decoder.as_rlp();
|
||||||
if d.item_count() != 3 {
|
if d.item_count() != 3 {
|
||||||
@ -76,8 +75,6 @@ impl Decodable for Block {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Internal type for a block's common elements.
|
/// Internal type for a block's common elements.
|
||||||
// TODO: rename to ExecutedBlock
|
|
||||||
// TODO: use BareBlock
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ExecutedBlock {
|
pub struct ExecutedBlock {
|
||||||
base: Block,
|
base: Block,
|
||||||
@ -85,9 +82,10 @@ pub struct ExecutedBlock {
|
|||||||
receipts: Vec<Receipt>,
|
receipts: Vec<Receipt>,
|
||||||
transactions_set: HashSet<H256>,
|
transactions_set: HashSet<H256>,
|
||||||
state: State,
|
state: State,
|
||||||
|
traces: Option<Vec<Trace>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A set of references to `ExecutedBlock` fields that are publicly accessible.
|
/// A set of references to `ExecutedBlock` fields that are publicly accessible.
|
||||||
pub struct BlockRefMut<'a> {
|
pub struct BlockRefMut<'a> {
|
||||||
/// Block header.
|
/// Block header.
|
||||||
pub header: &'a Header,
|
pub header: &'a Header,
|
||||||
@ -99,11 +97,21 @@ pub struct BlockRefMut<'a> {
|
|||||||
pub receipts: &'a Vec<Receipt>,
|
pub receipts: &'a Vec<Receipt>,
|
||||||
/// State.
|
/// State.
|
||||||
pub state: &'a mut State,
|
pub state: &'a mut State,
|
||||||
|
/// Traces.
|
||||||
|
pub traces: &'a Option<Vec<Trace>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExecutedBlock {
|
impl ExecutedBlock {
|
||||||
/// Create a new block from the given `state`.
|
/// Create a new block from the given `state`.
|
||||||
fn new(state: State) -> ExecutedBlock { ExecutedBlock { base: Default::default(), receipts: Default::default(), transactions_set: Default::default(), state: state } }
|
fn new(state: State, tracing: bool) -> ExecutedBlock {
|
||||||
|
ExecutedBlock {
|
||||||
|
base: Default::default(),
|
||||||
|
receipts: Default::default(),
|
||||||
|
transactions_set: Default::default(),
|
||||||
|
state: state,
|
||||||
|
traces: if tracing {Some(Vec::new())} else {None},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Get a structure containing individual references to all public fields.
|
/// Get a structure containing individual references to all public fields.
|
||||||
pub fn fields(&mut self) -> BlockRefMut {
|
pub fn fields(&mut self) -> BlockRefMut {
|
||||||
@ -113,6 +121,7 @@ impl ExecutedBlock {
|
|||||||
uncles: &self.base.uncles,
|
uncles: &self.base.uncles,
|
||||||
state: &mut self.state,
|
state: &mut self.state,
|
||||||
receipts: &self.receipts,
|
receipts: &self.receipts,
|
||||||
|
traces: &self.traces,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -134,6 +143,9 @@ pub trait IsBlock {
|
|||||||
/// Get all information on receipts in this block.
|
/// Get all information on receipts in this block.
|
||||||
fn receipts(&self) -> &Vec<Receipt> { &self.block().receipts }
|
fn receipts(&self) -> &Vec<Receipt> { &self.block().receipts }
|
||||||
|
|
||||||
|
/// Get all information concerning transaction tracing in this block.
|
||||||
|
fn traces(&self) -> &Option<Vec<Trace>> { &self.block().traces }
|
||||||
|
|
||||||
/// Get all uncles in this block.
|
/// Get all uncles in this block.
|
||||||
fn uncles(&self) -> &Vec<Header> { &self.block().base.uncles }
|
fn uncles(&self) -> &Vec<Header> { &self.block().base.uncles }
|
||||||
}
|
}
|
||||||
@ -144,20 +156,20 @@ impl IsBlock for ExecutedBlock {
|
|||||||
|
|
||||||
/// Block that is ready for transactions to be added.
|
/// Block that is ready for transactions to be added.
|
||||||
///
|
///
|
||||||
/// It's a bit like a Vec<Transaction>, eccept that whenever a transaction is pushed, we execute it and
|
/// It's a bit like a Vec<Transaction>, except that whenever a transaction is pushed, we execute it and
|
||||||
/// maintain the system `state()`. We also archive execution receipts in preparation for later block creation.
|
/// maintain the system `state()`. We also archive execution receipts in preparation for later block creation.
|
||||||
pub struct OpenBlock<'x, 'y> {
|
pub struct OpenBlock<'x> {
|
||||||
block: ExecutedBlock,
|
block: ExecutedBlock,
|
||||||
engine: &'x Engine,
|
engine: &'x Engine,
|
||||||
last_hashes: &'y LastHashes,
|
last_hashes: LastHashes,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Just like OpenBlock, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
|
/// Just like OpenBlock, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
|
||||||
/// and collected the uncles.
|
/// and collected the uncles.
|
||||||
///
|
///
|
||||||
/// There is no function available to push a transaction. If you want that you'll need to `reopen()` it.
|
/// There is no function available to push a transaction.
|
||||||
pub struct ClosedBlock<'x, 'y> {
|
pub struct ClosedBlock {
|
||||||
open_block: OpenBlock<'x, 'y>,
|
block: ExecutedBlock,
|
||||||
uncle_bytes: Bytes,
|
uncle_bytes: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,21 +181,23 @@ pub struct SealedBlock {
|
|||||||
uncle_bytes: Bytes,
|
uncle_bytes: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'x, 'y> OpenBlock<'x, 'y> {
|
impl<'x> OpenBlock<'x> {
|
||||||
/// Create a new OpenBlock ready for transaction pushing.
|
/// Create a new OpenBlock ready for transaction pushing.
|
||||||
pub fn new<'a, 'b>(engine: &'a Engine, db: JournalDB, parent: &Header, last_hashes: &'b LastHashes, author: Address, extra_data: Bytes) -> OpenBlock<'a, 'b> {
|
pub fn new(engine: &'x Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes, author: Address, gas_floor_target: U256, extra_data: Bytes) -> Self {
|
||||||
let mut r = OpenBlock {
|
let mut r = OpenBlock {
|
||||||
block: ExecutedBlock::new(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce())),
|
block: ExecutedBlock::new(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce()), tracing),
|
||||||
engine: engine,
|
engine: engine,
|
||||||
last_hashes: last_hashes,
|
last_hashes: last_hashes,
|
||||||
};
|
};
|
||||||
|
|
||||||
r.block.base.header.set_number(parent.number() + 1);
|
r.block.base.header.parent_hash = parent.hash();
|
||||||
r.block.base.header.set_author(author);
|
r.block.base.header.number = parent.number + 1;
|
||||||
r.block.base.header.set_extra_data(extra_data);
|
r.block.base.header.author = author;
|
||||||
r.block.base.header.set_timestamp_now();
|
r.block.base.header.set_timestamp_now(parent.timestamp());
|
||||||
|
r.block.base.header.extra_data = extra_data;
|
||||||
|
r.block.base.header.note_dirty();
|
||||||
|
|
||||||
engine.populate_from_parent(&mut r.block.base.header, parent);
|
engine.populate_from_parent(&mut r.block.base.header, parent, gas_floor_target);
|
||||||
engine.on_new_block(&mut r.block);
|
engine.on_new_block(&mut r.block);
|
||||||
r
|
r
|
||||||
}
|
}
|
||||||
@ -218,8 +232,8 @@ impl<'x, 'y> OpenBlock<'x, 'y> {
|
|||||||
/// NOTE Will check chain constraints and the uncle number but will NOT check
|
/// NOTE Will check chain constraints and the uncle number but will NOT check
|
||||||
/// that the header itself is actually valid.
|
/// that the header itself is actually valid.
|
||||||
pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> {
|
pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> {
|
||||||
if self.block.base.uncles.len() >= self.engine.maximum_uncle_count() {
|
if self.block.base.uncles.len() + 1 > self.engine.maximum_uncle_count() {
|
||||||
return Err(BlockError::TooManyUncles(OutOfBounds{min: None, max: Some(self.engine.maximum_uncle_count()), found: self.block.base.uncles.len()}));
|
return Err(BlockError::TooManyUncles(OutOfBounds{min: None, max: Some(self.engine.maximum_uncle_count()), found: self.block.base.uncles.len() + 1}));
|
||||||
}
|
}
|
||||||
// TODO: check number
|
// TODO: check number
|
||||||
// TODO: check not a direct ancestor (use last_hashes for that)
|
// TODO: check not a direct ancestor (use last_hashes for that)
|
||||||
@ -247,11 +261,13 @@ impl<'x, 'y> OpenBlock<'x, 'y> {
|
|||||||
pub fn push_transaction(&mut self, t: SignedTransaction, h: Option<H256>) -> Result<&Receipt, Error> {
|
pub fn push_transaction(&mut self, t: SignedTransaction, h: Option<H256>) -> Result<&Receipt, Error> {
|
||||||
let env_info = self.env_info();
|
let env_info = self.env_info();
|
||||||
// info!("env_info says gas_used={}", env_info.gas_used);
|
// info!("env_info says gas_used={}", env_info.gas_used);
|
||||||
match self.block.state.apply(&env_info, self.engine, &t) {
|
match self.block.state.apply(&env_info, self.engine, &t, self.block.traces.is_some()) {
|
||||||
Ok(receipt) => {
|
Ok(outcome) => {
|
||||||
self.block.transactions_set.insert(h.unwrap_or_else(||t.hash()));
|
self.block.transactions_set.insert(h.unwrap_or_else(||t.hash()));
|
||||||
self.block.base.transactions.push(t);
|
self.block.base.transactions.push(t);
|
||||||
self.block.receipts.push(receipt);
|
let t = outcome.trace;
|
||||||
|
self.block.traces.as_mut().map(|traces| traces.push(t.expect("self.block.traces.is_some(): so we must be tracing: qed")));
|
||||||
|
self.block.receipts.push(outcome.receipt);
|
||||||
Ok(&self.block.receipts.last().unwrap())
|
Ok(&self.block.receipts.last().unwrap())
|
||||||
}
|
}
|
||||||
Err(x) => Err(From::from(x))
|
Err(x) => Err(From::from(x))
|
||||||
@ -259,58 +275,63 @@ impl<'x, 'y> OpenBlock<'x, 'y> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Turn this into a `ClosedBlock`. A BlockChain must be provided in order to figure out the uncles.
|
/// Turn this into a `ClosedBlock`. A BlockChain must be provided in order to figure out the uncles.
|
||||||
pub fn close(self) -> ClosedBlock<'x, 'y> {
|
pub fn close(self) -> ClosedBlock {
|
||||||
let mut s = self;
|
let mut s = self;
|
||||||
s.engine.on_close_block(&mut s.block);
|
s.engine.on_close_block(&mut s.block);
|
||||||
s.block.base.header.transactions_root = ordered_trie_root(s.block.base.transactions.iter().map(|ref e| e.rlp_bytes().to_vec()).collect());
|
s.block.base.header.transactions_root = ordered_trie_root(s.block.base.transactions.iter().map(|ref e| e.rlp_bytes().to_vec()).collect());
|
||||||
let uncle_bytes = s.block.base.uncles.iter().fold(RlpStream::new_list(s.block.base.uncles.len()), |mut s, u| {s.append(&u.rlp(Seal::With)); s} ).out();
|
let uncle_bytes = s.block.base.uncles.iter().fold(RlpStream::new_list(s.block.base.uncles.len()), |mut s, u| {s.append_raw(&u.rlp(Seal::With), 1); s} ).out();
|
||||||
s.block.base.header.uncles_hash = uncle_bytes.sha3();
|
s.block.base.header.uncles_hash = uncle_bytes.sha3();
|
||||||
s.block.base.header.state_root = s.block.state.root().clone();
|
s.block.base.header.state_root = s.block.state.root().clone();
|
||||||
s.block.base.header.receipts_root = ordered_trie_root(s.block.receipts.iter().map(|ref r| r.rlp_bytes().to_vec()).collect());
|
s.block.base.header.receipts_root = ordered_trie_root(s.block.receipts.iter().map(|ref r| r.rlp_bytes().to_vec()).collect());
|
||||||
s.block.base.header.log_bloom = s.block.receipts.iter().fold(LogBloom::zero(), |mut b, r| {b |= &r.log_bloom; b});
|
s.block.base.header.log_bloom = s.block.receipts.iter().fold(LogBloom::zero(), |mut b, r| {b = &b | &r.log_bloom; b}); //TODO: use |= operator
|
||||||
s.block.base.header.gas_used = s.block.receipts.last().map_or(U256::zero(), |r| r.gas_used);
|
s.block.base.header.gas_used = s.block.receipts.last().map_or(U256::zero(), |r| r.gas_used);
|
||||||
s.block.base.header.note_dirty();
|
s.block.base.header.note_dirty();
|
||||||
|
|
||||||
ClosedBlock::new(s, uncle_bytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'x, 'y> IsBlock for OpenBlock<'x, 'y> {
|
|
||||||
fn block(&self) -> &ExecutedBlock { &self.block }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'x, 'y> IsBlock for ClosedBlock<'x, 'y> {
|
|
||||||
fn block(&self) -> &ExecutedBlock { &self.open_block.block }
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'x, 'y> ClosedBlock<'x, 'y> {
|
|
||||||
fn new<'a, 'b>(open_block: OpenBlock<'a, 'b>, uncle_bytes: Bytes) -> ClosedBlock<'a, 'b> {
|
|
||||||
ClosedBlock {
|
ClosedBlock {
|
||||||
open_block: open_block,
|
block: s.block,
|
||||||
uncle_bytes: uncle_bytes,
|
uncle_bytes: uncle_bytes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'x> IsBlock for OpenBlock<'x> {
|
||||||
|
fn block(&self) -> &ExecutedBlock { &self.block }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'x> IsBlock for ClosedBlock {
|
||||||
|
fn block(&self) -> &ExecutedBlock { &self.block }
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClosedBlock {
|
||||||
/// Get the hash of the header without seal arguments.
|
/// Get the hash of the header without seal arguments.
|
||||||
pub fn hash(&self) -> H256 { self.header().rlp_sha3(Seal::Without) }
|
pub fn hash(&self) -> H256 { self.header().rlp_sha3(Seal::Without) }
|
||||||
|
|
||||||
/// Provide a valid seal in order to turn this into a `SealedBlock`.
|
/// Provide a valid seal in order to turn this into a `SealedBlock`.
|
||||||
///
|
///
|
||||||
/// NOTE: This does not check the validity of `seal` with the engine.
|
/// NOTE: This does not check the validity of `seal` with the engine.
|
||||||
pub fn seal(self, seal: Vec<Bytes>) -> Result<SealedBlock, BlockError> {
|
pub fn seal(self, engine: &Engine, seal: Vec<Bytes>) -> Result<SealedBlock, BlockError> {
|
||||||
let mut s = self;
|
let mut s = self;
|
||||||
if seal.len() != s.open_block.engine.seal_fields() {
|
if seal.len() != engine.seal_fields() {
|
||||||
return Err(BlockError::InvalidSealArity(Mismatch{expected: s.open_block.engine.seal_fields(), found: seal.len()}));
|
return Err(BlockError::InvalidSealArity(Mismatch{expected: engine.seal_fields(), found: seal.len()}));
|
||||||
}
|
}
|
||||||
s.open_block.block.base.header.set_seal(seal);
|
s.block.base.header.set_seal(seal);
|
||||||
Ok(SealedBlock { block: s.open_block.block, uncle_bytes: s.uncle_bytes })
|
Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turn this back into an `OpenBlock`.
|
/// Provide a valid seal in order to turn this into a `SealedBlock`.
|
||||||
pub fn reopen(self) -> OpenBlock<'x, 'y> { self.open_block }
|
/// This does check the validity of `seal` with the engine.
|
||||||
|
/// Returns the `ClosedBlock` back again if the seal is no good.
|
||||||
|
pub fn try_seal(self, engine: &Engine, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
|
||||||
|
let mut s = self;
|
||||||
|
s.block.base.header.set_seal(seal);
|
||||||
|
match engine.verify_block_seal(&s.block.base.header) {
|
||||||
|
Err(_) => Err(s),
|
||||||
|
_ => Ok(SealedBlock { block: s.block, uncle_bytes: s.uncle_bytes }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Drop this object and return the underlieing database.
|
/// Drop this object and return the underlieing database.
|
||||||
pub fn drain(self) -> JournalDB { self.open_block.block.state.drop().1 }
|
pub fn drain(self) -> Box<JournalDB> { self.block.state.drop().1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SealedBlock {
|
impl SealedBlock {
|
||||||
@ -324,7 +345,7 @@ impl SealedBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Drop this object and return the underlieing database.
|
/// Drop this object and return the underlieing database.
|
||||||
pub fn drain(self) -> JournalDB { self.block.state.drop().1 }
|
pub fn drain(self) -> Box<JournalDB> { self.block.state.drop().1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsBlock for SealedBlock {
|
impl IsBlock for SealedBlock {
|
||||||
@ -332,15 +353,15 @@ impl IsBlock for SealedBlock {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by block header, transactions and uncles
|
/// Enact the block given by block header, transactions and uncles
|
||||||
pub fn enact<'x, 'y>(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &'x Engine, db: JournalDB, parent: &Header, last_hashes: &'y LastHashes) -> Result<ClosedBlock<'x, 'y>, Error> {
|
pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
|
||||||
{
|
{
|
||||||
if ::log::max_log_level() >= ::log::LogLevel::Trace {
|
if ::log::max_log_level() >= ::log::LogLevel::Trace {
|
||||||
let s = State::from_existing(db.clone(), parent.state_root().clone(), engine.account_start_nonce());
|
let s = State::from_existing(db.spawn(), parent.state_root().clone(), engine.account_start_nonce());
|
||||||
trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()));
|
trace!("enact(): root={}, author={}, author_balance={}\n", s.root(), header.author(), s.balance(&header.author()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut b = OpenBlock::new(engine, db, parent, last_hashes, header.author().clone(), header.extra_data().clone());
|
let mut b = OpenBlock::new(engine, tracing, db, parent, last_hashes, header.author().clone(), x!(3141562), header.extra_data().clone());
|
||||||
b.set_difficulty(*header.difficulty());
|
b.set_difficulty(*header.difficulty());
|
||||||
b.set_gas_limit(*header.gas_limit());
|
b.set_gas_limit(*header.gas_limit());
|
||||||
b.set_timestamp(header.timestamp());
|
b.set_timestamp(header.timestamp());
|
||||||
@ -350,22 +371,22 @@ pub fn enact<'x, 'y>(header: &Header, transactions: &[SignedTransaction], uncles
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||||
pub fn enact_bytes<'x, 'y>(block_bytes: &[u8], engine: &'x Engine, db: JournalDB, parent: &Header, last_hashes: &'y LastHashes) -> Result<ClosedBlock<'x, 'y>, Error> {
|
pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
|
||||||
let block = BlockView::new(block_bytes);
|
let block = BlockView::new(block_bytes);
|
||||||
let header = block.header();
|
let header = block.header();
|
||||||
enact(&header, &block.transactions(), &block.uncles(), engine, db, parent, last_hashes)
|
enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||||
pub fn enact_verified<'x, 'y>(block: &PreVerifiedBlock, engine: &'x Engine, db: JournalDB, parent: &Header, last_hashes: &'y LastHashes) -> Result<ClosedBlock<'x, 'y>, Error> {
|
pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<ClosedBlock, Error> {
|
||||||
let view = BlockView::new(&block.bytes);
|
let view = BlockView::new(&block.bytes);
|
||||||
enact(&block.header, &block.transactions, &view.uncles(), engine, db, parent, last_hashes)
|
enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
|
||||||
pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, db: JournalDB, parent: &Header, last_hashes: &LastHashes) -> Result<SealedBlock, Error> {
|
pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes) -> Result<SealedBlock, Error> {
|
||||||
let header = BlockView::new(block_bytes).header_view();
|
let header = BlockView::new(block_bytes).header_view();
|
||||||
Ok(try!(try!(enact_bytes(block_bytes, engine, db, parent, last_hashes)).seal(header.seal())))
|
Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes)).seal(engine, header.seal())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -382,11 +403,11 @@ mod tests {
|
|||||||
let genesis_header = engine.spec().genesis_header();
|
let genesis_header = engine.spec().genesis_header();
|
||||||
let mut db_result = get_temp_journal_db();
|
let mut db_result = get_temp_journal_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
engine.spec().ensure_db_good(&mut db);
|
engine.spec().ensure_db_good(db.as_hashdb_mut());
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
|
let b = OpenBlock::new(engine.deref(), false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]);
|
||||||
let b = b.close();
|
let b = b.close();
|
||||||
let _ = b.seal(vec![]);
|
let _ = b.seal(engine.deref(), vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -397,15 +418,15 @@ mod tests {
|
|||||||
|
|
||||||
let mut db_result = get_temp_journal_db();
|
let mut db_result = get_temp_journal_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
engine.spec().ensure_db_good(&mut db);
|
engine.spec().ensure_db_good(db.as_hashdb_mut());
|
||||||
let b = OpenBlock::new(engine.deref(), db, &genesis_header, &vec![genesis_header.hash()], Address::zero(), vec![]).close().seal(vec![]).unwrap();
|
let b = OpenBlock::new(engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]).close().seal(engine.deref(), vec![]).unwrap();
|
||||||
let orig_bytes = b.rlp_bytes();
|
let orig_bytes = b.rlp_bytes();
|
||||||
let orig_db = b.drain();
|
let orig_db = b.drain();
|
||||||
|
|
||||||
let mut db_result = get_temp_journal_db();
|
let mut db_result = get_temp_journal_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
engine.spec().ensure_db_good(&mut db);
|
engine.spec().ensure_db_good(db.as_hashdb_mut());
|
||||||
let e = enact_and_seal(&orig_bytes, engine.deref(), db, &genesis_header, &vec![genesis_header.hash()]).unwrap();
|
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()]).unwrap();
|
||||||
|
|
||||||
assert_eq!(e.rlp_bytes(), orig_bytes);
|
assert_eq!(e.rlp_bytes(), orig_bytes);
|
||||||
|
|
||||||
@ -413,4 +434,40 @@ mod tests {
|
|||||||
assert_eq!(orig_db.keys(), db.keys());
|
assert_eq!(orig_db.keys(), db.keys());
|
||||||
assert!(orig_db.keys().iter().filter(|k| orig_db.get(k.0) != db.get(k.0)).next() == None);
|
assert!(orig_db.keys().iter().filter(|k| orig_db.get(k.0) != db.get(k.0)).next() == None);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn enact_block_with_uncle() {
|
||||||
|
use spec::*;
|
||||||
|
let engine = Spec::new_test().to_engine().unwrap();
|
||||||
|
let genesis_header = engine.spec().genesis_header();
|
||||||
|
|
||||||
|
let mut db_result = get_temp_journal_db();
|
||||||
|
let mut db = db_result.take();
|
||||||
|
engine.spec().ensure_db_good(db.as_hashdb_mut());
|
||||||
|
let mut open_block = OpenBlock::new(engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), x!(3141562), vec![]);
|
||||||
|
let mut uncle1_header = Header::new();
|
||||||
|
uncle1_header.extra_data = b"uncle1".to_vec();
|
||||||
|
let mut uncle2_header = Header::new();
|
||||||
|
uncle2_header.extra_data = b"uncle2".to_vec();
|
||||||
|
open_block.push_uncle(uncle1_header).unwrap();
|
||||||
|
open_block.push_uncle(uncle2_header).unwrap();
|
||||||
|
let b = open_block.close().seal(engine.deref(), vec![]).unwrap();
|
||||||
|
|
||||||
|
let orig_bytes = b.rlp_bytes();
|
||||||
|
let orig_db = b.drain();
|
||||||
|
|
||||||
|
let mut db_result = get_temp_journal_db();
|
||||||
|
let mut db = db_result.take();
|
||||||
|
engine.spec().ensure_db_good(db.as_hashdb_mut());
|
||||||
|
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()]).unwrap();
|
||||||
|
|
||||||
|
let bytes = e.rlp_bytes();
|
||||||
|
assert_eq!(bytes, orig_bytes);
|
||||||
|
let uncles = BlockView::new(&bytes).uncles();
|
||||||
|
assert_eq!(uncles[1].extra_data, b"uncle2");
|
||||||
|
|
||||||
|
let db = e.drain();
|
||||||
|
assert_eq!(orig_db.keys(), db.keys());
|
||||||
|
assert!(orig_db.keys().iter().filter(|k| orig_db.get(k.0) != db.get(k.0)).next() == None);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,31 @@ use service::*;
|
|||||||
use client::BlockStatus;
|
use client::BlockStatus;
|
||||||
use util::panics::*;
|
use util::panics::*;
|
||||||
|
|
||||||
|
known_heap_size!(0, UnverifiedBlock, VerifyingBlock, PreverifiedBlock);
|
||||||
|
|
||||||
|
const MIN_MEM_LIMIT: usize = 16384;
|
||||||
|
const MIN_QUEUE_LIMIT: usize = 512;
|
||||||
|
|
||||||
|
/// Block queue configuration
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BlockQueueConfig {
|
||||||
|
/// Maximum number of blocks to keep in unverified queue.
|
||||||
|
/// When the limit is reached, is_full returns true.
|
||||||
|
pub max_queue_size: usize,
|
||||||
|
/// Maximum heap memory to use.
|
||||||
|
/// When the limit is reached, is_full returns true.
|
||||||
|
pub max_mem_use: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BlockQueueConfig {
|
||||||
|
fn default() -> Self {
|
||||||
|
BlockQueueConfig {
|
||||||
|
max_queue_size: 30000,
|
||||||
|
max_mem_use: 50 * 1024 * 1024,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Block queue status
|
/// Block queue status
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BlockQueueInfo {
|
pub struct BlockQueueInfo {
|
||||||
@ -37,6 +62,12 @@ pub struct BlockQueueInfo {
|
|||||||
pub verified_queue_size: usize,
|
pub verified_queue_size: usize,
|
||||||
/// Number of blocks being verified
|
/// Number of blocks being verified
|
||||||
pub verifying_queue_size: usize,
|
pub verifying_queue_size: usize,
|
||||||
|
/// Configured maximum number of blocks in the queue
|
||||||
|
pub max_queue_size: usize,
|
||||||
|
/// Configured maximum number of bytes to use
|
||||||
|
pub max_mem_use: usize,
|
||||||
|
/// Heap memory used in bytes
|
||||||
|
pub mem_used: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockQueueInfo {
|
impl BlockQueueInfo {
|
||||||
@ -48,7 +79,8 @@ impl BlockQueueInfo {
|
|||||||
|
|
||||||
/// Indicates that queue is full
|
/// Indicates that queue is full
|
||||||
pub fn is_full(&self) -> bool {
|
pub fn is_full(&self) -> bool {
|
||||||
self.unverified_queue_size + self.verified_queue_size + self.verifying_queue_size > MAX_UNVERIFIED_QUEUE_SIZE
|
self.unverified_queue_size + self.verified_queue_size + self.verifying_queue_size > self.max_queue_size ||
|
||||||
|
self.mem_used > self.max_mem_use
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Indicates that queue is empty
|
/// Indicates that queue is empty
|
||||||
@ -63,22 +95,24 @@ pub struct BlockQueue {
|
|||||||
panic_handler: Arc<PanicHandler>,
|
panic_handler: Arc<PanicHandler>,
|
||||||
engine: Arc<Box<Engine>>,
|
engine: Arc<Box<Engine>>,
|
||||||
more_to_verify: Arc<Condvar>,
|
more_to_verify: Arc<Condvar>,
|
||||||
verification: Arc<Mutex<Verification>>,
|
verification: Arc<Verification>,
|
||||||
verifiers: Vec<JoinHandle<()>>,
|
verifiers: Vec<JoinHandle<()>>,
|
||||||
deleting: Arc<AtomicBool>,
|
deleting: Arc<AtomicBool>,
|
||||||
ready_signal: Arc<QueueSignal>,
|
ready_signal: Arc<QueueSignal>,
|
||||||
empty: Arc<Condvar>,
|
empty: Arc<Condvar>,
|
||||||
processing: RwLock<HashSet<H256>>
|
processing: RwLock<HashSet<H256>>,
|
||||||
|
max_queue_size: usize,
|
||||||
|
max_mem_use: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UnVerifiedBlock {
|
struct UnverifiedBlock {
|
||||||
header: Header,
|
header: Header,
|
||||||
bytes: Bytes,
|
bytes: Bytes,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VerifyingBlock {
|
struct VerifyingBlock {
|
||||||
hash: H256,
|
hash: H256,
|
||||||
block: Option<PreVerifiedBlock>,
|
block: Option<PreverifiedBlock>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct QueueSignal {
|
struct QueueSignal {
|
||||||
@ -87,7 +121,7 @@ struct QueueSignal {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl QueueSignal {
|
impl QueueSignal {
|
||||||
#[allow(bool_comparison)]
|
#[cfg_attr(feature="dev", allow(bool_comparison))]
|
||||||
fn set(&self) {
|
fn set(&self) {
|
||||||
if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false {
|
if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false {
|
||||||
self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message");
|
self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message");
|
||||||
@ -98,20 +132,23 @@ impl QueueSignal {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default)]
|
|
||||||
struct Verification {
|
struct Verification {
|
||||||
unverified: VecDeque<UnVerifiedBlock>,
|
// All locks must be captured in the order declared here.
|
||||||
verified: VecDeque<PreVerifiedBlock>,
|
unverified: Mutex<VecDeque<UnverifiedBlock>>,
|
||||||
verifying: VecDeque<VerifyingBlock>,
|
verified: Mutex<VecDeque<PreverifiedBlock>>,
|
||||||
bad: HashSet<H256>,
|
verifying: Mutex<VecDeque<VerifyingBlock>>,
|
||||||
|
bad: Mutex<HashSet<H256>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const MAX_UNVERIFIED_QUEUE_SIZE: usize = 50000;
|
|
||||||
|
|
||||||
impl BlockQueue {
|
impl BlockQueue {
|
||||||
/// Creates a new queue instance.
|
/// Creates a new queue instance.
|
||||||
pub fn new(engine: Arc<Box<Engine>>, message_channel: IoChannel<NetSyncMessage>) -> BlockQueue {
|
pub fn new(config: BlockQueueConfig, engine: Arc<Box<Engine>>, message_channel: IoChannel<NetSyncMessage>) -> BlockQueue {
|
||||||
let verification = Arc::new(Mutex::new(Verification::default()));
|
let verification = Arc::new(Verification {
|
||||||
|
unverified: Mutex::new(VecDeque::new()),
|
||||||
|
verified: Mutex::new(VecDeque::new()),
|
||||||
|
verifying: Mutex::new(VecDeque::new()),
|
||||||
|
bad: Mutex::new(HashSet::new()),
|
||||||
|
});
|
||||||
let more_to_verify = Arc::new(Condvar::new());
|
let more_to_verify = Arc::new(Condvar::new());
|
||||||
let ready_signal = Arc::new(QueueSignal { signalled: AtomicBool::new(false), message_channel: message_channel });
|
let ready_signal = Arc::new(QueueSignal { signalled: AtomicBool::new(false), message_channel: message_channel });
|
||||||
let deleting = Arc::new(AtomicBool::new(false));
|
let deleting = Arc::new(AtomicBool::new(false));
|
||||||
@ -133,7 +170,7 @@ impl BlockQueue {
|
|||||||
.name(format!("Verifier #{}", i))
|
.name(format!("Verifier #{}", i))
|
||||||
.spawn(move || {
|
.spawn(move || {
|
||||||
panic_handler.catch_panic(move || {
|
panic_handler.catch_panic(move || {
|
||||||
BlockQueue::verify(verification, engine, more_to_verify, ready_signal, deleting, empty)
|
BlockQueue::verify(verification, engine, more_to_verify, ready_signal, deleting, empty)
|
||||||
}).unwrap()
|
}).unwrap()
|
||||||
})
|
})
|
||||||
.expect("Error starting block verification thread")
|
.expect("Error starting block verification thread")
|
||||||
@ -149,68 +186,73 @@ impl BlockQueue {
|
|||||||
deleting: deleting.clone(),
|
deleting: deleting.clone(),
|
||||||
processing: RwLock::new(HashSet::new()),
|
processing: RwLock::new(HashSet::new()),
|
||||||
empty: empty.clone(),
|
empty: empty.clone(),
|
||||||
|
max_queue_size: max(config.max_queue_size, MIN_QUEUE_LIMIT),
|
||||||
|
max_mem_use: max(config.max_mem_use, MIN_MEM_LIMIT),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(verification: Arc<Mutex<Verification>>, engine: Arc<Box<Engine>>, wait: Arc<Condvar>, ready: Arc<QueueSignal>, deleting: Arc<AtomicBool>, empty: Arc<Condvar>) {
|
fn verify(verification: Arc<Verification>, engine: Arc<Box<Engine>>, wait: Arc<Condvar>, ready: Arc<QueueSignal>, deleting: Arc<AtomicBool>, empty: Arc<Condvar>) {
|
||||||
while !deleting.load(AtomicOrdering::Relaxed) {
|
while !deleting.load(AtomicOrdering::Acquire) {
|
||||||
{
|
{
|
||||||
let mut lock = verification.lock().unwrap();
|
let mut unverified = verification.unverified.lock().unwrap();
|
||||||
|
|
||||||
if lock.unverified.is_empty() && lock.verifying.is_empty() {
|
if unverified.is_empty() && verification.verifying.lock().unwrap().is_empty() {
|
||||||
empty.notify_all();
|
empty.notify_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
while lock.unverified.is_empty() && !deleting.load(AtomicOrdering::Relaxed) {
|
while unverified.is_empty() && !deleting.load(AtomicOrdering::Acquire) {
|
||||||
lock = wait.wait(lock).unwrap();
|
unverified = wait.wait(unverified).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
if deleting.load(AtomicOrdering::Relaxed) {
|
if deleting.load(AtomicOrdering::Acquire) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let block = {
|
let block = {
|
||||||
let mut v = verification.lock().unwrap();
|
let mut unverified = verification.unverified.lock().unwrap();
|
||||||
if v.unverified.is_empty() {
|
if unverified.is_empty() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let block = v.unverified.pop_front().unwrap();
|
let mut verifying = verification.verifying.lock().unwrap();
|
||||||
v.verifying.push_back(VerifyingBlock{ hash: block.header.hash(), block: None });
|
let block = unverified.pop_front().unwrap();
|
||||||
|
verifying.push_back(VerifyingBlock{ hash: block.header.hash(), block: None });
|
||||||
block
|
block
|
||||||
};
|
};
|
||||||
|
|
||||||
let block_hash = block.header.hash();
|
let block_hash = block.header.hash();
|
||||||
match verify_block_unordered(block.header, block.bytes, engine.deref().deref()) {
|
match verify_block_unordered(block.header, block.bytes, engine.deref().deref()) {
|
||||||
Ok(verified) => {
|
Ok(verified) => {
|
||||||
let mut v = verification.lock().unwrap();
|
let mut verifying = verification.verifying.lock().unwrap();
|
||||||
for e in &mut v.verifying {
|
for e in verifying.iter_mut() {
|
||||||
if e.hash == block_hash {
|
if e.hash == block_hash {
|
||||||
e.block = Some(verified);
|
e.block = Some(verified);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !v.verifying.is_empty() && v.verifying.front().unwrap().hash == block_hash {
|
if !verifying.is_empty() && verifying.front().unwrap().hash == block_hash {
|
||||||
// we're next!
|
// we're next!
|
||||||
let mut vref = v.deref_mut();
|
let mut verified = verification.verified.lock().unwrap();
|
||||||
BlockQueue::drain_verifying(&mut vref.verifying, &mut vref.verified, &mut vref.bad);
|
let mut bad = verification.bad.lock().unwrap();
|
||||||
|
BlockQueue::drain_verifying(&mut verifying, &mut verified, &mut bad);
|
||||||
ready.set();
|
ready.set();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let mut v = verification.lock().unwrap();
|
let mut verifying = verification.verifying.lock().unwrap();
|
||||||
|
let mut verified = verification.verified.lock().unwrap();
|
||||||
|
let mut bad = verification.bad.lock().unwrap();
|
||||||
warn!(target: "client", "Stage 2 block verification failed for {}\nError: {:?}", block_hash, err);
|
warn!(target: "client", "Stage 2 block verification failed for {}\nError: {:?}", block_hash, err);
|
||||||
v.bad.insert(block_hash.clone());
|
bad.insert(block_hash.clone());
|
||||||
v.verifying.retain(|e| e.hash != block_hash);
|
verifying.retain(|e| e.hash != block_hash);
|
||||||
let mut vref = v.deref_mut();
|
BlockQueue::drain_verifying(&mut verifying, &mut verified, &mut bad);
|
||||||
BlockQueue::drain_verifying(&mut vref.verifying, &mut vref.verified, &mut vref.bad);
|
|
||||||
ready.set();
|
ready.set();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn drain_verifying(verifying: &mut VecDeque<VerifyingBlock>, verified: &mut VecDeque<PreVerifiedBlock>, bad: &mut HashSet<H256>) {
|
fn drain_verifying(verifying: &mut VecDeque<VerifyingBlock>, verified: &mut VecDeque<PreverifiedBlock>, bad: &mut HashSet<H256>) {
|
||||||
while !verifying.is_empty() && verifying.front().unwrap().block.is_some() {
|
while !verifying.is_empty() && verifying.front().unwrap().block.is_some() {
|
||||||
let block = verifying.pop_front().unwrap().block.unwrap();
|
let block = verifying.pop_front().unwrap().block.unwrap();
|
||||||
if bad.contains(&block.header.parent_hash) {
|
if bad.contains(&block.header.parent_hash) {
|
||||||
@ -223,19 +265,21 @@ impl BlockQueue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Clear the queue and stop verification activity.
|
/// Clear the queue and stop verification activity.
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&self) {
|
||||||
let mut verification = self.verification.lock().unwrap();
|
let mut unverified = self.verification.unverified.lock().unwrap();
|
||||||
verification.unverified.clear();
|
let mut verifying = self.verification.verifying.lock().unwrap();
|
||||||
verification.verifying.clear();
|
let mut verified = self.verification.verified.lock().unwrap();
|
||||||
verification.verified.clear();
|
unverified.clear();
|
||||||
|
verifying.clear();
|
||||||
|
verified.clear();
|
||||||
self.processing.write().unwrap().clear();
|
self.processing.write().unwrap().clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wait for queue to be empty
|
/// Wait for unverified queue to be empty
|
||||||
pub fn flush(&mut self) {
|
pub fn flush(&self) {
|
||||||
let mut verification = self.verification.lock().unwrap();
|
let mut unverified = self.verification.unverified.lock().unwrap();
|
||||||
while !verification.unverified.is_empty() || !verification.verifying.is_empty() {
|
while !unverified.is_empty() || !self.verification.verifying.lock().unwrap().is_empty() {
|
||||||
verification = self.empty.wait(verification).unwrap();
|
unverified = self.empty.wait(unverified).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,84 +288,96 @@ impl BlockQueue {
|
|||||||
if self.processing.read().unwrap().contains(&hash) {
|
if self.processing.read().unwrap().contains(&hash) {
|
||||||
return BlockStatus::Queued;
|
return BlockStatus::Queued;
|
||||||
}
|
}
|
||||||
if self.verification.lock().unwrap().bad.contains(&hash) {
|
if self.verification.bad.lock().unwrap().contains(&hash) {
|
||||||
return BlockStatus::Bad;
|
return BlockStatus::Bad;
|
||||||
}
|
}
|
||||||
BlockStatus::Unknown
|
BlockStatus::Unknown
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a block to the queue.
|
/// Add a block to the queue.
|
||||||
pub fn import_block(&mut self, bytes: Bytes) -> ImportResult {
|
pub fn import_block(&self, bytes: Bytes) -> ImportResult {
|
||||||
let header = BlockView::new(&bytes).header();
|
let header = BlockView::new(&bytes).header();
|
||||||
let h = header.hash();
|
let h = header.hash();
|
||||||
if self.processing.read().unwrap().contains(&h) {
|
|
||||||
return Err(ImportError::AlreadyQueued);
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
let mut verification = self.verification.lock().unwrap();
|
if self.processing.read().unwrap().contains(&h) {
|
||||||
if verification.bad.contains(&h) {
|
return Err(x!(ImportError::AlreadyQueued));
|
||||||
return Err(ImportError::Bad(None));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if verification.bad.contains(&header.parent_hash) {
|
let mut bad = self.verification.bad.lock().unwrap();
|
||||||
verification.bad.insert(h.clone());
|
if bad.contains(&h) {
|
||||||
return Err(ImportError::Bad(None));
|
return Err(x!(ImportError::KnownBad));
|
||||||
|
}
|
||||||
|
|
||||||
|
if bad.contains(&header.parent_hash) {
|
||||||
|
bad.insert(h.clone());
|
||||||
|
return Err(x!(ImportError::KnownBad));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
match verify_block_basic(&header, &bytes, self.engine.deref().deref()) {
|
match verify_block_basic(&header, &bytes, self.engine.deref().deref()) {
|
||||||
Ok(()) => {
|
Ok(()) => {
|
||||||
self.processing.write().unwrap().insert(h.clone());
|
self.processing.write().unwrap().insert(h.clone());
|
||||||
self.verification.lock().unwrap().unverified.push_back(UnVerifiedBlock { header: header, bytes: bytes });
|
self.verification.unverified.lock().unwrap().push_back(UnverifiedBlock { header: header, bytes: bytes });
|
||||||
self.more_to_verify.notify_all();
|
self.more_to_verify.notify_all();
|
||||||
Ok(h)
|
Ok(h)
|
||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
warn!(target: "client", "Stage 1 block verification failed for {}\nError: {:?}", BlockView::new(&bytes).header_view().sha3(), err);
|
warn!(target: "client", "Stage 1 block verification failed for {}\nError: {:?}", BlockView::new(&bytes).header_view().sha3(), err);
|
||||||
self.verification.lock().unwrap().bad.insert(h.clone());
|
self.verification.bad.lock().unwrap().insert(h.clone());
|
||||||
Err(From::from(err))
|
Err(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark given block and all its children as bad. Stops verification.
|
/// Mark given block and all its children as bad. Stops verification.
|
||||||
pub fn mark_as_bad(&mut self, hash: &H256) {
|
pub fn mark_as_bad(&self, block_hashes: &[H256]) {
|
||||||
let mut verification_lock = self.verification.lock().unwrap();
|
if block_hashes.is_empty() {
|
||||||
let mut verification = verification_lock.deref_mut();
|
return;
|
||||||
verification.bad.insert(hash.clone());
|
}
|
||||||
self.processing.write().unwrap().remove(&hash);
|
let mut verified_lock = self.verification.verified.lock().unwrap();
|
||||||
|
let mut verified = verified_lock.deref_mut();
|
||||||
|
let mut bad = self.verification.bad.lock().unwrap();
|
||||||
|
let mut processing = self.processing.write().unwrap();
|
||||||
|
bad.reserve(block_hashes.len());
|
||||||
|
for hash in block_hashes {
|
||||||
|
bad.insert(hash.clone());
|
||||||
|
processing.remove(&hash);
|
||||||
|
}
|
||||||
|
|
||||||
let mut new_verified = VecDeque::new();
|
let mut new_verified = VecDeque::new();
|
||||||
for block in verification.verified.drain(..) {
|
for block in verified.drain(..) {
|
||||||
if verification.bad.contains(&block.header.parent_hash) {
|
if bad.contains(&block.header.parent_hash) {
|
||||||
verification.bad.insert(block.header.hash());
|
bad.insert(block.header.hash());
|
||||||
self.processing.write().unwrap().remove(&block.header.hash());
|
processing.remove(&block.header.hash());
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
new_verified.push_back(block);
|
new_verified.push_back(block);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
verification.verified = new_verified;
|
*verified = new_verified;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mark given block as processed
|
/// Mark given block as processed
|
||||||
pub fn mark_as_good(&mut self, hashes: &[H256]) {
|
pub fn mark_as_good(&self, block_hashes: &[H256]) {
|
||||||
|
if block_hashes.is_empty() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
let mut processing = self.processing.write().unwrap();
|
let mut processing = self.processing.write().unwrap();
|
||||||
for h in hashes {
|
for hash in block_hashes {
|
||||||
processing.remove(&h);
|
processing.remove(&hash);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Removes up to `max` verified blocks from the queue
|
/// Removes up to `max` verified blocks from the queue
|
||||||
pub fn drain(&mut self, max: usize) -> Vec<PreVerifiedBlock> {
|
pub fn drain(&self, max: usize) -> Vec<PreverifiedBlock> {
|
||||||
let mut verification = self.verification.lock().unwrap();
|
let mut verified = self.verification.verified.lock().unwrap();
|
||||||
let count = min(max, verification.verified.len());
|
let count = min(max, verified.len());
|
||||||
let mut result = Vec::with_capacity(count);
|
let mut result = Vec::with_capacity(count);
|
||||||
for _ in 0..count {
|
for _ in 0..count {
|
||||||
let block = verification.verified.pop_front().unwrap();
|
let block = verified.pop_front().unwrap();
|
||||||
result.push(block);
|
result.push(block);
|
||||||
}
|
}
|
||||||
self.ready_signal.reset();
|
self.ready_signal.reset();
|
||||||
if !verification.verified.is_empty() {
|
if !verified.is_empty() {
|
||||||
self.ready_signal.set();
|
self.ready_signal.set();
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
@ -329,13 +385,42 @@ impl BlockQueue {
|
|||||||
|
|
||||||
/// Get queue status.
|
/// Get queue status.
|
||||||
pub fn queue_info(&self) -> BlockQueueInfo {
|
pub fn queue_info(&self) -> BlockQueueInfo {
|
||||||
let verification = self.verification.lock().unwrap();
|
let (unverified_len, unverified_bytes) = {
|
||||||
|
let v = self.verification.unverified.lock().unwrap();
|
||||||
|
(v.len(), v.heap_size_of_children())
|
||||||
|
};
|
||||||
|
let (verifying_len, verifying_bytes) = {
|
||||||
|
let v = self.verification.verifying.lock().unwrap();
|
||||||
|
(v.len(), v.heap_size_of_children())
|
||||||
|
};
|
||||||
|
let (verified_len, verified_bytes) = {
|
||||||
|
let v = self.verification.verified.lock().unwrap();
|
||||||
|
(v.len(), v.heap_size_of_children())
|
||||||
|
};
|
||||||
BlockQueueInfo {
|
BlockQueueInfo {
|
||||||
verified_queue_size: verification.verified.len(),
|
unverified_queue_size: unverified_len,
|
||||||
unverified_queue_size: verification.unverified.len(),
|
verifying_queue_size: verifying_len,
|
||||||
verifying_queue_size: verification.verifying.len(),
|
verified_queue_size: verified_len,
|
||||||
|
max_queue_size: self.max_queue_size,
|
||||||
|
max_mem_use: self.max_mem_use,
|
||||||
|
mem_used:
|
||||||
|
unverified_bytes
|
||||||
|
+ verifying_bytes
|
||||||
|
+ verified_bytes
|
||||||
|
// TODO: https://github.com/servo/heapsize/pull/50
|
||||||
|
//+ self.processing.read().unwrap().heap_size_of_children(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Optimise memory footprint of the heap fields.
|
||||||
|
pub fn collect_garbage(&self) {
|
||||||
|
{
|
||||||
|
self.verification.unverified.lock().unwrap().shrink_to_fit();
|
||||||
|
self.verification.verifying.lock().unwrap().shrink_to_fit();
|
||||||
|
self.verification.verified.lock().unwrap().shrink_to_fit();
|
||||||
|
}
|
||||||
|
self.processing.write().unwrap().shrink_to_fit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MayPanic for BlockQueue {
|
impl MayPanic for BlockQueue {
|
||||||
@ -347,7 +432,7 @@ impl MayPanic for BlockQueue {
|
|||||||
impl Drop for BlockQueue {
|
impl Drop for BlockQueue {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.clear();
|
self.clear();
|
||||||
self.deleting.store(true, AtomicOrdering::Relaxed);
|
self.deleting.store(true, AtomicOrdering::Release);
|
||||||
self.more_to_verify.notify_all();
|
self.more_to_verify.notify_all();
|
||||||
for t in self.verifiers.drain(..) {
|
for t in self.verifiers.drain(..) {
|
||||||
t.join().unwrap();
|
t.join().unwrap();
|
||||||
@ -367,7 +452,7 @@ mod tests {
|
|||||||
fn get_test_queue() -> BlockQueue {
|
fn get_test_queue() -> BlockQueue {
|
||||||
let spec = get_test_spec();
|
let spec = get_test_spec();
|
||||||
let engine = spec.to_engine().unwrap();
|
let engine = spec.to_engine().unwrap();
|
||||||
BlockQueue::new(Arc::new(engine), IoChannel::disconnected())
|
BlockQueue::new(BlockQueueConfig::default(), Arc::new(engine), IoChannel::disconnected())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -375,12 +460,12 @@ mod tests {
|
|||||||
// TODO better test
|
// TODO better test
|
||||||
let spec = Spec::new_test();
|
let spec = Spec::new_test();
|
||||||
let engine = spec.to_engine().unwrap();
|
let engine = spec.to_engine().unwrap();
|
||||||
let _ = BlockQueue::new(Arc::new(engine), IoChannel::disconnected());
|
let _ = BlockQueue::new(BlockQueueConfig::default(), Arc::new(engine), IoChannel::disconnected());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_import_blocks() {
|
fn can_import_blocks() {
|
||||||
let mut queue = get_test_queue();
|
let queue = get_test_queue();
|
||||||
if let Err(e) = queue.import_block(get_good_dummy_block()) {
|
if let Err(e) = queue.import_block(get_good_dummy_block()) {
|
||||||
panic!("error importing block that is valid by definition({:?})", e);
|
panic!("error importing block that is valid by definition({:?})", e);
|
||||||
}
|
}
|
||||||
@ -388,7 +473,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn returns_error_for_duplicates() {
|
fn returns_error_for_duplicates() {
|
||||||
let mut queue = get_test_queue();
|
let queue = get_test_queue();
|
||||||
if let Err(e) = queue.import_block(get_good_dummy_block()) {
|
if let Err(e) = queue.import_block(get_good_dummy_block()) {
|
||||||
panic!("error importing block that is valid by definition({:?})", e);
|
panic!("error importing block that is valid by definition({:?})", e);
|
||||||
}
|
}
|
||||||
@ -397,7 +482,7 @@ mod tests {
|
|||||||
match duplicate_import {
|
match duplicate_import {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
match e {
|
match e {
|
||||||
ImportError::AlreadyQueued => {},
|
Error::Import(ImportError::AlreadyQueued) => {},
|
||||||
_ => { panic!("must return AlreadyQueued error"); }
|
_ => { panic!("must return AlreadyQueued error"); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -407,7 +492,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn returns_ok_for_drained_duplicates() {
|
fn returns_ok_for_drained_duplicates() {
|
||||||
let mut queue = get_test_queue();
|
let queue = get_test_queue();
|
||||||
let block = get_good_dummy_block();
|
let block = get_good_dummy_block();
|
||||||
let hash = BlockView::new(&block).header().hash().clone();
|
let hash = BlockView::new(&block).header().hash().clone();
|
||||||
if let Err(e) = queue.import_block(block) {
|
if let Err(e) = queue.import_block(block) {
|
||||||
@ -424,11 +509,26 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn returns_empty_once_finished() {
|
fn returns_empty_once_finished() {
|
||||||
let mut queue = get_test_queue();
|
let queue = get_test_queue();
|
||||||
queue.import_block(get_good_dummy_block()).expect("error importing block that is valid by definition");
|
queue.import_block(get_good_dummy_block()).expect("error importing block that is valid by definition");
|
||||||
queue.flush();
|
queue.flush();
|
||||||
queue.drain(1);
|
queue.drain(1);
|
||||||
|
|
||||||
assert!(queue.queue_info().is_empty());
|
assert!(queue.queue_info().is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mem_limit() {
|
||||||
|
let spec = get_test_spec();
|
||||||
|
let engine = spec.to_engine().unwrap();
|
||||||
|
let mut config = BlockQueueConfig::default();
|
||||||
|
config.max_mem_use = super::MIN_MEM_LIMIT; // empty queue uses about 15000
|
||||||
|
let queue = BlockQueue::new(config, Arc::new(engine), IoChannel::disconnected());
|
||||||
|
assert!(!queue.queue_info().is_full());
|
||||||
|
let mut blocks = get_good_dummy_block_seq(50);
|
||||||
|
for b in blocks.drain(..) {
|
||||||
|
queue.import_block(b).unwrap();
|
||||||
|
}
|
||||||
|
assert!(queue.queue_info().is_full());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,865 +0,0 @@
|
|||||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Blockchain database.
|
|
||||||
|
|
||||||
use util::*;
|
|
||||||
use rocksdb::{DB, WriteBatch, Writable};
|
|
||||||
use header::*;
|
|
||||||
use extras::*;
|
|
||||||
use transaction::*;
|
|
||||||
use views::*;
|
|
||||||
|
|
||||||
/// Represents a tree route between `from` block and `to` block:
|
|
||||||
pub struct TreeRoute {
|
|
||||||
/// A vector of hashes of all blocks, ordered from `from` to `to`.
|
|
||||||
pub blocks: Vec<H256>,
|
|
||||||
/// Best common ancestor of these blocks.
|
|
||||||
pub ancestor: H256,
|
|
||||||
/// An index where best common ancestor would be.
|
|
||||||
pub index: usize
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents blockchain's in-memory cache size in bytes.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct CacheSize {
|
|
||||||
/// Blocks cache size.
|
|
||||||
pub blocks: usize,
|
|
||||||
/// BlockDetails cache size.
|
|
||||||
pub block_details: usize,
|
|
||||||
/// Transaction addresses cache size.
|
|
||||||
pub transaction_addresses: usize,
|
|
||||||
/// Logs cache size.
|
|
||||||
pub block_logs: usize,
|
|
||||||
/// Blooms cache size.
|
|
||||||
pub blocks_blooms: usize
|
|
||||||
}
|
|
||||||
|
|
||||||
impl CacheSize {
|
|
||||||
/// Total amount used by the cache.
|
|
||||||
fn total(&self) -> usize { self.blocks + self.block_details + self.transaction_addresses + self.block_logs + self.blocks_blooms }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Information about best block gathered together
|
|
||||||
struct BestBlock {
|
|
||||||
pub hash: H256,
|
|
||||||
pub number: BlockNumber,
|
|
||||||
pub total_difficulty: U256
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BestBlock {
|
|
||||||
fn new() -> BestBlock {
|
|
||||||
BestBlock {
|
|
||||||
hash: H256::new(),
|
|
||||||
number: 0,
|
|
||||||
total_difficulty: U256::from(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Interface for querying blocks by hash and by number.
|
|
||||||
pub trait BlockProvider {
|
|
||||||
/// Returns true if the given block is known
|
|
||||||
/// (though not necessarily a part of the canon chain).
|
|
||||||
fn is_known(&self, hash: &H256) -> bool;
|
|
||||||
|
|
||||||
/// Get raw block data
|
|
||||||
fn block(&self, hash: &H256) -> Option<Bytes>;
|
|
||||||
|
|
||||||
/// Get the familial details concerning a block.
|
|
||||||
fn block_details(&self, hash: &H256) -> Option<BlockDetails>;
|
|
||||||
|
|
||||||
/// Get the hash of given block's number.
|
|
||||||
fn block_hash(&self, index: BlockNumber) -> Option<H256>;
|
|
||||||
|
|
||||||
/// Get the address of transaction with given hash.
|
|
||||||
fn transaction_address(&self, hash: &H256) -> Option<TransactionAddress>;
|
|
||||||
|
|
||||||
/// Get the partial-header of a block.
|
|
||||||
fn block_header(&self, hash: &H256) -> Option<Header> {
|
|
||||||
self.block(hash).map(|bytes| BlockView::new(&bytes).header())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a list of uncles for a given block.
|
|
||||||
/// Returns None if block deos not exist.
|
|
||||||
fn uncles(&self, hash: &H256) -> Option<Vec<Header>> {
|
|
||||||
self.block(hash).map(|bytes| BlockView::new(&bytes).uncles())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a list of uncle hashes for a given block.
|
|
||||||
/// Returns None if block does not exist.
|
|
||||||
fn uncle_hashes(&self, hash: &H256) -> Option<Vec<H256>> {
|
|
||||||
self.block(hash).map(|bytes| BlockView::new(&bytes).uncle_hashes())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the number of given block's hash.
|
|
||||||
fn block_number(&self, hash: &H256) -> Option<BlockNumber> {
|
|
||||||
self.block(hash).map(|bytes| BlockView::new(&bytes).header_view().number())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get transaction with given transaction hash.
|
|
||||||
fn transaction(&self, address: &TransactionAddress) -> Option<LocalizedTransaction> {
|
|
||||||
self.block(&address.block_hash).and_then(|bytes| BlockView::new(&bytes).localized_transaction_at(address.index))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a list of transactions for a given block.
|
|
||||||
/// Returns None if block does not exist.
|
|
||||||
fn transactions(&self, hash: &H256) -> Option<Vec<LocalizedTransaction>> {
|
|
||||||
self.block(hash).map(|bytes| BlockView::new(&bytes).localized_transactions())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns reference to genesis hash.
|
|
||||||
fn genesis_hash(&self) -> H256 {
|
|
||||||
self.block_hash(0).expect("Genesis hash should always exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns the header of the genesis block.
|
|
||||||
fn genesis_header(&self) -> Header {
|
|
||||||
self.block_header(&self.genesis_hash()).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Hash, Eq, PartialEq, Clone)]
|
|
||||||
enum CacheID {
|
|
||||||
Block(H256),
|
|
||||||
Extras(ExtrasIndex, H256),
|
|
||||||
}
|
|
||||||
|
|
||||||
struct CacheManager {
|
|
||||||
cache_usage: VecDeque<HashSet<CacheID>>,
|
|
||||||
in_use: HashSet<CacheID>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Structure providing fast access to blockchain data.
|
|
||||||
///
|
|
||||||
/// **Does not do input data verification.**
|
|
||||||
pub struct BlockChain {
|
|
||||||
pref_cache_size: usize,
|
|
||||||
max_cache_size: usize,
|
|
||||||
|
|
||||||
best_block: RwLock<BestBlock>,
|
|
||||||
|
|
||||||
// block cache
|
|
||||||
blocks: RwLock<HashMap<H256, Bytes>>,
|
|
||||||
|
|
||||||
// extra caches
|
|
||||||
block_details: RwLock<HashMap<H256, BlockDetails>>,
|
|
||||||
block_hashes: RwLock<HashMap<BlockNumber, H256>>,
|
|
||||||
transaction_addresses: RwLock<HashMap<H256, TransactionAddress>>,
|
|
||||||
block_logs: RwLock<HashMap<H256, BlockLogBlooms>>,
|
|
||||||
blocks_blooms: RwLock<HashMap<H256, BlocksBlooms>>,
|
|
||||||
|
|
||||||
extras_db: DB,
|
|
||||||
blocks_db: DB,
|
|
||||||
|
|
||||||
cache_man: RwLock<CacheManager>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BlockProvider for BlockChain {
|
|
||||||
/// Returns true if the given block is known
|
|
||||||
/// (though not necessarily a part of the canon chain).
|
|
||||||
fn is_known(&self, hash: &H256) -> bool {
|
|
||||||
self.query_extras_exist(hash, &self.block_details)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get raw block data
|
|
||||||
fn block(&self, hash: &H256) -> Option<Bytes> {
|
|
||||||
{
|
|
||||||
let read = self.blocks.read().unwrap();
|
|
||||||
if let Some(v) = read.get(hash) {
|
|
||||||
return Some(v.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let opt = self.blocks_db.get(hash)
|
|
||||||
.expect("Low level database error. Some issue with disk?");
|
|
||||||
|
|
||||||
self.note_used(CacheID::Block(hash.clone()));
|
|
||||||
|
|
||||||
match opt {
|
|
||||||
Some(b) => {
|
|
||||||
let bytes: Bytes = b.to_vec();
|
|
||||||
let mut write = self.blocks.write().unwrap();
|
|
||||||
write.insert(hash.clone(), bytes.clone());
|
|
||||||
Some(bytes)
|
|
||||||
},
|
|
||||||
None => None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the familial details concerning a block.
|
|
||||||
fn block_details(&self, hash: &H256) -> Option<BlockDetails> {
|
|
||||||
self.query_extras(hash, &self.block_details)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the hash of given block's number.
|
|
||||||
fn block_hash(&self, index: BlockNumber) -> Option<H256> {
|
|
||||||
self.query_extras(&index, &self.block_hashes)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the address of transaction with given hash.
|
|
||||||
fn transaction_address(&self, hash: &H256) -> Option<TransactionAddress> {
|
|
||||||
self.query_extras(hash, &self.transaction_addresses)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const COLLECTION_QUEUE_SIZE: usize = 8;
|
|
||||||
|
|
||||||
impl BlockChain {
|
|
||||||
/// Create new instance of blockchain from given Genesis
|
|
||||||
///
|
|
||||||
/// ```rust
|
|
||||||
/// extern crate ethcore_util as util;
|
|
||||||
/// extern crate ethcore;
|
|
||||||
/// use std::env;
|
|
||||||
/// use std::str::FromStr;
|
|
||||||
/// use ethcore::spec::*;
|
|
||||||
/// use ethcore::blockchain::*;
|
|
||||||
/// use ethcore::ethereum;
|
|
||||||
/// use util::hash::*;
|
|
||||||
/// use util::uint::*;
|
|
||||||
///
|
|
||||||
/// fn main() {
|
|
||||||
/// let spec = ethereum::new_frontier();
|
|
||||||
///
|
|
||||||
/// let mut dir = env::temp_dir();
|
|
||||||
/// dir.push(H32::random().hex());
|
|
||||||
///
|
|
||||||
/// let bc = BlockChain::new(&spec.genesis_block(), &dir);
|
|
||||||
///
|
|
||||||
/// let genesis_hash = "d4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3";
|
|
||||||
/// assert_eq!(bc.genesis_hash(), H256::from_str(genesis_hash).unwrap());
|
|
||||||
/// assert!(bc.is_known(&bc.genesis_hash()));
|
|
||||||
/// assert_eq!(bc.genesis_hash(), bc.block_hash(0).unwrap());
|
|
||||||
/// }
|
|
||||||
/// ```
|
|
||||||
pub fn new(genesis: &[u8], path: &Path) -> BlockChain {
|
|
||||||
// open extras db
|
|
||||||
let mut extras_path = path.to_path_buf();
|
|
||||||
extras_path.push("extras");
|
|
||||||
let extras_db = DB::open_default(extras_path.to_str().unwrap()).unwrap();
|
|
||||||
|
|
||||||
// open blocks db
|
|
||||||
let mut blocks_path = path.to_path_buf();
|
|
||||||
blocks_path.push("blocks");
|
|
||||||
let blocks_db = DB::open_default(blocks_path.to_str().unwrap()).unwrap();
|
|
||||||
|
|
||||||
let mut cache_man = CacheManager{cache_usage: VecDeque::new(), in_use: HashSet::new()};
|
|
||||||
(0..COLLECTION_QUEUE_SIZE).foreach(|_| cache_man.cache_usage.push_back(HashSet::new()));
|
|
||||||
|
|
||||||
let bc = BlockChain {
|
|
||||||
pref_cache_size: 1 << 14,
|
|
||||||
max_cache_size: 1 << 20,
|
|
||||||
best_block: RwLock::new(BestBlock::new()),
|
|
||||||
blocks: RwLock::new(HashMap::new()),
|
|
||||||
block_details: RwLock::new(HashMap::new()),
|
|
||||||
block_hashes: RwLock::new(HashMap::new()),
|
|
||||||
transaction_addresses: RwLock::new(HashMap::new()),
|
|
||||||
block_logs: RwLock::new(HashMap::new()),
|
|
||||||
blocks_blooms: RwLock::new(HashMap::new()),
|
|
||||||
extras_db: extras_db,
|
|
||||||
blocks_db: blocks_db,
|
|
||||||
cache_man: RwLock::new(cache_man),
|
|
||||||
};
|
|
||||||
|
|
||||||
// load best block
|
|
||||||
let best_block_hash = match bc.extras_db.get(b"best").unwrap() {
|
|
||||||
Some(best) => H256::from_slice(&best),
|
|
||||||
None => {
|
|
||||||
// best block does not exist
|
|
||||||
// we need to insert genesis into the cache
|
|
||||||
let block = BlockView::new(genesis);
|
|
||||||
let header = block.header_view();
|
|
||||||
let hash = block.sha3();
|
|
||||||
|
|
||||||
let details = BlockDetails {
|
|
||||||
number: header.number(),
|
|
||||||
total_difficulty: header.difficulty(),
|
|
||||||
parent: header.parent_hash(),
|
|
||||||
children: vec![]
|
|
||||||
};
|
|
||||||
|
|
||||||
bc.blocks_db.put(&hash, genesis).unwrap();
|
|
||||||
|
|
||||||
let batch = WriteBatch::new();
|
|
||||||
batch.put_extras(&hash, &details);
|
|
||||||
batch.put_extras(&header.number(), &hash);
|
|
||||||
batch.put(b"best", &hash).unwrap();
|
|
||||||
bc.extras_db.write(batch).unwrap();
|
|
||||||
|
|
||||||
hash
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut best_block = bc.best_block.write().unwrap();
|
|
||||||
best_block.number = bc.block_number(&best_block_hash).unwrap();
|
|
||||||
best_block.total_difficulty = bc.block_details(&best_block_hash).unwrap().total_difficulty;
|
|
||||||
best_block.hash = best_block_hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
bc
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set the cache configuration.
|
|
||||||
pub fn configure_cache(&mut self, pref_cache_size: usize, max_cache_size: usize) {
|
|
||||||
self.pref_cache_size = pref_cache_size;
|
|
||||||
self.max_cache_size = max_cache_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a tree route between `from` and `to`, which is a tuple of:
|
|
||||||
///
|
|
||||||
/// - a vector of hashes of all blocks, ordered from `from` to `to`.
|
|
||||||
///
|
|
||||||
/// - common ancestor of these blocks.
|
|
||||||
///
|
|
||||||
/// - an index where best common ancestor would be
|
|
||||||
///
|
|
||||||
/// 1.) from newer to older
|
|
||||||
///
|
|
||||||
/// - bc: `A1 -> A2 -> A3 -> A4 -> A5`
|
|
||||||
/// - from: A5, to: A4
|
|
||||||
/// - route:
|
|
||||||
///
|
|
||||||
/// ```json
|
|
||||||
/// { blocks: [A5], ancestor: A4, index: 1 }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// 2.) from older to newer
|
|
||||||
///
|
|
||||||
/// - bc: `A1 -> A2 -> A3 -> A4 -> A5`
|
|
||||||
/// - from: A3, to: A4
|
|
||||||
/// - route:
|
|
||||||
///
|
|
||||||
/// ```json
|
|
||||||
/// { blocks: [A4], ancestor: A3, index: 0 }
|
|
||||||
/// ```
|
|
||||||
///
|
|
||||||
/// 3.) fork:
|
|
||||||
///
|
|
||||||
/// - bc:
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// A1 -> A2 -> A3 -> A4
|
|
||||||
/// -> B3 -> B4
|
|
||||||
/// ```
|
|
||||||
/// - from: B4, to: A4
|
|
||||||
/// - route:
|
|
||||||
///
|
|
||||||
/// ```json
|
|
||||||
/// { blocks: [B4, B3, A3, A4], ancestor: A2, index: 2 }
|
|
||||||
/// ```
|
|
||||||
pub fn tree_route(&self, from: H256, to: H256) -> Option<TreeRoute> {
|
|
||||||
let from_details = match self.block_details(&from) {
|
|
||||||
Some(h) => h,
|
|
||||||
None => return None,
|
|
||||||
};
|
|
||||||
let to_details = match self.block_details(&to) {
|
|
||||||
Some(h) => h,
|
|
||||||
None => return None,
|
|
||||||
};
|
|
||||||
Some(self.tree_route_aux((&from_details, &from), (&to_details, &to)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Similar to `tree_route` function, but can be used to return a route
|
|
||||||
/// between blocks which may not be in database yet.
|
|
||||||
fn tree_route_aux(&self, from: (&BlockDetails, &H256), to: (&BlockDetails, &H256)) -> TreeRoute {
|
|
||||||
let mut from_branch = vec![];
|
|
||||||
let mut to_branch = vec![];
|
|
||||||
|
|
||||||
let mut from_details = from.0.clone();
|
|
||||||
let mut to_details = to.0.clone();
|
|
||||||
let mut current_from = from.1.clone();
|
|
||||||
let mut current_to = to.1.clone();
|
|
||||||
|
|
||||||
// reset from && to to the same level
|
|
||||||
while from_details.number > to_details.number {
|
|
||||||
from_branch.push(current_from);
|
|
||||||
current_from = from_details.parent.clone();
|
|
||||||
from_details = self.block_details(&from_details.parent).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
while to_details.number > from_details.number {
|
|
||||||
to_branch.push(current_to);
|
|
||||||
current_to = to_details.parent.clone();
|
|
||||||
to_details = self.block_details(&to_details.parent).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_eq!(from_details.number, to_details.number);
|
|
||||||
|
|
||||||
// move to shared parent
|
|
||||||
while current_from != current_to {
|
|
||||||
from_branch.push(current_from);
|
|
||||||
current_from = from_details.parent.clone();
|
|
||||||
from_details = self.block_details(&from_details.parent).unwrap();
|
|
||||||
|
|
||||||
to_branch.push(current_to);
|
|
||||||
current_to = to_details.parent.clone();
|
|
||||||
to_details = self.block_details(&to_details.parent).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let index = from_branch.len();
|
|
||||||
|
|
||||||
from_branch.extend(to_branch.into_iter().rev());
|
|
||||||
|
|
||||||
TreeRoute {
|
|
||||||
blocks: from_branch,
|
|
||||||
ancestor: current_from,
|
|
||||||
index: index
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Inserts the block into backing cache database.
|
|
||||||
/// Expects the block to be valid and already verified.
|
|
||||||
/// If the block is already known, does nothing.
|
|
||||||
pub fn insert_block(&self, bytes: &[u8]) {
|
|
||||||
// create views onto rlp
|
|
||||||
let block = BlockView::new(bytes);
|
|
||||||
let header = block.header_view();
|
|
||||||
let hash = header.sha3();
|
|
||||||
|
|
||||||
if self.is_known(&hash) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store block in db
|
|
||||||
self.blocks_db.put(&hash, &bytes).unwrap();
|
|
||||||
let (batch, new_best, details) = self.block_to_extras_insert_batch(bytes);
|
|
||||||
|
|
||||||
// update best block
|
|
||||||
let mut best_block = self.best_block.write().unwrap();
|
|
||||||
if let Some(b) = new_best {
|
|
||||||
*best_block = b;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update caches
|
|
||||||
let mut write = self.block_details.write().unwrap();
|
|
||||||
write.remove(&header.parent_hash());
|
|
||||||
write.insert(hash.clone(), details);
|
|
||||||
self.note_used(CacheID::Block(hash));
|
|
||||||
|
|
||||||
// update extras database
|
|
||||||
self.extras_db.write(batch).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Transforms block into WriteBatch that may be written into database
|
|
||||||
/// Additionally, if it's new best block it returns new best block object.
|
|
||||||
fn block_to_extras_insert_batch(&self, bytes: &[u8]) -> (WriteBatch, Option<BestBlock>, BlockDetails) {
|
|
||||||
// create views onto rlp
|
|
||||||
let block = BlockView::new(bytes);
|
|
||||||
let header = block.header_view();
|
|
||||||
|
|
||||||
// prepare variables
|
|
||||||
let hash = block.sha3();
|
|
||||||
let mut parent_details = self.block_details(&header.parent_hash()).expect("Invalid parent hash.");
|
|
||||||
let total_difficulty = parent_details.total_difficulty + header.difficulty();
|
|
||||||
let is_new_best = total_difficulty > self.best_block_total_difficulty();
|
|
||||||
let parent_hash = header.parent_hash();
|
|
||||||
|
|
||||||
// create current block details
|
|
||||||
let details = BlockDetails {
|
|
||||||
number: header.number(),
|
|
||||||
total_difficulty: total_difficulty,
|
|
||||||
parent: parent_hash.clone(),
|
|
||||||
children: vec![]
|
|
||||||
};
|
|
||||||
|
|
||||||
// prepare the batch
|
|
||||||
let batch = WriteBatch::new();
|
|
||||||
|
|
||||||
// insert new block details
|
|
||||||
batch.put_extras(&hash, &details);
|
|
||||||
|
|
||||||
// update parent details
|
|
||||||
parent_details.children.push(hash.clone());
|
|
||||||
batch.put_extras(&parent_hash, &parent_details);
|
|
||||||
|
|
||||||
// update transaction addresses
|
|
||||||
for (i, tx_hash) in block.transaction_hashes().iter().enumerate() {
|
|
||||||
batch.put_extras(tx_hash, &TransactionAddress {
|
|
||||||
block_hash: hash.clone(),
|
|
||||||
index: i
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// if it's not new best block, just return
|
|
||||||
if !is_new_best {
|
|
||||||
return (batch, None, details);
|
|
||||||
}
|
|
||||||
|
|
||||||
// if its new best block we need to make sure that all ancestors
|
|
||||||
// are moved to "canon chain"
|
|
||||||
// find the route between old best block and the new one
|
|
||||||
let best_hash = self.best_block_hash();
|
|
||||||
let best_details = self.block_details(&best_hash).expect("best block hash is invalid!");
|
|
||||||
let route = self.tree_route_aux((&best_details, &best_hash), (&details, &hash));
|
|
||||||
|
|
||||||
match route.blocks.len() {
|
|
||||||
// its our parent
|
|
||||||
1 => batch.put_extras(&header.number(), &hash),
|
|
||||||
// it is a fork
|
|
||||||
i if i > 1 => {
|
|
||||||
let ancestor_number = self.block_number(&route.ancestor).unwrap();
|
|
||||||
let start_number = ancestor_number + 1;
|
|
||||||
for (index, hash) in route.blocks.iter().skip(route.index).enumerate() {
|
|
||||||
batch.put_extras(&(start_number + index as BlockNumber), hash);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
// route.blocks.len() could be 0 only if inserted block is best block,
|
|
||||||
// and this is not possible at this stage
|
|
||||||
_ => { unreachable!(); }
|
|
||||||
};
|
|
||||||
|
|
||||||
// this is new best block
|
|
||||||
batch.put(b"best", &hash).unwrap();
|
|
||||||
|
|
||||||
let best_block = BestBlock {
|
|
||||||
hash: hash,
|
|
||||||
number: header.number(),
|
|
||||||
total_difficulty: total_difficulty
|
|
||||||
};
|
|
||||||
|
|
||||||
(batch, Some(best_block), details)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if transaction is known.
|
|
||||||
pub fn is_known_transaction(&self, hash: &H256) -> bool {
|
|
||||||
self.query_extras_exist(hash, &self.transaction_addresses)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get best block hash.
|
|
||||||
pub fn best_block_hash(&self) -> H256 {
|
|
||||||
self.best_block.read().unwrap().hash.clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get best block number.
|
|
||||||
pub fn best_block_number(&self) -> BlockNumber {
|
|
||||||
self.best_block.read().unwrap().number
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get best block total difficulty.
|
|
||||||
pub fn best_block_total_difficulty(&self) -> U256 {
|
|
||||||
self.best_block.read().unwrap().total_difficulty
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the transactions' log blooms of a block.
|
|
||||||
pub fn log_blooms(&self, hash: &H256) -> Option<BlockLogBlooms> {
|
|
||||||
self.query_extras(hash, &self.block_logs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn query_extras<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> Option<T> where
|
|
||||||
T: Clone + Decodable + ExtrasIndexable,
|
|
||||||
K: ExtrasSliceConvertable + Eq + Hash + Clone {
|
|
||||||
{
|
|
||||||
let read = cache.read().unwrap();
|
|
||||||
if let Some(v) = read.get(hash) {
|
|
||||||
return Some(v.clone());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(h) = hash.as_h256() {
|
|
||||||
self.note_used(CacheID::Extras(T::extras_index(), h.clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
self.extras_db.get_extras(hash).map(| t: T | {
|
|
||||||
let mut write = cache.write().unwrap();
|
|
||||||
write.insert(hash.clone(), t.clone());
|
|
||||||
t
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn query_extras_exist<K, T>(&self, hash: &K, cache: &RwLock<HashMap<K, T>>) -> bool where
|
|
||||||
K: ExtrasSliceConvertable + Eq + Hash + Clone,
|
|
||||||
T: ExtrasIndexable {
|
|
||||||
{
|
|
||||||
let read = cache.read().unwrap();
|
|
||||||
if let Some(_) = read.get(hash) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.extras_db.extras_exists::<_, T>(hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get current cache size.
|
|
||||||
pub fn cache_size(&self) -> CacheSize {
|
|
||||||
CacheSize {
|
|
||||||
blocks: self.blocks.read().unwrap().heap_size_of_children(),
|
|
||||||
block_details: self.block_details.read().unwrap().heap_size_of_children(),
|
|
||||||
transaction_addresses: self.transaction_addresses.read().unwrap().heap_size_of_children(),
|
|
||||||
block_logs: self.block_logs.read().unwrap().heap_size_of_children(),
|
|
||||||
blocks_blooms: self.blocks_blooms.read().unwrap().heap_size_of_children()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Let the cache system know that a cacheable item has been used.
|
|
||||||
fn note_used(&self, id: CacheID) {
|
|
||||||
let mut cache_man = self.cache_man.write().unwrap();
|
|
||||||
if !cache_man.cache_usage[0].contains(&id) {
|
|
||||||
cache_man.cache_usage[0].insert(id.clone());
|
|
||||||
if cache_man.in_use.contains(&id) {
|
|
||||||
if let Some(c) = cache_man.cache_usage.iter_mut().skip(1).find(|e|e.contains(&id)) {
|
|
||||||
c.remove(&id);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cache_man.in_use.insert(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ticks our cache system and throws out any old data.
|
|
||||||
pub fn collect_garbage(&self) {
|
|
||||||
if self.cache_size().total() < self.pref_cache_size { return; }
|
|
||||||
|
|
||||||
for _ in 0..COLLECTION_QUEUE_SIZE {
|
|
||||||
{
|
|
||||||
let mut cache_man = self.cache_man.write().unwrap();
|
|
||||||
let mut blocks = self.blocks.write().unwrap();
|
|
||||||
let mut block_details = self.block_details.write().unwrap();
|
|
||||||
let mut block_hashes = self.block_hashes.write().unwrap();
|
|
||||||
let mut transaction_addresses = self.transaction_addresses.write().unwrap();
|
|
||||||
let mut block_logs = self.block_logs.write().unwrap();
|
|
||||||
let mut blocks_blooms = self.blocks_blooms.write().unwrap();
|
|
||||||
|
|
||||||
for id in cache_man.cache_usage.pop_back().unwrap().into_iter() {
|
|
||||||
cache_man.in_use.remove(&id);
|
|
||||||
match id {
|
|
||||||
CacheID::Block(h) => { blocks.remove(&h); },
|
|
||||||
CacheID::Extras(ExtrasIndex::BlockDetails, h) => { block_details.remove(&h); },
|
|
||||||
CacheID::Extras(ExtrasIndex::TransactionAddress, h) => { transaction_addresses.remove(&h); },
|
|
||||||
CacheID::Extras(ExtrasIndex::BlockLogBlooms, h) => { block_logs.remove(&h); },
|
|
||||||
CacheID::Extras(ExtrasIndex::BlocksBlooms, h) => { blocks_blooms.remove(&h); },
|
|
||||||
_ => panic!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cache_man.cache_usage.push_front(HashSet::new());
|
|
||||||
|
|
||||||
// TODO: handle block_hashes properly.
|
|
||||||
block_hashes.clear();
|
|
||||||
}
|
|
||||||
if self.cache_size().total() < self.max_cache_size { break; }
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: m_lastCollection = chrono::system_clock::now();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use std::str::FromStr;
|
|
||||||
use rustc_serialize::hex::FromHex;
|
|
||||||
use util::hash::*;
|
|
||||||
use blockchain::*;
|
|
||||||
use tests::helpers::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn valid_tests_extra32() {
|
|
||||||
let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0925002c3260b44e44c3edebad1cc442142b03020209df1ab8bb86752edbd2cd7a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a0363659b251bf8b819179874c8cce7b9b983d7f3704cbb58a3b334431f7032871889032d09c281e1236c0c0".from_hex().unwrap();
|
|
||||||
|
|
||||||
let temp = RandomTempPath::new();
|
|
||||||
let bc = BlockChain::new(&genesis, temp.as_path());
|
|
||||||
|
|
||||||
let genesis_hash = H256::from_str("3caa2203f3d7c136c0295ed128a7d31cea520b1ca5e27afe17d0853331798942").unwrap();
|
|
||||||
|
|
||||||
assert_eq!(bc.genesis_hash(), genesis_hash.clone());
|
|
||||||
assert_eq!(bc.best_block_number(), 0);
|
|
||||||
assert_eq!(bc.best_block_hash(), genesis_hash.clone());
|
|
||||||
assert_eq!(bc.block_hash(0), Some(genesis_hash.clone()));
|
|
||||||
assert_eq!(bc.block_hash(1), None);
|
|
||||||
|
|
||||||
let first = "f90285f90219a03caa2203f3d7c136c0295ed128a7d31cea520b1ca5e27afe17d0853331798942a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0bac6177a79e910c98d86ec31a09ae37ac2de15b754fd7bed1ba52362c49416bfa0d45893a296c1490a978e0bd321b5f2635d8280365c1fe9f693d65f233e791344a0c7778a7376099ee2e5c455791c1885b5c361b95713fddcbe32d97fd01334d296b90100000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000400000000000000000000000000000000000000000000000000000008302000001832fefd882560b845627cb99a00102030405060708091011121314151617181920212223242526272829303132a08ccb2837fb2923bd97e8f2d08ea32012d6e34be018c73e49a0f98843e8f47d5d88e53be49fec01012ef866f864800a82c35094095e7baea6a6c7c4c2dfeb977efac326af552d8785012a05f200801ba0cb088b8d2ff76a7b2c6616c9d02fb6b7a501afbf8b69d7180b09928a1b80b5e4a06448fe7476c606582039bb72a9f6f4b4fad18507b8dfbd00eebbe151cc573cd2c0".from_hex().unwrap();
|
|
||||||
|
|
||||||
bc.insert_block(&first);
|
|
||||||
|
|
||||||
let first_hash = H256::from_str("a940e5af7d146b3b917c953a82e1966b906dace3a4e355b5b0a4560190357ea1").unwrap();
|
|
||||||
|
|
||||||
assert_eq!(bc.block_hash(0), Some(genesis_hash.clone()));
|
|
||||||
assert_eq!(bc.best_block_number(), 1);
|
|
||||||
assert_eq!(bc.best_block_hash(), first_hash.clone());
|
|
||||||
assert_eq!(bc.block_hash(1), Some(first_hash.clone()));
|
|
||||||
assert_eq!(bc.block_details(&first_hash).unwrap().parent, genesis_hash.clone());
|
|
||||||
assert_eq!(bc.block_details(&genesis_hash).unwrap().children, vec![first_hash.clone()]);
|
|
||||||
assert_eq!(bc.block_hash(2), None);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
#[allow(cyclomatic_complexity)]
|
|
||||||
fn test_small_fork() {
|
|
||||||
let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a059262c330941f3fe2a34d16d6e3c7b30d2ceb37c6a0e9a994c494ee1a61d2410885aa4c8bf8e56e264c0c0".from_hex().unwrap();
|
|
||||||
let b1 = "f90261f901f9a05716670833ec874362d65fea27a7cd35af5897d275b31a44944113111e4e96d2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a0e78628dd45a1f8dc495594d83b76c588a3ee67463260f8b7d4a42f574aeab29aa0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd882520884562791e580a051b3ecba4e3f2b49c11d42dd0851ec514b1be3138080f72a2b6e83868275d98f8877671f479c414b47f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca09e2709d7ec9bbe6b1bbbf0b2088828d14cd5e8642a1fee22dc74bfa89761a7f9a04bd8813dee4be989accdb708b1c2e325a7e9c695a8024e30e89d6c644e424747c0".from_hex().unwrap();
|
|
||||||
let b2 = "f902ccf901f9a0437e51676ff10756fcfee5edd9159fa41dbcb1b2c592850450371cbecd54ee4fa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0c70a5dc56146e5ef025e4e5726a6373c6f12fd2f6784093a19ead0a7d17fb292a040645cbce4fd399e7bb9160b4c30c40d7ee616a030d4e18ef0ed3b02bdb65911a086e608555f63628417032a011d107b36427af37d153f0da02ce3f90fdd5e8c08b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302004002832fefd882c0e384562791e880a0e3cc39ff775cc0a32f175995b92e84b729e5c9a3563ff899e3555b908bc21d75887c3cde283f4846a6f8cdf8cb01018304cb2f8080b87e6060604052606e8060106000396000f360606040526000357c010000000000000000000000000000000000000000000000000000000090048063c0406226146037576035565b005b60406004506056565b6040518082815260200191505060405180910390f35b6000600560006000508190555060059050606b565b90561ba05258615c63503c0a600d6994b12ea5750d45b3c69668e2a371b4fbfb9eeff6b8a0a11be762bc90491231274a2945be35a43f23c27775b1ff24dd521702fe15f73ec0".from_hex().unwrap();
|
|
||||||
let b3a = "f90261f901f9a036fde1253128666fcb95a5956da14a73489e988bb72738717ec1d31e1cee781aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a09dc4b1357c0b7b8108f8a098f4f9a1a274957bc9ebc22a9ae67ae81739e5b19ca007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd882524d84562791eb80a074861666bd346c025889745c793b91ab9cd1e2ca19b5cf3c50d04d135b0a4d2b8809fe9587ea4cdc04f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba06fd84874d36d5de9e8e48978c03619b53a96b7ae0a4cd1ac118f103098b44801a00572596974dd7df4f9f69bd7456585618c568d8434ef6453391b89281ce12ae1c0".from_hex().unwrap();
|
|
||||||
let b3b = "f90265f901f9a036fde1253128666fcb95a5956da14a73489e988bb72738717ec1d31e1cee781aa01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0ab87dc338bfd6f662b1cd90bc0c9e40a1b2146a095312393c9e13ce3a5008b09a0e609b7a7d4b8a2403ec1268627ecd98783627246e8f1b26addb3ff504f76a054a0592fabf92476512952db3a69a2481a42912e668a1ee28c4c322e703bb665f8beb90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefd882a1f084562791ee80a0fe7098fa7e4ac5d637eea81fb23f8f78346826dbab430068dd9a249d0afa99818853e1a6b201ae3545f866f86402018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d0284c04062261ca06edc9ce8e7da4cc34067beb325dcad59e5655a164a5100a50bc3eb681b12c716a0abf9053d5de65b1be81fe50d327b84de685efbeecea34e7b747180a6c6023e44c0".from_hex().unwrap();
|
|
||||||
|
|
||||||
let genesis_hash = H256::from_str("5716670833ec874362d65fea27a7cd35af5897d275b31a44944113111e4e96d2").unwrap();
|
|
||||||
let b1_hash = H256::from_str("437e51676ff10756fcfee5edd9159fa41dbcb1b2c592850450371cbecd54ee4f").unwrap();
|
|
||||||
let b2_hash = H256::from_str("36fde1253128666fcb95a5956da14a73489e988bb72738717ec1d31e1cee781a").unwrap();
|
|
||||||
let b3a_hash = H256::from_str("c208f88c9f5bf7e00840439742c12e5226d9752981f3ec0521bdcb6dd08af277").unwrap();
|
|
||||||
let b3b_hash = H256::from_str("bf72270ae0d95c9ea39a6adab994793fddb8c10fba7391e26279474124605d54").unwrap();
|
|
||||||
|
|
||||||
// b3a is a part of canon chain, whereas b3b is part of sidechain
|
|
||||||
let best_block_hash = H256::from_str("c208f88c9f5bf7e00840439742c12e5226d9752981f3ec0521bdcb6dd08af277").unwrap();
|
|
||||||
|
|
||||||
let temp = RandomTempPath::new();
|
|
||||||
let bc = BlockChain::new(&genesis, temp.as_path());
|
|
||||||
bc.insert_block(&b1);
|
|
||||||
bc.insert_block(&b2);
|
|
||||||
bc.insert_block(&b3a);
|
|
||||||
bc.insert_block(&b3b);
|
|
||||||
|
|
||||||
assert_eq!(bc.best_block_hash(), best_block_hash);
|
|
||||||
assert_eq!(bc.block_number(&genesis_hash).unwrap(), 0);
|
|
||||||
assert_eq!(bc.block_number(&b1_hash).unwrap(), 1);
|
|
||||||
assert_eq!(bc.block_number(&b2_hash).unwrap(), 2);
|
|
||||||
assert_eq!(bc.block_number(&b3a_hash).unwrap(), 3);
|
|
||||||
assert_eq!(bc.block_number(&b3b_hash).unwrap(), 3);
|
|
||||||
|
|
||||||
assert_eq!(bc.block_hash(0).unwrap(), genesis_hash);
|
|
||||||
assert_eq!(bc.block_hash(1).unwrap(), b1_hash);
|
|
||||||
assert_eq!(bc.block_hash(2).unwrap(), b2_hash);
|
|
||||||
assert_eq!(bc.block_hash(3).unwrap(), b3a_hash);
|
|
||||||
|
|
||||||
// test trie route
|
|
||||||
let r0_1 = bc.tree_route(genesis_hash.clone(), b1_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r0_1.ancestor, genesis_hash);
|
|
||||||
assert_eq!(r0_1.blocks, [b1_hash.clone()]);
|
|
||||||
assert_eq!(r0_1.index, 0);
|
|
||||||
|
|
||||||
let r0_2 = bc.tree_route(genesis_hash.clone(), b2_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r0_2.ancestor, genesis_hash);
|
|
||||||
assert_eq!(r0_2.blocks, [b1_hash.clone(), b2_hash.clone()]);
|
|
||||||
assert_eq!(r0_2.index, 0);
|
|
||||||
|
|
||||||
let r1_3a = bc.tree_route(b1_hash.clone(), b3a_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r1_3a.ancestor, b1_hash);
|
|
||||||
assert_eq!(r1_3a.blocks, [b2_hash.clone(), b3a_hash.clone()]);
|
|
||||||
assert_eq!(r1_3a.index, 0);
|
|
||||||
|
|
||||||
let r1_3b = bc.tree_route(b1_hash.clone(), b3b_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r1_3b.ancestor, b1_hash);
|
|
||||||
assert_eq!(r1_3b.blocks, [b2_hash.clone(), b3b_hash.clone()]);
|
|
||||||
assert_eq!(r1_3b.index, 0);
|
|
||||||
|
|
||||||
let r3a_3b = bc.tree_route(b3a_hash.clone(), b3b_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r3a_3b.ancestor, b2_hash);
|
|
||||||
assert_eq!(r3a_3b.blocks, [b3a_hash.clone(), b3b_hash.clone()]);
|
|
||||||
assert_eq!(r3a_3b.index, 1);
|
|
||||||
|
|
||||||
let r1_0 = bc.tree_route(b1_hash.clone(), genesis_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r1_0.ancestor, genesis_hash);
|
|
||||||
assert_eq!(r1_0.blocks, [b1_hash.clone()]);
|
|
||||||
assert_eq!(r1_0.index, 1);
|
|
||||||
|
|
||||||
let r2_0 = bc.tree_route(b2_hash.clone(), genesis_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r2_0.ancestor, genesis_hash);
|
|
||||||
assert_eq!(r2_0.blocks, [b2_hash.clone(), b1_hash.clone()]);
|
|
||||||
assert_eq!(r2_0.index, 2);
|
|
||||||
|
|
||||||
let r3a_1 = bc.tree_route(b3a_hash.clone(), b1_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r3a_1.ancestor, b1_hash);
|
|
||||||
assert_eq!(r3a_1.blocks, [b3a_hash.clone(), b2_hash.clone()]);
|
|
||||||
assert_eq!(r3a_1.index, 2);
|
|
||||||
|
|
||||||
let r3b_1 = bc.tree_route(b3b_hash.clone(), b1_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r3b_1.ancestor, b1_hash);
|
|
||||||
assert_eq!(r3b_1.blocks, [b3b_hash.clone(), b2_hash.clone()]);
|
|
||||||
assert_eq!(r3b_1.index, 2);
|
|
||||||
|
|
||||||
let r3b_3a = bc.tree_route(b3b_hash.clone(), b3a_hash.clone()).unwrap();
|
|
||||||
assert_eq!(r3b_3a.ancestor, b2_hash);
|
|
||||||
assert_eq!(r3b_3a.blocks, [b3b_hash.clone(), b3a_hash.clone()]);
|
|
||||||
assert_eq!(r3b_3a.index, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_reopen_blockchain_db() {
|
|
||||||
let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a07dba07d6b448a186e9612e5f737d1c909dce473e53199901a302c00646d523c1a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000080832fefd8808454c98c8142a059262c330941f3fe2a34d16d6e3c7b30d2ceb37c6a0e9a994c494ee1a61d2410885aa4c8bf8e56e264c0c0".from_hex().unwrap();
|
|
||||||
let b1 = "f90261f901f9a05716670833ec874362d65fea27a7cd35af5897d275b31a44944113111e4e96d2a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0cb52de543653d86ccd13ba3ddf8b052525b04231c6884a4db3188a184681d878a0e78628dd45a1f8dc495594d83b76c588a3ee67463260f8b7d4a42f574aeab29aa0e9244cf7503b79c03d3a099e07a80d2dbc77bb0b502d8a89d51ac0d68dd31313b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302000001832fefd882520884562791e580a051b3ecba4e3f2b49c11d42dd0851ec514b1be3138080f72a2b6e83868275d98f8877671f479c414b47f862f86080018304cb2f94095e7baea6a6c7c4c2dfeb977efac326af552d870a801ca09e2709d7ec9bbe6b1bbbf0b2088828d14cd5e8642a1fee22dc74bfa89761a7f9a04bd8813dee4be989accdb708b1c2e325a7e9c695a8024e30e89d6c644e424747c0".from_hex().unwrap();
|
|
||||||
let genesis_hash = H256::from_str("5716670833ec874362d65fea27a7cd35af5897d275b31a44944113111e4e96d2").unwrap();
|
|
||||||
let b1_hash = H256::from_str("437e51676ff10756fcfee5edd9159fa41dbcb1b2c592850450371cbecd54ee4f").unwrap();
|
|
||||||
|
|
||||||
let temp = RandomTempPath::new();
|
|
||||||
{
|
|
||||||
let bc = BlockChain::new(&genesis, temp.as_path());
|
|
||||||
assert_eq!(bc.best_block_hash(), genesis_hash);
|
|
||||||
bc.insert_block(&b1);
|
|
||||||
assert_eq!(bc.best_block_hash(), b1_hash);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
let bc = BlockChain::new(&genesis, temp.as_path());
|
|
||||||
assert_eq!(bc.best_block_hash(), b1_hash);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_contain_arbitrary_block_sequence() {
|
|
||||||
let bc_result = generate_dummy_blockchain(50);
|
|
||||||
let bc = bc_result.reference();
|
|
||||||
assert_eq!(bc.best_block_number(), 49);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_collect_garbage() {
|
|
||||||
let bc_result = generate_dummy_blockchain(3000);
|
|
||||||
let bc = bc_result.reference();
|
|
||||||
|
|
||||||
assert_eq!(bc.best_block_number(), 2999);
|
|
||||||
let best_hash = bc.best_block_hash();
|
|
||||||
let mut block_header = bc.block_header(&best_hash);
|
|
||||||
|
|
||||||
while !block_header.is_none() {
|
|
||||||
block_header = bc.block_header(&block_header.unwrap().parent_hash);
|
|
||||||
}
|
|
||||||
assert!(bc.cache_size().blocks > 1024 * 1024);
|
|
||||||
|
|
||||||
for _ in 0..2 {
|
|
||||||
bc.collect_garbage();
|
|
||||||
}
|
|
||||||
assert!(bc.cache_size().blocks < 1024 * 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_contain_arbitrary_block_sequence_with_extra() {
|
|
||||||
let bc_result = generate_dummy_blockchain_with_extra(25);
|
|
||||||
let bc = bc_result.reference();
|
|
||||||
assert_eq!(bc.best_block_number(), 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn can_contain_only_genesis_block() {
|
|
||||||
let bc_result = generate_dummy_empty_blockchain();
|
|
||||||
let bc = bc_result.reference();
|
|
||||||
assert_eq!(bc.best_block_number(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn find_transaction_by_hash() {
|
|
||||||
let genesis = "f901fcf901f7a00000000000000000000000000000000000000000000000000000000000000000a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0af81e09f8c46ca322193edfda764fa7e88e81923f802f1d325ec0b0308ac2cd0a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200008083023e38808454c98c8142a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421880102030405060708c0c0".from_hex().unwrap();
|
|
||||||
let b1 = "f904a8f901faa0ce1f26f798dd03c8782d63b3e42e79a64eaea5694ea686ac5d7ce3df5171d1aea01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a0a65c2364cd0f1542d761823dc0109c6b072f14c20459598c5455c274601438f4a070616ebd7ad2ed6fb7860cf7e9df00163842351c38a87cac2c1cb193895035a2a05c5b4fc43c2d45787f54e1ae7d27afdb4ad16dfc567c5692070d5c4556e0b1d7b9010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000830200000183023ec683021536845685109780a029f07836e4e59229b3a065913afc27702642c683bba689910b2b2fd45db310d3888957e6d004a31802f902a7f85f800a8255f094aaaf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca0575da4e21b66fa764be5f74da9389e67693d066fb0d1312e19e17e501da00ecda06baf5a5327595f6619dfc2fcb3f2e6fb410b5810af3cb52d0e7508038e91a188f85f010a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba04fa966bf34b93abc1bcd665554b7f316b50f928477b50be0f3285ead29d18c5ba017bba0eeec1625ab433746955e125d46d80b7fdc97386c51266f842d8e02192ef85f020a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca004377418ae981cc32b1312b4a427a1d69a821b28db8584f5f2bd8c6d42458adaa053a1dba1af177fac92f3b6af0a9fa46a22adf56e686c93794b6a012bf254abf5f85f030a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ca04fe13febd28a05f4fcb2f451d7ddc2dda56486d9f8c79a62b0ba4da775122615a0651b2382dd402df9ebc27f8cb4b2e0f3cea68dda2dca0ee9603608f0b6f51668f85f040a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba078e6a0ba086a08f8450e208a399bb2f2d2a0d984acd2517c7c7df66ccfab567da013254002cd45a97fac049ae00afbc43ed0d9961d0c56a3b2382c80ce41c198ddf85f050a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba0a7174d8f43ea71c8e3ca9477691add8d80ac8e0ed89d8d8b572041eef81f4a54a0534ea2e28ec4da3b5b944b18c51ec84a5cf35f5b3343c5fb86521fd2d388f506f85f060a82520894bbbf5374fce5edbc8e2a8697c15331677e6ebf0b0a801ba034bd04065833536a10c77ee2a43a5371bc6d34837088b861dd9d4b7f44074b59a078807715786a13876d3455716a6b9cb2186b7a4887a5c31160fc877454958616c0".from_hex().unwrap();
|
|
||||||
let b1_hash = H256::from_str("f53f268d23a71e85c7d6d83a9504298712b84c1a2ba220441c86eeda0bf0b6e3").unwrap();
|
|
||||||
|
|
||||||
let temp = RandomTempPath::new();
|
|
||||||
let bc = BlockChain::new(&genesis, temp.as_path());
|
|
||||||
bc.insert_block(&b1);
|
|
||||||
|
|
||||||
let transactions = bc.transactions(&b1_hash).unwrap();
|
|
||||||
assert_eq!(transactions.len(), 7);
|
|
||||||
for t in transactions {
|
|
||||||
assert_eq!(bc.transaction(&bc.transaction_address(&t.hash()).unwrap()).unwrap(), t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
29
ethcore/src/blockchain/best_block.rs
Normal file
29
ethcore/src/blockchain/best_block.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use util::numbers::{U256,H256};
|
||||||
|
use header::BlockNumber;
|
||||||
|
|
||||||
|
/// Best block info.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct BestBlock {
|
||||||
|
/// Best block hash.
|
||||||
|
pub hash: H256,
|
||||||
|
/// Best block number.
|
||||||
|
pub number: BlockNumber,
|
||||||
|
/// Best block total difficulty.
|
||||||
|
pub total_difficulty: U256
|
||||||
|
}
|
51
ethcore/src/blockchain/block_info.rs
Normal file
51
ethcore/src/blockchain/block_info.rs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use util::numbers::{U256,H256};
|
||||||
|
use header::BlockNumber;
|
||||||
|
|
||||||
|
/// Brief info about inserted block.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BlockInfo {
|
||||||
|
/// Block hash.
|
||||||
|
pub hash: H256,
|
||||||
|
/// Block number.
|
||||||
|
pub number: BlockNumber,
|
||||||
|
/// Total block difficulty.
|
||||||
|
pub total_difficulty: U256,
|
||||||
|
/// Block location in blockchain.
|
||||||
|
pub location: BlockLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Describes location of newly inserted block.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub enum BlockLocation {
|
||||||
|
/// It's part of the canon chain.
|
||||||
|
CanonChain,
|
||||||
|
/// It's not a part of the canon chain.
|
||||||
|
Branch,
|
||||||
|
/// It's part of the fork which should become canon chain,
|
||||||
|
/// because it's total difficulty is higher than current
|
||||||
|
/// canon chain difficulty.
|
||||||
|
BranchBecomingCanonChain {
|
||||||
|
/// Hash of the newest common ancestor with old canon chain.
|
||||||
|
ancestor: H256,
|
||||||
|
/// Hashes of the blocks between ancestor and this block.
|
||||||
|
enacted: Vec<H256>,
|
||||||
|
/// Hashes of the blocks which were invalidated.
|
||||||
|
retracted: Vec<H256>,
|
||||||
|
}
|
||||||
|
}
|
1217
ethcore/src/blockchain/blockchain.rs
Normal file
1217
ethcore/src/blockchain/blockchain.rs
Normal file
File diff suppressed because it is too large
Load Diff
102
ethcore/src/blockchain/bloom_indexer.rs
Normal file
102
ethcore/src/blockchain/bloom_indexer.rs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use util::numbers::H256;
|
||||||
|
use chainfilter::BloomIndex;
|
||||||
|
|
||||||
|
/// Represents location of block bloom in extras database.
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct BlocksBloomLocation {
|
||||||
|
/// Unique hash of BlocksBloom
|
||||||
|
pub hash: H256,
|
||||||
|
/// Index within BlocksBloom
|
||||||
|
pub index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Should be used to localize blocks blooms in extras database.
|
||||||
|
pub struct BloomIndexer {
|
||||||
|
index_size: usize,
|
||||||
|
levels: u8,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BloomIndexer {
|
||||||
|
/// Plain constructor.
|
||||||
|
pub fn new(index_size: usize, levels: u8) -> Self {
|
||||||
|
BloomIndexer {
|
||||||
|
index_size: index_size,
|
||||||
|
levels: levels
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculates bloom's position in database.
|
||||||
|
pub fn location(&self, bloom_index: &BloomIndex) -> BlocksBloomLocation {
|
||||||
|
use std::{mem, ptr};
|
||||||
|
|
||||||
|
let hash = unsafe {
|
||||||
|
let mut hash: H256 = mem::zeroed();
|
||||||
|
ptr::copy(&[bloom_index.index / self.index_size] as *const usize as *const u8, hash.as_mut_ptr(), 8);
|
||||||
|
hash[8] = bloom_index.level;
|
||||||
|
hash.reverse();
|
||||||
|
hash
|
||||||
|
};
|
||||||
|
|
||||||
|
BlocksBloomLocation {
|
||||||
|
hash: hash,
|
||||||
|
index: bloom_index.index % self.index_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns index size.
|
||||||
|
pub fn index_size(&self) -> usize {
|
||||||
|
self.index_size
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns number of cache levels.
|
||||||
|
pub fn levels(&self) -> u8 {
|
||||||
|
self.levels
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::str::FromStr;
|
||||||
|
use util::hash::{H256, FixedHash};
|
||||||
|
use chainfilter::BloomIndex;
|
||||||
|
use blockchain::bloom_indexer::{BloomIndexer, BlocksBloomLocation};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bloom_indexer() {
|
||||||
|
let bi = BloomIndexer::new(16, 3);
|
||||||
|
|
||||||
|
let index = BloomIndex::new(0, 0);
|
||||||
|
assert_eq!(bi.location(&index), BlocksBloomLocation {
|
||||||
|
hash: H256::new(),
|
||||||
|
index: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
let index = BloomIndex::new(1, 0);
|
||||||
|
assert_eq!(bi.location(&index), BlocksBloomLocation {
|
||||||
|
hash: H256::from_str("0000000000000000000000000000000000000000000000010000000000000000").unwrap(),
|
||||||
|
index: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
let index = BloomIndex::new(0, 299_999);
|
||||||
|
assert_eq!(bi.location(&index), BlocksBloomLocation {
|
||||||
|
hash: H256::from_str("000000000000000000000000000000000000000000000000000000000000493d").unwrap(),
|
||||||
|
index: 15
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
37
ethcore/src/blockchain/cache.rs
Normal file
37
ethcore/src/blockchain/cache.rs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
/// Represents blockchain's in-memory cache size in bytes.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct CacheSize {
|
||||||
|
/// Blocks cache size.
|
||||||
|
pub blocks: usize,
|
||||||
|
/// BlockDetails cache size.
|
||||||
|
pub block_details: usize,
|
||||||
|
/// Transaction addresses cache size.
|
||||||
|
pub transaction_addresses: usize,
|
||||||
|
/// Logs cache size.
|
||||||
|
pub block_logs: usize,
|
||||||
|
/// Blooms cache size.
|
||||||
|
pub blocks_blooms: usize,
|
||||||
|
/// Block receipts size.
|
||||||
|
pub block_receipts: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CacheSize {
|
||||||
|
/// Total amount used by the cache.
|
||||||
|
pub fn total(&self) -> usize { self.blocks + self.block_details + self.transaction_addresses + self.block_logs + self.blocks_blooms }
|
||||||
|
}
|
64
ethcore/src/blockchain/generator/block.rs
Normal file
64
ethcore/src/blockchain/generator/block.rs
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use util::rlp::*;
|
||||||
|
use util::{H256, H2048};
|
||||||
|
use util::U256;
|
||||||
|
use util::bytes::Bytes;
|
||||||
|
use header::Header;
|
||||||
|
use transaction::SignedTransaction;
|
||||||
|
|
||||||
|
use super::fork::Forkable;
|
||||||
|
use super::bloom::WithBloom;
|
||||||
|
use super::complete::CompleteBlock;
|
||||||
|
|
||||||
|
/// Helper structure, used for encoding blocks.
|
||||||
|
#[derive(Default)]
|
||||||
|
pub struct Block {
|
||||||
|
pub header: Header,
|
||||||
|
pub transactions: Vec<SignedTransaction>,
|
||||||
|
pub uncles: Vec<Header>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodable for Block {
|
||||||
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
|
s.begin_list(3);
|
||||||
|
s.append(&self.header);
|
||||||
|
s.append(&self.transactions);
|
||||||
|
s.append(&self.uncles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Forkable for Block {
|
||||||
|
fn fork(mut self, fork_number: usize) -> Self where Self: Sized {
|
||||||
|
self.header.difficulty = self.header.difficulty - U256::from(fork_number);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl WithBloom for Block {
|
||||||
|
fn with_bloom(mut self, bloom: H2048) -> Self where Self: Sized {
|
||||||
|
self.header.log_bloom = bloom;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CompleteBlock for Block {
|
||||||
|
fn complete(mut self, parent_hash: H256) -> Bytes {
|
||||||
|
self.header.parent_hash = parent_hash;
|
||||||
|
encode(&self).to_vec()
|
||||||
|
}
|
||||||
|
}
|
35
ethcore/src/blockchain/generator/bloom.rs
Normal file
35
ethcore/src/blockchain/generator/bloom.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use util::hash::H2048;
|
||||||
|
|
||||||
|
pub trait WithBloom {
|
||||||
|
fn with_bloom(self, bloom: H2048) -> Self where Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Bloom<'a, I> where I: 'a {
|
||||||
|
pub iter: &'a mut I,
|
||||||
|
pub bloom: H2048,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, I> Iterator for Bloom<'a, I> where I: Iterator, <I as Iterator>::Item: WithBloom {
|
||||||
|
type Item = <I as Iterator>::Item;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.iter.next().map(|item| item.with_bloom(self.bloom.clone()))
|
||||||
|
}
|
||||||
|
}
|
53
ethcore/src/blockchain/generator/complete.rs
Normal file
53
ethcore/src/blockchain/generator/complete.rs
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use util::hash::H256;
|
||||||
|
use util::bytes::Bytes;
|
||||||
|
use util::sha3::Hashable;
|
||||||
|
use views::BlockView;
|
||||||
|
|
||||||
|
#[derive(Default, Clone)]
|
||||||
|
pub struct BlockFinalizer {
|
||||||
|
parent_hash: H256
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockFinalizer {
|
||||||
|
pub fn fork(&self) -> Self {
|
||||||
|
self.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub trait CompleteBlock {
|
||||||
|
fn complete(self, parent_hash: H256) -> Bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Complete<'a, I> where I: 'a {
|
||||||
|
pub iter: &'a mut I,
|
||||||
|
pub finalizer: &'a mut BlockFinalizer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, I> Iterator for Complete<'a, I> where I: Iterator, <I as Iterator>::Item: CompleteBlock {
|
||||||
|
type Item = Bytes;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.iter.next().map(|item| {
|
||||||
|
let rlp = item.complete(self.finalizer.parent_hash.clone());
|
||||||
|
self.finalizer.parent_hash = BlockView::new(&rlp).header_view().sha3();
|
||||||
|
rlp
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
42
ethcore/src/blockchain/generator/fork.rs
Normal file
42
ethcore/src/blockchain/generator/fork.rs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
pub trait Forkable {
|
||||||
|
fn fork(self, fork_number: usize) -> Self where Self: Sized;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct Fork<I> {
|
||||||
|
pub iter: I,
|
||||||
|
pub fork_number: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> Clone for Fork<I> where I: Iterator + Clone {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Fork {
|
||||||
|
iter: self.iter.clone(),
|
||||||
|
fork_number: self.fork_number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> Iterator for Fork<I> where I: Iterator, <I as Iterator>::Item: Forkable {
|
||||||
|
type Item = <I as Iterator>::Item;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
self.iter.next().map(|item| item.fork(self.fork_number))
|
||||||
|
}
|
||||||
|
}
|
169
ethcore/src/blockchain/generator/generator.rs
Normal file
169
ethcore/src/blockchain/generator/generator.rs
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use util::hash::H2048;
|
||||||
|
use util::numbers::U256;
|
||||||
|
use util::bytes::Bytes;
|
||||||
|
use header::BlockNumber;
|
||||||
|
use super::fork::Fork;
|
||||||
|
use super::bloom::Bloom;
|
||||||
|
use super::complete::{BlockFinalizer, CompleteBlock, Complete};
|
||||||
|
use super::block::Block;
|
||||||
|
|
||||||
|
/// Chain iterator interface.
|
||||||
|
pub trait ChainIterator: Iterator + Sized {
|
||||||
|
/// Should be called to create a fork of current iterator.
|
||||||
|
/// Blocks generated by fork will have lower difficulty than current chain.
|
||||||
|
fn fork(&self, fork_number: usize) -> Fork<Self> where Self: Clone;
|
||||||
|
/// Should be called to make every consecutive block have given bloom.
|
||||||
|
fn with_bloom(&mut self, bloom: H2048) -> Bloom<Self>;
|
||||||
|
/// Should be called to complete block. Without complete, block may have incorrect hash.
|
||||||
|
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self>;
|
||||||
|
/// Completes and generates block.
|
||||||
|
fn generate<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Option<Bytes> where Self::Item: CompleteBlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I> ChainIterator for I where I: Iterator + Sized {
|
||||||
|
fn fork(&self, fork_number: usize) -> Fork<Self> where I: Clone {
|
||||||
|
Fork {
|
||||||
|
iter: self.clone(),
|
||||||
|
fork_number: fork_number
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn with_bloom(&mut self, bloom: H2048) -> Bloom<Self> {
|
||||||
|
Bloom {
|
||||||
|
iter: self,
|
||||||
|
bloom: bloom
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn complete<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Complete<'a, Self> {
|
||||||
|
Complete {
|
||||||
|
iter: self,
|
||||||
|
finalizer: finalizer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generate<'a>(&'a mut self, finalizer: &'a mut BlockFinalizer) -> Option<Bytes> where <I as Iterator>::Item: CompleteBlock {
|
||||||
|
self.complete(finalizer).next()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Blockchain generator.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct ChainGenerator {
|
||||||
|
/// Next block number.
|
||||||
|
number: BlockNumber,
|
||||||
|
/// Next block difficulty.
|
||||||
|
difficulty: U256,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ChainGenerator {
|
||||||
|
fn prepare_block(&self) -> Block {
|
||||||
|
let mut block = Block::default();
|
||||||
|
block.header.number = self.number;
|
||||||
|
block.header.difficulty = self.difficulty;
|
||||||
|
block
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for ChainGenerator {
|
||||||
|
fn default() -> Self {
|
||||||
|
ChainGenerator {
|
||||||
|
number: 0,
|
||||||
|
difficulty: U256::from(1000),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Iterator for ChainGenerator {
|
||||||
|
type Item = Block;
|
||||||
|
|
||||||
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
let block = self.prepare_block();
|
||||||
|
self.number += 1;
|
||||||
|
Some(block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mod tests {
|
||||||
|
use util::hash::{H256, H2048};
|
||||||
|
use util::sha3::Hashable;
|
||||||
|
use views::BlockView;
|
||||||
|
use blockchain::generator::{ChainIterator, ChainGenerator, BlockFinalizer};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn canon_chain_generator() {
|
||||||
|
let mut canon_chain = ChainGenerator::default();
|
||||||
|
let mut finalizer = BlockFinalizer::default();
|
||||||
|
|
||||||
|
let genesis_rlp = canon_chain.generate(&mut finalizer).unwrap();
|
||||||
|
let genesis = BlockView::new(&genesis_rlp);
|
||||||
|
|
||||||
|
assert_eq!(genesis.header_view().parent_hash(), H256::default());
|
||||||
|
assert_eq!(genesis.header_view().number(), 0);
|
||||||
|
|
||||||
|
let b1_rlp = canon_chain.generate(&mut finalizer).unwrap();
|
||||||
|
let b1 = BlockView::new(&b1_rlp);
|
||||||
|
|
||||||
|
assert_eq!(b1.header_view().parent_hash(), genesis.header_view().sha3());
|
||||||
|
assert_eq!(b1.header_view().number(), 1);
|
||||||
|
|
||||||
|
let mut fork_chain = canon_chain.fork(1);
|
||||||
|
|
||||||
|
let b2_rlp_fork = fork_chain.generate(&mut finalizer.fork()).unwrap();
|
||||||
|
let b2_fork = BlockView::new(&b2_rlp_fork);
|
||||||
|
|
||||||
|
assert_eq!(b2_fork.header_view().parent_hash(), b1.header_view().sha3());
|
||||||
|
assert_eq!(b2_fork.header_view().number(), 2);
|
||||||
|
|
||||||
|
let b2_rlp = canon_chain.generate(&mut finalizer).unwrap();
|
||||||
|
let b2 = BlockView::new(&b2_rlp);
|
||||||
|
|
||||||
|
assert_eq!(b2.header_view().parent_hash(), b1.header_view().sha3());
|
||||||
|
assert_eq!(b2.header_view().number(), 2);
|
||||||
|
assert!(b2.header_view().difficulty() > b2_fork.header_view().difficulty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn with_bloom_generator() {
|
||||||
|
let bloom = H2048([0x1; 256]);
|
||||||
|
let mut gen = ChainGenerator::default();
|
||||||
|
let mut finalizer = BlockFinalizer::default();
|
||||||
|
|
||||||
|
let block0_rlp = gen.with_bloom(bloom).generate(&mut finalizer).unwrap();
|
||||||
|
let block1_rlp = gen.generate(&mut finalizer).unwrap();
|
||||||
|
let block0 = BlockView::new(&block0_rlp);
|
||||||
|
let block1 = BlockView::new(&block1_rlp);
|
||||||
|
|
||||||
|
assert_eq!(block0.header_view().number(), 0);
|
||||||
|
assert_eq!(block0.header_view().parent_hash(), H256::default());
|
||||||
|
|
||||||
|
assert_eq!(block1.header_view().number(), 1);
|
||||||
|
assert_eq!(block1.header_view().parent_hash(), block0.header_view().sha3());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn generate_1000_blocks() {
|
||||||
|
let generator = ChainGenerator::default();
|
||||||
|
let mut finalizer = BlockFinalizer::default();
|
||||||
|
let blocks: Vec<_> = generator.take(1000).complete(&mut finalizer).collect();
|
||||||
|
assert_eq!(blocks.len(), 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
24
ethcore/src/blockchain/generator/mod.rs
Normal file
24
ethcore/src/blockchain/generator/mod.rs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
mod bloom;
|
||||||
|
mod block;
|
||||||
|
mod complete;
|
||||||
|
mod fork;
|
||||||
|
pub mod generator;
|
||||||
|
|
||||||
|
pub use self::complete::BlockFinalizer;
|
||||||
|
pub use self::generator::{ChainIterator, ChainGenerator};
|
119
ethcore/src/blockchain/import_route.rs
Normal file
119
ethcore/src/blockchain/import_route.rs
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Import route.
|
||||||
|
|
||||||
|
use util::hash::H256;
|
||||||
|
use blockchain::block_info::{BlockInfo, BlockLocation};
|
||||||
|
|
||||||
|
/// Import route for newly inserted block.
|
||||||
|
#[derive(Debug, PartialEq)]
|
||||||
|
pub struct ImportRoute {
|
||||||
|
/// Blocks that were invalidated by new block.
|
||||||
|
pub retracted: Vec<H256>,
|
||||||
|
/// Blocks that were validated by new block.
|
||||||
|
pub enacted: Vec<H256>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ImportRoute {
|
||||||
|
pub fn none() -> Self {
|
||||||
|
ImportRoute {
|
||||||
|
retracted: vec![],
|
||||||
|
enacted: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<BlockInfo> for ImportRoute {
|
||||||
|
fn from(info: BlockInfo) -> ImportRoute {
|
||||||
|
match info.location {
|
||||||
|
BlockLocation::CanonChain => ImportRoute {
|
||||||
|
retracted: vec![],
|
||||||
|
enacted: vec![info.hash],
|
||||||
|
},
|
||||||
|
BlockLocation::Branch => ImportRoute::none(),
|
||||||
|
BlockLocation::BranchBecomingCanonChain { mut enacted, retracted, .. } => {
|
||||||
|
enacted.push(info.hash);
|
||||||
|
ImportRoute {
|
||||||
|
retracted: retracted,
|
||||||
|
enacted: enacted,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use util::hash::H256;
|
||||||
|
use util::numbers::U256;
|
||||||
|
use blockchain::block_info::{BlockInfo, BlockLocation};
|
||||||
|
use blockchain::ImportRoute;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn import_route_none() {
|
||||||
|
assert_eq!(ImportRoute::none(), ImportRoute {
|
||||||
|
enacted: vec![],
|
||||||
|
retracted: vec![],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn import_route_branch() {
|
||||||
|
let info = BlockInfo {
|
||||||
|
hash: H256::from(U256::from(1)),
|
||||||
|
number: 0,
|
||||||
|
total_difficulty: U256::from(0),
|
||||||
|
location: BlockLocation::Branch,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(ImportRoute::from(info), ImportRoute::none());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn import_route_canon_chain() {
|
||||||
|
let info = BlockInfo {
|
||||||
|
hash: H256::from(U256::from(1)),
|
||||||
|
number: 0,
|
||||||
|
total_difficulty: U256::from(0),
|
||||||
|
location: BlockLocation::CanonChain,
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(ImportRoute::from(info), ImportRoute {
|
||||||
|
retracted: vec![],
|
||||||
|
enacted: vec![H256::from(U256::from(1))],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn import_route_branch_becoming_canon_chain() {
|
||||||
|
let info = BlockInfo {
|
||||||
|
hash: H256::from(U256::from(2)),
|
||||||
|
number: 0,
|
||||||
|
total_difficulty: U256::from(0),
|
||||||
|
location: BlockLocation::BranchBecomingCanonChain {
|
||||||
|
ancestor: H256::from(U256::from(0)),
|
||||||
|
enacted: vec![H256::from(U256::from(1))],
|
||||||
|
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(ImportRoute::from(info), ImportRoute {
|
||||||
|
retracted: vec![H256::from(U256::from(3)), H256::from(U256::from(4))],
|
||||||
|
enacted: vec![H256::from(U256::from(1)), H256::from(U256::from(2))],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
33
ethcore/src/blockchain/mod.rs
Normal file
33
ethcore/src/blockchain/mod.rs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Blockchain database.
|
||||||
|
|
||||||
|
pub mod blockchain;
|
||||||
|
mod best_block;
|
||||||
|
mod block_info;
|
||||||
|
mod bloom_indexer;
|
||||||
|
mod cache;
|
||||||
|
mod tree_route;
|
||||||
|
mod update;
|
||||||
|
mod import_route;
|
||||||
|
#[cfg(test)]
|
||||||
|
mod generator;
|
||||||
|
|
||||||
|
pub use self::blockchain::{BlockProvider, BlockChain, BlockChainConfig};
|
||||||
|
pub use self::cache::CacheSize;
|
||||||
|
pub use self::tree_route::TreeRoute;
|
||||||
|
pub use self::import_route::ImportRoute;
|
29
ethcore/src/blockchain/tree_route.rs
Normal file
29
ethcore/src/blockchain/tree_route.rs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use util::numbers::H256;
|
||||||
|
|
||||||
|
/// Represents a tree route between `from` block and `to` block:
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct TreeRoute {
|
||||||
|
/// A vector of hashes of all blocks, ordered from `from` to `to`.
|
||||||
|
pub blocks: Vec<H256>,
|
||||||
|
/// Best common ancestor of these blocks.
|
||||||
|
pub ancestor: H256,
|
||||||
|
/// An index where best common ancestor would be.
|
||||||
|
pub index: usize,
|
||||||
|
}
|
||||||
|
|
21
ethcore/src/blockchain/update.rs
Normal file
21
ethcore/src/blockchain/update.rs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
use std::collections::HashMap;
|
||||||
|
use util::numbers::H256;
|
||||||
|
use header::BlockNumber;
|
||||||
|
use blockchain::block_info::BlockInfo;
|
||||||
|
use extras::{BlockDetails, BlockReceipts, TransactionAddress, BlocksBlooms};
|
||||||
|
|
||||||
|
/// Block extras update info.
|
||||||
|
pub struct ExtrasUpdate {
|
||||||
|
/// Block info.
|
||||||
|
pub info: BlockInfo,
|
||||||
|
/// Modified block hashes.
|
||||||
|
pub block_hashes: HashMap<BlockNumber, H256>,
|
||||||
|
/// Modified block details.
|
||||||
|
pub block_details: HashMap<H256, BlockDetails>,
|
||||||
|
/// Modified block receipts.
|
||||||
|
pub block_receipts: HashMap<H256, BlockReceipts>,
|
||||||
|
/// Modified transaction addresses.
|
||||||
|
pub transactions_addresses: HashMap<H256, TransactionAddress>,
|
||||||
|
/// Modified blocks blooms.
|
||||||
|
pub blocks_blooms: HashMap<H256, BlocksBlooms>,
|
||||||
|
}
|
@ -19,7 +19,7 @@ use crypto::sha2::Sha256;
|
|||||||
use crypto::ripemd160::Ripemd160;
|
use crypto::ripemd160::Ripemd160;
|
||||||
use crypto::digest::Digest;
|
use crypto::digest::Digest;
|
||||||
|
|
||||||
/// Definition of a contract whose implementation is built-in.
|
/// Definition of a contract whose implementation is built-in.
|
||||||
pub struct Builtin {
|
pub struct Builtin {
|
||||||
/// The gas cost of running this built-in for the given size of input data.
|
/// The gas cost of running this built-in for the given size of input data.
|
||||||
pub cost: Box<Fn(usize) -> U256>, // TODO: U256 should be bignum.
|
pub cost: Box<Fn(usize) -> U256>, // TODO: U256 should be bignum.
|
||||||
@ -63,14 +63,16 @@ impl Builtin {
|
|||||||
|
|
||||||
/// Create a builtin from JSON.
|
/// Create a builtin from JSON.
|
||||||
///
|
///
|
||||||
/// JSON must be of the form `{ "name": "identity", "linear": {"base": 10, "word": 20} }`.
|
/// JSON must be of the form `{ "name": "identity", "pricing": {"base": 10, "word": 20} }`.
|
||||||
pub fn from_json(json: &Json) -> Option<Builtin> {
|
pub fn from_json(json: &Json) -> Option<Builtin> {
|
||||||
// NICE: figure out a more convenient means of handing errors here.
|
// NICE: figure out a more convenient means of handing errors here.
|
||||||
if let Json::String(ref name) = json["name"] {
|
if let Json::String(ref name) = json["name"] {
|
||||||
if let Json::Object(ref o) = json["linear"] {
|
if let Json::Object(ref o) = json["pricing"] {
|
||||||
if let Json::U64(ref word) = o["word"] {
|
if let Json::Object(ref o) = o["linear"] {
|
||||||
if let Json::U64(ref base) = o["base"] {
|
if let Json::U64(ref word) = o["word"] {
|
||||||
return Self::from_named_linear(&name[..], *base as usize, *word as usize);
|
if let Json::U64(ref base) = o["base"] {
|
||||||
|
return Self::from_named_linear(&name[..], *base as usize, *word as usize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,7 +276,7 @@ fn from_named_linear() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn from_json() {
|
fn from_json() {
|
||||||
let text = "{ \"name\": \"identity\", \"linear\": {\"base\": 10, \"word\": 20} }";
|
let text = r#"{"name": "identity", "pricing": {"linear": {"base": 10, "word": 20}}}"#;
|
||||||
let json = Json::from_str(text).unwrap();
|
let json = Json::from_str(text).unwrap();
|
||||||
let b = Builtin::from_json(&json).unwrap();
|
let b = Builtin::from_json(&json).unwrap();
|
||||||
assert_eq!((*b.cost)(0), U256::from(10));
|
assert_eq!((*b.cost)(0), U256::from(10));
|
||||||
|
40
ethcore/src/chainfilter/bloomindex.rs
Normal file
40
ethcore/src/chainfilter/bloomindex.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Represents bloom index in cache
|
||||||
|
|
||||||
|
/// Represents bloom index in cache
|
||||||
|
///
|
||||||
|
/// On cache level 0, every block bloom is represented by different index.
|
||||||
|
/// On higher cache levels, multiple block blooms are represented by one
|
||||||
|
/// index. Their `BloomIndex` can be created from block number and given level.
|
||||||
|
#[derive(Eq, PartialEq, Hash, Clone, Debug)]
|
||||||
|
pub struct BloomIndex {
|
||||||
|
/// Bloom level
|
||||||
|
pub level: u8,
|
||||||
|
/// Filter Index
|
||||||
|
pub index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BloomIndex {
|
||||||
|
/// Default constructor for `BloomIndex`
|
||||||
|
pub fn new(level: u8, index: usize) -> BloomIndex {
|
||||||
|
BloomIndex {
|
||||||
|
level: level,
|
||||||
|
index: index,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
739
ethcore/src/chainfilter/blooms.txt
Normal file
739
ethcore/src/chainfilter/blooms.txt
Normal file
@ -0,0 +1,739 @@
|
|||||||
|
300054 0x00000000000000000000000000000000000000000000020000001000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
300059 0x00000020000000000000000000000000000000000000000002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000002000
|
||||||
|
300221 0x00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
301826 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
303166 0x00000000000000000000000000000000000000001000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000808000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000020000000001000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
303345 0x00000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000000000000000000000000000000000000008000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
303379 0x00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000080000000006000008000000000000000000080000000000000000000000000000000000000000001000000000000000000000008000000000400000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000800000000000000000000000000000000000002004000000000000
|
||||||
|
303388 0x00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000800000040000000001000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000080000000006001008000000000000008000080000000000000000000000000000000000000000001000000000000000000000008000000000400000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000800000000000000040000000000000000000002004000000000000
|
||||||
|
303621 0x00000000000000000000008000000000200000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000080000000000000000000000080000000001100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000
|
||||||
|
303670 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000400200000000000000
|
||||||
|
303674 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
|
||||||
|
303683 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000400200000000000000
|
||||||
|
303689 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000040200000000000000
|
||||||
|
303692 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000040200000000000000
|
||||||
|
303716 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
|
||||||
|
303717 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
|
||||||
|
303748 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000400200000000000000
|
||||||
|
303756 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000080000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000040200000000000000
|
||||||
|
303758 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000400000000000000000000000000000000000000000000000000000000001000000000040200000000000000
|
||||||
|
304090 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000000000000000000040000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000003000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304095 0x04000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000008000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000
|
||||||
|
304107 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000400000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304113 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000002000000000000000000000000000000000000000000000000003008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304222 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000800000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304245 0x00000000000000000000000000000000100000000000000000000000000000000000000000000000000200000000000000800000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000080000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304247 0x000000080000000000000000000000800000020000000000000000000000000000000000000000000202000000000000008000004004000000000000000000000000000000000000000000000200000000200000000080000000000000000000000004000000000000000000000000000000001040000000000000000000000000000004000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000c0002000000000000000000000000000000001000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304312 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000040000000000000200000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304319 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000100000000000020000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000080000000000000000000000000008000000000000000000000000000000000008000000000000000000000000000000000000020000000000002000000000000000000040000000000000200000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304367 0x00000000000000000000001000000000000000000400020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000100000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304375 0x00000000004000000000001000000000000000000400020000000800000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000020000000000000000000000000000000000000000000000000008000000000000010000000008000000000000000000000000000000000008000800000000000000000000000100000000000000000000000000000000000000000100000000000000002000000000002000000040010010000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304407 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304431 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304433 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304608 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000400000000000000000000040000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304609 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000400000000000000000000040000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304788 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304794 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304819 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304835 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304849 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304856 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304862 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
304872 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304881 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304902 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304996 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
304999 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305006 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
305010 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305425 0x00000000004000000000000000000001000000000000020000000000000000000000000000000000000000000000000000000000008000000080000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010400000048000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000400000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305445 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000080000100000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305448 0x00000000004000000000000000000000000000000000020000000000000000000004000008000000000000000000000000000000000000000000000000000800000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000080000100000000002000000000000000000040000000000000000000000100000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305450 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000080000000000000000000000000000020000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000004000000000000000000000000000
|
||||||
|
305452 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000002000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000080000000000000000000000000000020000000000000000000000000000000000000000000008002000000000000000000040000000000000000000000000400000000000000000000000000000000004000000000000000000000000000
|
||||||
|
305454 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000001000000040000000000000000000000000000000000000000000000000000000000000000000000000840000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305457 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305463 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000200080000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305464 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000008000000000000000000000000000000000240000000200480000000000000000000000000000000000000000000000000000002000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305468 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008080000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305488 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000002000000000000008000000000000010000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305492 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000008000000000000000000000000000000008040000000000000000000000000000002000000000001000000000000000000000000000400000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000200000000000000000000000000000000000000000000
|
||||||
|
305501 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000008000000000000000000040000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000080000000000000
|
||||||
|
305502 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000008000000000000008000000000000000000040000000001000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000080000000000000000000000000000000000010000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000080000000000000
|
||||||
|
305510 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000044000004000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305616 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305620 0x0000000000400000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000080000000000000000000000000000800000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000040000000001000000000a000000000000000010000000000000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305622 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000080000000000000000000000000200000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000080000000000000
|
||||||
|
305624 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000001000000000000000080000000000000000000000000200000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000004000000000000000000000000004000000000000000000000000000000000000080000000000000
|
||||||
|
305626 0x00000000004000000000100000000000000000000000020000000000000000000000000002000000000000000000000000000000200000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000010000000004000000000002000000000000002000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305627 0x00000001000000000000000000000200000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305629 0x00000001004000000000000000000200000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000040000000000000000001040000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305634 0x00000000005080000000000000000000000000000000020000400000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008020000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000400000000000000000000000
|
||||||
|
305826 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000400000000000000002000000000000000000840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305827 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000100000000000000000000000000040000000000000000000000000000000000000000000000000000000000000040000000000000000000000010000000008000000000000000000000000000000100008000000000000000000000000000000000000000000000000000000000000000000000400000000000000002004000000000000000840000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305829 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000008000000000080000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000080000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305834 0x00000000004002000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000041000000000000000000000000000000000000008000000000080000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000020000000000000000000000000000008000000000000000000000000000000000000000000000080000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305839 0x00000000000000000000000000000000000010000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000080000000000000000000000000000000000000000000000000000000000000
|
||||||
|
305841 0x40000000004000000000000000000000000010000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000008000000008000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000080000000000000000000000000000000000000000000008000000000000000
|
||||||
|
306889 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
307290 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
307508 0x00000000000000000000000000000000000000000000020000000000000000000000200000000000400000000000000000000000000000000000000000000000002000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
307509 0x00000000004000000000000000000000000000000000020000000000000000000000200000000000400000000000000000000000000000000000000000000000002000000000000000008000000000000000000000000000000000040000000000040000000000000000000000000000000000000000000000000000000000000000000000000010000000008000010000004000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
307513 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000004000000000000000000000000010000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000200000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
307519 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000001000000000000002000000000000000000040000000000000000000000000000000000000000000080000000000000000000000000000000000000000000
|
||||||
|
307528 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000020000000000000000000000000000000000000000000000000000000000000000100000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
308010 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002020000000000080000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000
|
||||||
|
308115 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
|
||||||
|
308124 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000400200000000000000
|
||||||
|
308127 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
|
||||||
|
308157 0x00000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000020000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000
|
||||||
|
308183 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000002020000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
308190 0x00000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000020000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000
|
||||||
|
308216 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000002020000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
308224 0x00000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000000000000000000000000020000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000
|
||||||
|
308257 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
308265 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
308267 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
308268 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
308285 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
308599 0x00000000000000000000000000000000000000000000080000000000000800000000000000000010000000000000000000200002000000000000000000000000000000000000000000020000001000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004010010000002000000000000000400000000000000000000000000000000000000000000040000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
309175 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
309177 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
309184 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
309186 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
309190 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
309194 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
309198 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
309417 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
309881 0x00400000000000000000000000000000000000000000004000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000
|
||||||
|
309883 0x00400000000000000000000000000000000000000000004000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000
|
||||||
|
309892 0x00400000000000000000000000000000000000000000004000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000
|
||||||
|
310069 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
310114 0x00400000000000000000000000000000000000000000004000000000000000000000000000100000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
310116 0x00400000000000000000000000000000000000000000004000000000000000000000000000100000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
310177 0x00400000000000000000000000000000000000000000004000000000000000000000000000100000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
310533 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
310589 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
310592 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
310599 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
310601 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
310604 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
311317 0x00000000002000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
311758 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
311858 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
311859 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
311865 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
311888 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
312096 0x00400000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000200000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
312124 0x00400000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000200000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
312367 0x00400000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
312371 0x00400000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
312383 0x00400000000000000000000000000000000400000000004000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
313355 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
313368 0x00000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
313507 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
313526 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
313724 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
313789 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
314190 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
314375 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000008000000000000000008000400000000000000000000000000
|
||||||
|
315698 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
315705 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
315780 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
316726 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000040000000000000000
|
||||||
|
316747 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
317179 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000000000200000000000000
|
||||||
|
317522 0x04000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000006001008000000000000008000080000000000000000000000000000000000000000001000000000100000000000008000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000040000000000000008000002004000000000000
|
||||||
|
317526 0x00000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
317536 0x00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000020000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000006000008000000000000000000080000000000000000000000000000000000000000001000000000000000000000008000000800400000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
|
||||||
|
317567 0x00000000000000200000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000001004000000000000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000001000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
317588 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
317597 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
317606 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
317610 0x00000000000000200000000000000000000000000000000000020000000000000000000000000000000000400000000000000000000800000080000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000001044000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000400000000000000000000000000000000000000000000000000000000000000000000440000000000000000
|
||||||
|
317643 0x00000000000000200000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000010000000000000000000000000000004000000000020000000000000000000000000000000000000000000001004000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
317646 0x00000000000000000000000000000000000000000000000000004000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000010000000000000000000000000000004000000000020000000000000000000000000000000000000000000001000000000000000000004000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
317660 0x00000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000080000000006000008000000000000000000080000000000000000000000000000000000000000001000000000000000000000008000000000400002000000000000000000000000000000000000000000000000000008000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
|
||||||
|
317957 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
318030 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
318032 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
318033 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000008400000000000000000000000000000000000000000000000000008000000000000000000000000020000000000000800000000000000000000000000000000000002004000000000000
|
||||||
|
318034 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
318036 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
318063 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000040000000001000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000008400000000000000000000000000000000000000000000000000008000000000000000000000000040000000000000800000000000000000000000000000000000002004000000000000
|
||||||
|
318074 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000100000010020000000000000000000200000000000000000080000000020000000000000000000800000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000020000000000000000000000000000000000000000000000000102000000000000000
|
||||||
|
318096 0x04000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000100000000000000000000008400000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000008000002004000000000000
|
||||||
|
318137 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
318528 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000020000000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000808400000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
|
||||||
|
318627 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000000000000001000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000008400002000000000000000000000000000000000000000000000008000008000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
|
||||||
|
318639 0x00000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000800000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000002000000000000000000000010000000000000004800000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000080000000000000000000000000
|
||||||
|
318650 0x00000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000800000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000010000000000000004000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000
|
||||||
|
318653 0x00000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000010000000000000000000000000800000000000000000000000000000000000000000000000000000
|
||||||
|
318904 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
319523 0x00000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000400000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
321346 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
321884 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
321900 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000040000000000000000
|
||||||
|
322038 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322041 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322043 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322047 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322048 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322056 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322059 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000000000000800000000000000011000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006000000000000000000000001080000800000000000000000000000000000000000005000000000000000000000000000000008400000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
|
||||||
|
322083 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322090 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322108 0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000010020000000000000000000200000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000000000000004000000000100000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000008000100000000000000000
|
||||||
|
322121 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000010000000000100000010020000000000000000000200000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000001080000800000000000000000000000000000000000004000000000000000000000000000000808000000000000000400000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000000000100000000000000000
|
||||||
|
322122 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000100000010020000000000000000040200000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000040000000000000800000000000000000000000000000000000100000000000000000
|
||||||
|
322128 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000010020000000000000000000200000000000000000088000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000080000000000000000000000000000000000000000004000000000000000000000000000000008000002000000000000000000000000000000000000000000000008000008000000000000000000000000000000000800000000000000000000000000000000000100000000000000000
|
||||||
|
322454 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008010000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000010000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000080000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322509 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008010000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000080000000000000000000000000000008000000000200000000000000000010000000000000000000000000000000000000000000000000000000002000000000200000000040000000000000080000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322550 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322749 0x00000000001000000000000000000000000000000000000000000000000000000000000800000008000000000000000000000000000400000000800000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000080000000006400000000000000000000000080000000000000000000000000000000000000000005000000000000000000000000000000008400000000080000000000000000000000000000000000000000008000000000000000000000000000000000000000800000000000000000000000000000000000002004000000000000
|
||||||
|
322750 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000020000000000000040000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322752 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000008000000000000000000080000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000080000020000000000000040000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000080000000000000000000000
|
||||||
|
322758 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322760 0x00000004004000000000000000000000000000000000020000000000000000000000100000000000000000000000000000000000000000000000000000000000010000000000000000008000000000000000000000000000000000040000000000002000000000000000000000000000000000000000000004000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322764 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000001000000000000000000000000000000000000000000000000000000000000001000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000020000000000000000000000000000000
|
||||||
|
322765 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000400000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000001000000000000000000000000000000000000000000000000000000000000001000000000000000002000000000200000000040000000000000000000000000000000000000000000000000000000020000000000000000000000000000000
|
||||||
|
322767 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002080000000000000000040000000000000000000000000000000000000000000002000000000000000000000000000000000000000000
|
||||||
|
322768 0x00000000004000000000000000000000000000000000120000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000400000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002080004000000000000040000000000000000000000000000000000000000000002000000000000000000000000000000000000000000
|
||||||
|
322774 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000008000000000000000000000000000000000000000000000000000000000000000000002001000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322776 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000010000000000000000000000000040000000000000000000000000000000010000000008000000000000000000000000000000000009000000000000000008000000000000000000000000000000000000000000000000000000000000000000002001000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
322777 0x00000000004000000000008000100000000000000000020000000000000002000000000000000000000000000000000000000004000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000020000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000001000000000000000000000000000000000000000000000000
|
||||||
|
324029 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
324316 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000004000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
324318 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000
|
||||||
|
324322 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000400000000000000000000000000000000000000000000000000000008000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
325807 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
326760 0x00000000000000000000000000000000000000000000000000000040000000000000001000000000000000000000000000008000000000000000000000000000000000008000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000008000000000000000
|
||||||
|
327103 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
327105 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
327227 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000040000000000000000
|
||||||
|
327399 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
327544 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
327690 0x00000000000000000000000000000100000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
328002 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000200000000000
|
||||||
|
328269 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
328529 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
328585 0x20000000000000000000100000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
328870 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
329480 0x00000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000200000000000000000000000020000000000000000000000000000000000000000000
|
||||||
|
329484 0x00000000004000000000000008000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000040000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000200000000000000000000000020000000000000000000000000000000000000000000
|
||||||
|
329485 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
329491 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
329513 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
329519 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
329659 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000020000000000000000000000000000000000000000000000000000000000020000000010000000008000000000000000000000000000000000008000000400000000000000000000000000000000000000000000000000000000000000000000000000000002000000080000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000020000000
|
||||||
|
329667 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000100000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000002000000000000000000000000000000000000000000
|
||||||
|
329668 0x0000000000400000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000004000000000000010000000000000000000000000000000000000000000000000001000000000000000000001000000000c000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000002000000000000000000800000000000000000000000
|
||||||
|
329673 0x00000000004000001000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000004000000000000000000000000000000000000000000000000004000000000000000000010000000008000000000000000000000000000002000008000000000000000000000000000000000000000000000000000000000000000000000400400000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
329740 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000010000000000000
|
||||||
|
329749 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000008000000000000000000000000000000000000000002000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
329750 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000008000000000000000000000000000000000040000000040000000000000000000000010000000000000000000000000000000000000000000000000000010000000008000000000000000000000080000000000008000000000000000000000000000000000000000002000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000400000000000000000000000000000000000000000000
|
||||||
|
329824 0x00000000000000000000000000000000000000000000200000000000000000000000001000000000000000000000000000008000000008000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
329964 0x00000000000000000000000000000000000000000000000000000000100000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
330023 0x00000000000000000000000000000000000000000000000000000000100000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
330207 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000004000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000200000000000000000000000008000000000000000
|
||||||
|
330473 0x00000000000400000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000001000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
330511 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000002000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000400000000000000000000000020000000000000000000000000000000000000000000040000000000000000
|
||||||
|
330579 0x00000000000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000001000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
330683 0x00000000000000000000000000000000000000000000080000000000004000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
330919 0x00020000000000000000000000000000000000000000000000000000000000000008001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
331009 0x00000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
331542 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000100000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000004000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
332007 0x00000000000000000000000000000000000000000000000000000200000080000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008200000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
333256 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000400000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000010000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
333294 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
333583 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000200000000000000000000000000000000000000000000000000010008000000000000000
|
||||||
|
333640 0x80000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000004000000008000000000000000000000000000000000000010000000000000000000000000000000000008000000000000000
|
||||||
|
334263 0x00000000000000080000000000000000000000000000000000000000000000000100001000000000000010000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
334279 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000040000020000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000
|
||||||
|
334883 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
334915 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000004000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
334919 0x00000020000000000000000000000000000000000000000000000000000000000000001000000000000020000000000000008000000000000000000000000000000000000020000000000000020000812000002000000000000000000000000001000000000000000000000000000000400000000000000000000000000000000000000000000000040000800000000010000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000008000400000000008000000000000000
|
||||||
|
335076 0x00000000000000001000000000000000000000000000000000000000000000000000001000000000000000000100000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
335348 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000080000000008000000000000000000000040000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000008000000000
|
||||||
|
335643 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
335649 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
335652 0x00000000000008000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
335684 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000002000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
336089 0x0000000000000000000000000000000000000000000000000000000000020000000000100000000000000000000000000000800000000000000000000000000000000000000000000000000000000080200000a000000000000000000000000001000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
336231 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336234 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336242 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336243 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336244 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336245 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336247 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336248 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336255 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336260 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336263 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336264 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336266 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336334 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336336 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336337 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336338 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336439 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336451 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336452 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336453 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336461 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336495 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336497 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336507 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336508 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336509 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336510 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336518 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336520 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336521 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336522 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336526 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336527 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336528 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
336543 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000080000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000040000000000000000000200000000000000000000200000000000000000008000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
337012 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000001000000000000000000000000400000000000000802000002000000200000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
337642 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000408000000000000000000000000000000000040000080000000000000000080000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000020000000000000000002000000000000000000040000000000000001000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
337647 0x00000000000000000000000000000000000000000000020000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000800000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
337649 0x00000000004000000000000000000000000000000000020000000000000080000000100000000000000000000000000000000000000000000000000000000000000000000000000000008002000000000000000000000000000000040000000000000000000000000000000800000000000000000000000000000000000000000000000002000010000000008000000000000000000000000000000000008000000000000000000000000000000000200000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
337653 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000040000000000000000000040000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
337654 0x00000000004000000000008000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000020000040000000000000000000040000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
337655 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000040000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000400000000040000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
337656 0x00000000004000000000000000000000000400000000020000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000008000040000000000000000000000000000040000000000000000000000000000000000000000000000000000004000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000400000000040000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
337663 0x00000000004000000000000000000000080000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000001000000000000000000000000000050000000000000000000000000040000000000000000000000000000000000000000004000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000080000000000000000000000000000000000000
|
||||||
|
337664 0x00000000000000000000000000000000000000000000020000000010000000000000000000000000001000000000000000000000000000000000000000000000000200000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
337669 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000008000000000
|
||||||
|
337672 0x40000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000020000000000000010000000008000000000000000000000000008000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000008000008000000000
|
||||||
|
337731 0x00000000000000000000000020000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000800000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
338275 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010004000200000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
338281 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010004000200000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
338336 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
338424 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008004000000000000000000000000000000000000100000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
338435 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000008000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000004000000000000000000000000010000000000000000000000000000000000000
|
||||||
|
338439 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000010802000002000000000000000000000000001000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
338661 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
338991 0x00000000000000000000000000200000000000000008000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000400800000000000000000000000000000010000000000000000000000000000000000000000000000000
|
||||||
|
339173 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002400000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000088000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
339369 0x00000020000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
339427 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000020000000000000000000001000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
340633 0x00000000000000000000000000000000000000000000020000000004000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
340635 0x00000000004000000000000000000000000000000000020000000004000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000200000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000001000000000200000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
340653 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000001000000002000000000000000000040000000000000000000000000000000000000000000000000000000010000000000000000000000000000000
|
||||||
|
340658 0x0000000000400000000000000000000400000000000002000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000020000000000000000000001000000000800000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000100000000a000000000000000000040000000000000000000000000000000000000000000000000000000010000000000000000000000000000000
|
||||||
|
340674 0x00000000000800000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040080000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
340675 0x00000000004800000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000100000000000000000000000000000000000000000000000000000000000000000000000000000002000010000000000000040080000000000000000000000000000000000002000000000000000000080000000000000000000000000000
|
||||||
|
340685 0x00000000000000000000000000000000000000000000020010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000008000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
340686 0x00004000004000000000000000000000000000000000820010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000010000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000008000000000000040000000000000000000000000000000000000000000000000002000000000000000000000000000000000000
|
||||||
|
340700 0x00000000004000000000000000000000000000000000020001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000080000000000000000000000000000000000008000000000000000000000000000000000000000000002004200000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000001000
|
||||||
|
340708 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000008000000000000000000000000000040000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000080000000000000000000000000000000000000
|
||||||
|
340710 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000008000000000000000000000000000040000000000000100000000000000000800000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000400000000000000000000000000000000000000000000000000002000002000000000000040000000000000000000000000000000000000000000000000080000000000000000000000000000000000000
|
||||||
|
340712 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000080040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000008000000000200000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
340713 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000080840000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000028000000100000000000000000000000000008000000000200000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000001000000000000000000000
|
||||||
|
340718 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000100000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000002000000000000
|
||||||
|
340719 0x00000000004000000000000000000000000000000000020000000040000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000008000000000000080000002000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000100000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000002000000000000
|
||||||
|
340727 0x00000000004000000000040000002000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000200000000000080000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000001000000000000000000000000000000
|
||||||
|
340728 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000002000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000100000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
340835 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
340988 0x00000000000000000010000000000000000000000010000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000010000000000008000000000000000
|
||||||
|
341695 0x00000000000000000000000010000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000001000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
341985 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000100000000000004000000000000001000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
341997 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000000000004000000000000001000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
342001 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000100000000000004000000000000001000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
342004 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000100000000000004000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342007 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000004000000000000001000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342008 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000004000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342026 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000020000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
342027 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
342033 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
342035 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
342036 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
342041 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
342047 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000100000000000000000000000000000000002000000104000000000044100000000000001000002000000000000000000000001000000000000000000004000000000000080000000000000000000000000000000000000002000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
342053 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342080 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000000000000000000000000000000000000000040000000000000000000001040000000000000000000000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000440000000000000000
|
||||||
|
342101 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
342107 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342111 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342115 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
342118 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
342125 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342140 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
342141 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342145 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000000000000000000000000000000000000000040000000000000000000001040000000000000000000000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000440000000000000000
|
||||||
|
342162 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342173 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342188 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342272 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
342386 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000008000000000000000000000000000000000000000000000000000004000000000000000000000000000008000000000000000000000000001000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000010000000004000000000000000000000000010000000000000000000400000000000000000
|
||||||
|
342399 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
342466 0x00000000000000000000000000000000000000000000000000002000000000000000001000000000080000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
342601 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
342616 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
342618 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
342924 0x00000000000000000000000000000000000010000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
342964 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000081000000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
343006 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000080000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00000000000000000
|
||||||
|
343021 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000004000000000000000000000000000000000000000000000000080000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000
|
||||||
|
343059 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000008000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
343079 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000200000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
343083 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000040000000000000802000002000000000000000000000000001000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
343133 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
343162 0x00000020000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000100000000000000000000000000008000400000000000000000000000000
|
||||||
|
343185 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
343339 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000080000000000000000802000002000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
343946 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
343966 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
343971 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
344121 0x00000000000000000000000000000000000000000000000000000040000000000000001000000000000000000000000000008000000000000000000000000000000000008000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000008000000000000000
|
||||||
|
344164 0x00000000000000000000000000000000000000000000000000000040000000000000001000000000000000000000000000008000000000000000000000000000000000008000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000002000000000000008000000000000000
|
||||||
|
344839 0x00000000000000000000000000000000000000000000000000000000000000000200001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000008000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
345506 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
346112 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
346392 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
346395 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
346398 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
346425 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
346448 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
346451 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
346454 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
346464 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
346466 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
347014 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000400000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
347301 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000200000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000002000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
347333 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000200000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000002000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
347613 0x00000000000000000000000000000000000000000800000000000000000000000000000000000000000001000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010004000000002000000000000000000000000000000000000000000000000000000001000000040000000000000000000000800000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000001000000000000000000000
|
||||||
|
347700 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400010000000000000
|
||||||
|
347705 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400010000000000000
|
||||||
|
347711 0x00000000000000000000000000000000000000004000000000020000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040010000000000000
|
||||||
|
347853 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000
|
||||||
|
347953 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000
|
||||||
|
347958 0x00000000000000000000000000000000000000004000000000020000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040010000000000000
|
||||||
|
347960 0x00000000000000000000000000000000000000000000000000020000002000000001000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040010000000000000
|
||||||
|
348019 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
348244 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000004000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
348443 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000400000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
348675 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000080000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000400100000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
348743 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
348936 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000100000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000002000000000000000000000000000000000000000008000000000000000
|
||||||
|
350544 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
351473 0x00000000000000000000000000000000000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000
|
||||||
|
353157 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
353181 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000400000000000000000
|
||||||
|
353196 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
|
||||||
|
353273 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000
|
||||||
|
353276 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
|
||||||
|
353359 0x00000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000200000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000100000040
|
||||||
|
353360 0x00000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000040
|
||||||
|
353361 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008002400000000000000000000000000
|
||||||
|
353367 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000080000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000008000000000000000
|
||||||
|
353370 0x02000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
353438 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000080000000000000000000000000000000000000000000000000002000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000040
|
||||||
|
353443 0x0000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000a000400000000000000000000000000
|
||||||
|
353447 0x00000028000000000000000000000080000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
353479 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000002000001000000000000000000000000100000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
354071 0x02000000000000000000000000000000000000000000020000000000000000000000000040000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000001000000000020000000000000000000000200000000000000020000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000140000000000000000
|
||||||
|
354151 0x00000000000000000000000000000000000000000000002000000000000000000000400000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004040000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000080000000400000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
354162 0x00000000000000000000000000004000000000000000000000000000000000000000410000000000200000000000000002000000000002000000000040000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000
|
||||||
|
354233 0x00000000000000000000000000000000000000000000000000000000000000000000400040000004000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024040000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000400000000000000000000000040000000000000000000000000000000000100000000000000000
|
||||||
|
354585 0x00000000000000000000000000000000000000000000000000100000000000000000400000000000200000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004001000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000
|
||||||
|
354866 0x00000000000000000000000000000000000000000000000000001000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001
|
||||||
|
356461 0x00000000000000000000000000200000000000000000000000000000010000000000000000000000000000000000000000202000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
356488 0x00000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000200000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000020000000000000080000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000
|
||||||
|
356513 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000100001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000080000000000000a00000000000000000000000
|
||||||
|
356526 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
356535 0x00000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000
|
||||||
|
356543 0x00000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000800080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000
|
||||||
|
357195 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
357579 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
357588 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
357590 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000200000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
357592 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
357600 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
357622 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
357630 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
358290 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
358426 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
358556 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
358811 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000400000000000000000000000000000000002000000000008000000000000000
|
||||||
|
359114 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
359375 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000100000000000000000
|
||||||
|
359378 0x00000020000000000010000000000000000004000000000000000200400000000000000000000000000000000002000000000000000000020000000000000000000000000000000000000000000000010000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000040000000000040010000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000400000000000
|
||||||
|
359538 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
361585 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
361588 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
361732 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000842000002000000000000000000000000001000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000080000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
361757 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
361775 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
362002 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000010000000000000000000000000802000002000000000000000000000400001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
365791 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000040
|
||||||
|
365793 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000010000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000400010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
369141 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000200000000000000000000000000000000000000000000000000000000000000000008000000000010000
|
||||||
|
369239 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
369249 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
369253 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
369259 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
369261 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
369263 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
369274 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
369426 0x00000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000200000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000100000040
|
||||||
|
369428 0x20000020000000000000000000800000000004000000000000000200400000000000000040000000000000000000000000000000000000020000000000000000000000000000000000000000000000010000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000040000000000000010000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000008000400800000000000000000000000
|
||||||
|
369431 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000400000000000100000000000040
|
||||||
|
369538 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000040
|
||||||
|
369540 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
370399 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000001000000000000802000002000000000000000000000000001000000100000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
370517 0x00000000000000000000000000000080200000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000080004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
370545 0x00000000000000000000000000000080200000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000080004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371190 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371280 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371286 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371288 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371299 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371307 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371327 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371329 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371352 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371360 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371362 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371369 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371378 0x00000000000000000000000000000080200000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000080004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371450 0x00000000000000000000000000000080200000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000080004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371489 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371509 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371532 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371658 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371660 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371876 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371904 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371906 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371912 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371914 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371918 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371931 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371933 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371938 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
371940 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
371973 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
372006 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
372014 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
372847 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
374209 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
374225 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
374365 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
374388 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020001000000000000000000000200000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
375079 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
375093 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
375401 0x00000000000000000000000000000000000400000400000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
375440 0x00000000000000000000000000000000000400000400000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
375447 0x00000000000000000000000000000000000400000400000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
376493 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
376573 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
376588 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
376644 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
376650 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
376668 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
376906 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
377026 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
377139 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000001000000000000080000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
|
||||||
|
377506 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
377523 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
377525 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
377581 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000040
|
||||||
|
377586 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000040000000000000000000000100000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
377608 0x00000000000000000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
377627 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
|
||||||
|
377629 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
|
||||||
|
377703 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000001000000000000080000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
|
||||||
|
377730 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
377746 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000400000000000000000
|
||||||
|
377877 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
377894 0x00000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
377905 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000002000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000080000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
377917 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
377922 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
377925 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
378345 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
378347 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
379027 0x00000020000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
379032 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
379039 0x08000020000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
379158 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000400000000000000000002000040000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379161 0x00000400004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000040000000000000000000000000000000000000000000010000000008000000000000000000000000000000020008000000000000000000000000000000000000000000000000000000000000000000400000000000000000002000040000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379163 0x00000000000000000000000000000000000000000000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000008000010000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000080000000000000000000000000000000000000000
|
||||||
|
379164 0x00000000004000000000000000000000000000100000020000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000008000010000000000000000000000000000040000000000001000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000100000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000080000000000000000000000000000000000000000
|
||||||
|
379167 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000004
|
||||||
|
379170 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
379171 0x00000000004000000000000000800000000000000000020000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000008000000000000000000000000000002000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000200000000000000000000004
|
||||||
|
379172 0x00000000000000000010000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000200000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379176 0x00000000004000000010000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000100000000000000000000000000000000000000000200000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000040000000000000000000000000000000002000000000000000000040000000000000000200000000000000000000000000000000000001000000000000000000000000000000000
|
||||||
|
379180 0x00000000000080000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000800000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379182 0x00000000004080000000000002000000000000000800020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000800000000000000000000050000000008000000000000000000000000800000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379210 0x00000000000000040000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000004000000000000000000000400000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379212 0x00000000004000040000000000000000000000000000020000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000200000000000008000000000000000000000000000000000000000004000000000000000000000400000000000000000000002000000000000000000040002000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379214 0x00000001000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379216 0x00000001004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000000000000008000000000000008000000000000000000000000000000000040000000000000000000000000000000000020000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000020002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379217 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000800000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000020000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379219 0x00000000004000000000000000000000000000000000020000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000008000000000000000000000000010000000000000000010000000008800000000000000000000000000000000008000020000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000000000020000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379220 0x00000000000000000000000000200000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000100000000000100002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
379224 0x00000000004000000000000000200000000000000000020000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000008000000000000000040000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000008000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000100000000000100002000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000400000000000000
|
||||||
|
379235 0x00000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000040000000000000000080000000000000000000000000000000000000000800000000000000000000000000000
|
||||||
|
379237 0x00000000004000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000040000000000000000000000000000000000000100000000008000000000000000000000000000000000000010000000008008000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000080000000000000040000000000000000080000000000000000000000000000000000000000800000000000000000000000000000
|
||||||
|
381271 0x00000000000000000000000000000080000080004000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000200000000000004000000000000000000000000002000000000000000000400000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
381276 0x00000000000000000000000000000080000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
381689 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
382200 0x00000020000000000000000008000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
382217 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000400000010000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
382644 0x00000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000200000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000002000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
383284 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
383337 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
383354 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
383361 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
383427 0x00000000000000000000000000000000000004000800000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000800000001000000000008000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000
|
||||||
|
383466 0x00000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
383469 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000001000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
383515 0x00000000000000000000000000000000000004000800000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000800000001000000000008000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000
|
||||||
|
383519 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000010000000800000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000002000000000000000000000000000
|
||||||
|
383630 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
383760 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
383802 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000080000000000400000000000000000
|
||||||
|
383815 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000000000000010000000000000000000000040000000000000000000000000000000020000000100000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
383844 0x00000000000000000000000000000000100000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
383852 0x00000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000002000000000000000000000000000400000000000000004000000000000000080000000000000000000000000000000000000001000000000000000000004000000000000000000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
383859 0x00000000000000000000000000000000000000804000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000002000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
383864 0x00000000000000000000000000000000000000800000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000080000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
383968 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000001000000000000080000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000080000000000000000000000000000000000000040000000000000000
|
||||||
|
383973 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
384127 0x00000000000000000000000000000000000004000800000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000800000001000000000008000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000
|
||||||
|
384138 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
384149 0x00000000000000000000000000000000100000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
384173 0x00000000000000000000000000000000100000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000400000000000000000000080000000000000000000000000000000000008000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000001000000000000000000005000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000800000000000000000000000000000400000000000000000
|
||||||
|
384301 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000040000000000000000000000000000000000000000400000000000000000
|
||||||
|
384422 0x00000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
384506 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
384511 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
384546 0x00000000000000000000000000000000000004000800000000000000000000000000000000000000000001000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000800000001000000000008000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000
|
||||||
|
384771 0x00001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000800000
|
||||||
|
384825 0x00001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000
|
||||||
|
384861 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000100000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
384917 0x00000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
384923 0x00002000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000001000000
|
||||||
|
384965 0x00000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
385067 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000008000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
385073 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000008000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
385356 0x00002000000000000000000000000000000000010000000000000000000000000000000400000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000004000000000000000000000000000000004000000000000000000000000000000000000000000000000000000001000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000001000000
|
||||||
|
386571 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
386620 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
386736 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000040000000000000000000000000000010000000020000000000000000000000000000000000000000000000000000000000000000010
|
||||||
|
386786 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000280000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000040000000000000000000000000000010000000040000000000000000000000000000000000000000000000000000000000000000010
|
||||||
|
386795 0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000040000000000000000000000000000000000040000000000000000000000000000010000000000000000000000000000000000000000000000000000008000000000000000000010
|
||||||
|
386804 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000040000000000400000000000000000000000040000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010
|
||||||
|
386812 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000042000000000000000000000000000000000040000000000000000008000000000010000000000000000000000000000000000000000000000000000000000000000000000000010
|
||||||
|
386818 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000800000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000040000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010
|
||||||
|
386899 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000080000000000000000000000000000040000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010
|
||||||
|
386939 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000002000000000000000000000000000000000000000200000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000010000000020000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
386945 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000020000000000000000000800000000000000000000000000000000000000000200000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
386975 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000100000000000000000020000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
387011 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000010000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
387014 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000000000000040000000000000000000000000000000000000000000000040000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
387016 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000400000000800000000
|
||||||
|
387032 0x04000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000
|
||||||
|
387044 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000020000000000000000000000000000000000000000000080000000000000000000000
|
||||||
|
387045 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000400000000800000000
|
||||||
|
387206 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
387225 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
387241 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
387276 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000008000000000000000004000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000021000000000000000000004000000000000000000000400000000000000000000000000000000080000000000000000000000000000000000000040000000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
387284 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000040000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
387365 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000
|
||||||
|
387615 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
387627 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000800000000000000000400000000000000000
|
||||||
|
387641 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800008000000000000000000000001000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
387648 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
387654 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
387658 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000800008000000000000000000000001000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
387683 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
387688 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000800008000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
387690 0x00000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000800008000000000000000000000001000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
387761 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
388108 0x00000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
388111 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000800000000
|
||||||
|
388150 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000800000000
|
||||||
|
388246 0x00000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000001000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000
|
||||||
|
388285 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
388296 0x00000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000001000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000
|
||||||
|
388516 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
388860 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
388893 0x00000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000008000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000001000000000000000000000000000008000000000000000020000000000000000000010000000000001000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
388894 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
388907 0x00000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000104000000000004000000000000001000000000000000000000000000001000000000000000000004080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000004000000000000000400000000000000000
|
||||||
|
388909 0x00000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000400000000000000000
|
||||||
|
388912 0x00000000000000000000000000000000000000004000000000020000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000004000000000000000040000000000000000
|
||||||
|
388918 0x00000000000000000000000000000000000000000000000000020000002000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000040000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000004000000000000000040000000000000000
|
||||||
|
388923 0x00000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000008000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000001000000000000000000000080000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000000000000000001000000000000000000000000000000000000000000000004000000000000000400000000000000000
|
||||||
|
388940 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000020000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
388971 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000004000000000000000000000000000000000000000800000000000000000000000000000000000
|
||||||
|
388990 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000
|
||||||
|
389012 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000
|
||||||
|
389158 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000
|
||||||
|
389206 0x00000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000400000000000000000
|
||||||
|
389238 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
389277 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000100000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000400000000000000000
|
||||||
|
389292 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000800000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
389301 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
389309 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
389324 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000008000000000000000000000000004000000000000000000000000004000000000000000000000000000000000000000000000000000000001000000000000800000024000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000440000000000000000
|
||||||
|
389328 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
389343 0x00000000000000000000000000000000000000004000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000040000000000000000
|
||||||
|
390001 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000001000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
390004 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000200000000000000000000000000000000000000020000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
390024 0x00000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
390042 0x00000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
390236 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
390306 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000001000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
390867 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
391685 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000010000000800000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000002000000000000000000000000000
|
||||||
|
391690 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000010000000800000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000002000000000000000000000000000
|
||||||
|
391691 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000010000000800000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000002000000000000000000000000000
|
||||||
|
391697 0x00000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000040000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000
|
||||||
|
391713 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000
|
||||||
|
391849 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000100000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000400000000000000000
|
||||||
|
392002 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000
|
||||||
|
392097 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000020000000000000000000000000000000000000000000000000000000008000000000000000000080000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
392104 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000010000000000000000000000000000000000000000000000000000000020000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
392110 0x00000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000
|
||||||
|
392294 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000001000000000000000000000000000000000000020000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000004000000000000000000000000000000000000000000000000000000000
|
||||||
|
392697 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000010000000000000000000000000000400000000000000000
|
||||||
|
392960 0x00000000000000200000400000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
392970 0x00000000000000200000400000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
392990 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
393302 0x00000010000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
393370 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
393752 0x00000000000000000000000000000000001000000000000000000000000000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
394354 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000800000024000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
394389 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
394390 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
394391 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
394393 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
394394 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
394395 0x00000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000002000000000000000000000000000000100000000000000000100000000000000000000000000000000000000000000000000000000000002000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
394426 0x00000000000000200000400000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000200000000000000000000000000000000000000000000000000000000000000000000000008000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
394800 0x00000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000100000010000000000000000000000000000000000000000000000000000000000020000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000400000000000000000000000000
|
||||||
|
395595 0x00000000000000000000000000000000000000000000000000000000000100000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000800000000000000000000000000000000000000000000000000000000000000000008000000000000000
|
||||||
|
395969 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
396348 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000010000000000000000000000000000400000000000000000
|
||||||
|
397108 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
397588 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
397591 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
398412 0x00000000000000000000000000000000000000000000000000000000001000000000001000000000000000000000000000008000000000000000000000000000000000000000000000000000000000802000002000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000000000000000080000000000000000000800008000000000000000
|
||||||
|
398456 0x00000020000000080000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000
|
||||||
|
398477 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
398679 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040100000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
|
||||||
|
398968 0x00000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020200000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000
|
||||||
|
398972 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000400000000000000000
|
||||||
|
399058 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000200000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000
|
||||||
|
399804 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000010000000000000000000000000000400000000000000000
|
||||||
|
399849 0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000
|
197
ethcore/src/chainfilter/chainfilter.rs
Normal file
197
ethcore/src/chainfilter/chainfilter.rs
Normal file
@ -0,0 +1,197 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Multilevel blockchain bloom filter.
|
||||||
|
//!
|
||||||
|
//! ```not_run
|
||||||
|
//! extern crate ethcore_util as util;
|
||||||
|
//! extern crate ethcore;
|
||||||
|
//! use std::str::FromStr;
|
||||||
|
//! use util::sha3::*;
|
||||||
|
//! use util::hash::*;
|
||||||
|
//! use ethcore::chainfilter::*;
|
||||||
|
//!
|
||||||
|
//! fn main() {
|
||||||
|
//! let (index_size, bloom_levels) = (16, 3);
|
||||||
|
//! let mut cache = MemoryCache::new();
|
||||||
|
//!
|
||||||
|
//! let address = Address::from_str("ef2d6d194084c2de36e0dabfce45d046b37d1106").unwrap();
|
||||||
|
//!
|
||||||
|
//! // borrow cache for reading inside the scope
|
||||||
|
//! let modified_blooms = {
|
||||||
|
//! let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
//! let block_number = 39;
|
||||||
|
//! let mut bloom = H2048::new();
|
||||||
|
//! bloom.shift_bloomed(&address.sha3());
|
||||||
|
//! filter.add_bloom(&bloom, block_number)
|
||||||
|
//! };
|
||||||
|
//!
|
||||||
|
//! // number of updated blooms is equal number of levels
|
||||||
|
//! assert_eq!(modified_blooms.len(), bloom_levels as usize);
|
||||||
|
//!
|
||||||
|
//! // lets inserts modified blooms into the cache
|
||||||
|
//! cache.insert_blooms(modified_blooms);
|
||||||
|
//!
|
||||||
|
//! // borrow cache for another reading operations
|
||||||
|
//! {
|
||||||
|
//! let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
//! let blocks = filter.blocks_with_address(&address, 10, 40);
|
||||||
|
//! assert_eq!(blocks.len(), 1);
|
||||||
|
//! assert_eq!(blocks[0], 39);
|
||||||
|
//! }
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
//!
|
||||||
|
use std::collections::{HashMap};
|
||||||
|
use util::hash::*;
|
||||||
|
use chainfilter::{BloomIndex, FilterDataSource};
|
||||||
|
use chainfilter::indexer::Indexer;
|
||||||
|
|
||||||
|
/// Should be used for search operations on blockchain.
|
||||||
|
pub struct ChainFilter<'a, D>
|
||||||
|
where D: FilterDataSource + 'a
|
||||||
|
{
|
||||||
|
data_source: &'a D,
|
||||||
|
indexer: Indexer,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, D> ChainFilter<'a, D> where D: FilterDataSource
|
||||||
|
{
|
||||||
|
/// Creates new filter instance.
|
||||||
|
///
|
||||||
|
/// Borrows `FilterDataSource` for reading.
|
||||||
|
pub fn new(data_source: &'a D, index_size: usize, levels: u8) -> Self {
|
||||||
|
ChainFilter {
|
||||||
|
data_source: data_source,
|
||||||
|
indexer: Indexer::new(index_size, levels)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// internal function which does bloom search recursively
|
||||||
|
fn blocks(&self, bloom: &H2048, from_block: usize, to_block: usize, level: u8, offset: usize) -> Option<Vec<usize>> {
|
||||||
|
let index = self.indexer.bloom_index(offset, level);
|
||||||
|
|
||||||
|
match self.data_source.bloom_at_index(&index) {
|
||||||
|
None => return None,
|
||||||
|
Some(level_bloom) => match level {
|
||||||
|
// if we are on the lowest level
|
||||||
|
0 => return match offset <= to_block {
|
||||||
|
// take the value if its smaller than to_block
|
||||||
|
true if level_bloom.contains(bloom) => Some(vec![offset]),
|
||||||
|
// return None if it is is equal to to_block
|
||||||
|
_ => None
|
||||||
|
},
|
||||||
|
// return None if current level doesnt contain given bloom
|
||||||
|
_ if !level_bloom.contains(bloom) => return None,
|
||||||
|
// continue processing && go down
|
||||||
|
_ => ()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let level_size = self.indexer.level_size(level - 1);
|
||||||
|
let from_index = self.indexer.bloom_index(from_block, level - 1);
|
||||||
|
let to_index = self.indexer.bloom_index(to_block, level - 1);
|
||||||
|
let res: Vec<usize> = self.indexer.lower_level_bloom_indexes(&index).into_iter()
|
||||||
|
// chose only blooms in range
|
||||||
|
.filter(|li| li.index >= from_index.index && li.index <= to_index.index)
|
||||||
|
// map them to offsets
|
||||||
|
.map(|li| li.index * level_size)
|
||||||
|
// get all blocks that may contain our bloom
|
||||||
|
// filter existing ones
|
||||||
|
.filter_map(|off| self.blocks(bloom, from_block, to_block, level - 1, off))
|
||||||
|
// flatten nested structures
|
||||||
|
.flat_map(|v| v)
|
||||||
|
.collect();
|
||||||
|
Some(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Adds new bloom to all filter levels
|
||||||
|
pub fn add_bloom(&self, bloom: &H2048, block_number: usize) -> HashMap<BloomIndex, H2048> {
|
||||||
|
let mut result: HashMap<BloomIndex, H2048> = HashMap::new();
|
||||||
|
|
||||||
|
for level in 0..self.indexer.levels() {
|
||||||
|
let bloom_index = self.indexer.bloom_index(block_number, level);
|
||||||
|
let new_bloom = match self.data_source.bloom_at_index(&bloom_index) {
|
||||||
|
Some(old_bloom) => old_bloom | bloom.clone(),
|
||||||
|
None => bloom.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
result.insert(bloom_index, new_bloom);
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Resets blooms at level 0 and forces rebuild on higher levels.
|
||||||
|
pub fn reset_chain_head(&self, blooms: &[H2048], block_number: usize, old_highest_block: usize) -> HashMap<BloomIndex, H2048> {
|
||||||
|
let mut result: HashMap<BloomIndex, H2048> = HashMap::new();
|
||||||
|
|
||||||
|
// insert all new blooms at level 0
|
||||||
|
for (i, bloom) in blooms.iter().enumerate() {
|
||||||
|
result.insert(self.indexer.bloom_index(block_number + i, 0), bloom.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
// reset the rest of blooms
|
||||||
|
for reset_number in block_number + blooms.len()..(old_highest_block + 1) {
|
||||||
|
result.insert(self.indexer.bloom_index(reset_number, 0), H2048::new());
|
||||||
|
}
|
||||||
|
|
||||||
|
for level in 1..self.indexer.levels() {
|
||||||
|
for i in 0..blooms.len() {
|
||||||
|
|
||||||
|
let index = self.indexer.bloom_index(block_number + i, level);
|
||||||
|
let new_bloom = {
|
||||||
|
// use new blooms before db blooms where necessary
|
||||||
|
let bloom_at = | index | { result.get(&index).cloned().or_else(|| self.data_source.bloom_at_index(&index)) };
|
||||||
|
|
||||||
|
self.indexer.lower_level_bloom_indexes(&index)
|
||||||
|
.into_iter()
|
||||||
|
// get blooms
|
||||||
|
// filter existing ones
|
||||||
|
.filter_map(bloom_at)
|
||||||
|
// BitOr all of them
|
||||||
|
.fold(H2048::new(), |acc, bloom| acc | bloom)
|
||||||
|
};
|
||||||
|
|
||||||
|
result.insert(index, new_bloom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns numbers of blocks that may log bloom.
|
||||||
|
pub fn blocks_with_bloom(&self, bloom: &H2048, from_block: usize, to_block: usize) -> Vec<usize> {
|
||||||
|
let mut result = vec![];
|
||||||
|
// lets start from highest level
|
||||||
|
let max_level = self.indexer.max_level();
|
||||||
|
let level_size = self.indexer.level_size(max_level);
|
||||||
|
let from_index = self.indexer.bloom_index(from_block, max_level);
|
||||||
|
let to_index = self.indexer.bloom_index(to_block, max_level);
|
||||||
|
|
||||||
|
for index in from_index.index..to_index.index + 1 {
|
||||||
|
// offset will be used to calculate where we are right now
|
||||||
|
let offset = level_size * index;
|
||||||
|
|
||||||
|
// go doooown!
|
||||||
|
if let Some(blocks) = self.blocks(bloom, from_block, to_block, max_level, offset) {
|
||||||
|
result.extend(blocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
154
ethcore/src/chainfilter/indexer.rs
Normal file
154
ethcore/src/chainfilter/indexer.rs
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Simplifies working with bloom indexes.
|
||||||
|
|
||||||
|
use chainfilter::BloomIndex;
|
||||||
|
|
||||||
|
/// Simplifies working with bloom indexes.
|
||||||
|
pub struct Indexer {
|
||||||
|
index_size: usize,
|
||||||
|
level_sizes: Vec<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Indexer {
|
||||||
|
/// Creates new indexer.
|
||||||
|
pub fn new(index_size: usize, levels: u8) -> Self {
|
||||||
|
if levels == 0 {
|
||||||
|
panic!("Indexer requires at least 1 level.");
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut level_sizes = vec![1];
|
||||||
|
level_sizes.extend_from_slice(&(1..).into_iter()
|
||||||
|
.scan(1, |acc, _| {
|
||||||
|
*acc = *acc * index_size;
|
||||||
|
Some(*acc)
|
||||||
|
})
|
||||||
|
.take(levels as usize - 1)
|
||||||
|
.collect::<Vec<usize>>());
|
||||||
|
|
||||||
|
Indexer {
|
||||||
|
index_size: index_size,
|
||||||
|
level_sizes: level_sizes,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// unsafely get level size.
|
||||||
|
pub fn level_size(&self, level: u8) -> usize {
|
||||||
|
self.level_sizes[level as usize]
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts block number and level to `BloomIndex`.
|
||||||
|
pub fn bloom_index(&self, block_number: usize, level: u8) -> BloomIndex {
|
||||||
|
BloomIndex {
|
||||||
|
level: level,
|
||||||
|
index: block_number / self.level_size(level),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return bloom which are dependencies for given index.
|
||||||
|
///
|
||||||
|
/// Bloom indexes are ordered from lowest to highest.
|
||||||
|
pub fn lower_level_bloom_indexes(&self, index: &BloomIndex) -> Vec<BloomIndex> {
|
||||||
|
// this is the lowest level
|
||||||
|
if index.level == 0 {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_level = index.level - 1;
|
||||||
|
let offset = self.index_size * index.index;
|
||||||
|
|
||||||
|
(0..self.index_size).map(|i| BloomIndex::new(new_level, offset + i)).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return number of levels.
|
||||||
|
pub fn levels(&self) -> u8 {
|
||||||
|
self.level_sizes.len() as u8
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns max indexer level.
|
||||||
|
pub fn max_level(&self) -> u8 {
|
||||||
|
self.level_sizes.len() as u8 - 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use chainfilter::BloomIndex;
|
||||||
|
use chainfilter::indexer::Indexer;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_level_size() {
|
||||||
|
let indexer = Indexer::new(16, 3);
|
||||||
|
assert_eq!(indexer.level_size(0), 1);
|
||||||
|
assert_eq!(indexer.level_size(1), 16);
|
||||||
|
assert_eq!(indexer.level_size(2), 256);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bloom_index() {
|
||||||
|
let indexer = Indexer::new(16, 3);
|
||||||
|
|
||||||
|
let bi0 = indexer.bloom_index(0, 0);
|
||||||
|
assert_eq!(bi0.level, 0);
|
||||||
|
assert_eq!(bi0.index, 0);
|
||||||
|
|
||||||
|
let bi1 = indexer.bloom_index(1, 0);
|
||||||
|
assert_eq!(bi1.level, 0);
|
||||||
|
assert_eq!(bi1.index, 1);
|
||||||
|
|
||||||
|
let bi2 = indexer.bloom_index(2, 0);
|
||||||
|
assert_eq!(bi2.level, 0);
|
||||||
|
assert_eq!(bi2.index, 2);
|
||||||
|
|
||||||
|
let bi3 = indexer.bloom_index(3, 1);
|
||||||
|
assert_eq!(bi3.level, 1);
|
||||||
|
assert_eq!(bi3.index, 0);
|
||||||
|
|
||||||
|
let bi4 = indexer.bloom_index(15, 1);
|
||||||
|
assert_eq!(bi4.level, 1);
|
||||||
|
assert_eq!(bi4.index, 0);
|
||||||
|
|
||||||
|
let bi5 = indexer.bloom_index(16, 1);
|
||||||
|
assert_eq!(bi5.level, 1);
|
||||||
|
assert_eq!(bi5.index, 1);
|
||||||
|
|
||||||
|
let bi6 = indexer.bloom_index(255, 2);
|
||||||
|
assert_eq!(bi6.level, 2);
|
||||||
|
assert_eq!(bi6.index, 0);
|
||||||
|
|
||||||
|
let bi7 = indexer.bloom_index(256, 2);
|
||||||
|
assert_eq!(bi7.level, 2);
|
||||||
|
assert_eq!(bi7.index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_lower_level_bloom_indexes() {
|
||||||
|
let indexer = Indexer::new(16, 3);
|
||||||
|
|
||||||
|
let bi = indexer.bloom_index(256, 2);
|
||||||
|
assert_eq!(bi.level, 2);
|
||||||
|
assert_eq!(bi.index, 1);
|
||||||
|
|
||||||
|
let mut ebis = vec![];
|
||||||
|
for i in 16..32 {
|
||||||
|
ebis.push(BloomIndex::new(1, i));
|
||||||
|
}
|
||||||
|
|
||||||
|
let bis = indexer.lower_level_bloom_indexes(&bi);
|
||||||
|
assert_eq!(ebis, bis);
|
||||||
|
}
|
||||||
|
}
|
1013
ethcore/src/chainfilter/logs.txt
Normal file
1013
ethcore/src/chainfilter/logs.txt
Normal file
File diff suppressed because it is too large
Load Diff
35
ethcore/src/chainfilter/mod.rs
Normal file
35
ethcore/src/chainfilter/mod.rs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Multilevel blockchain bloom filter.
|
||||||
|
|
||||||
|
mod bloomindex;
|
||||||
|
mod chainfilter;
|
||||||
|
mod indexer;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests;
|
||||||
|
|
||||||
|
pub use self::bloomindex::BloomIndex;
|
||||||
|
pub use self::chainfilter::ChainFilter;
|
||||||
|
use util::hash::H2048;
|
||||||
|
|
||||||
|
/// Types implementing this trait provide read access for bloom filters database.
|
||||||
|
pub trait FilterDataSource {
|
||||||
|
/// returns reference to log at given position if it exists
|
||||||
|
fn bloom_at_index(&self, index: &BloomIndex) -> Option<H2048>;
|
||||||
|
}
|
||||||
|
|
283
ethcore/src/chainfilter/tests.rs
Normal file
283
ethcore/src/chainfilter/tests.rs
Normal file
@ -0,0 +1,283 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use std::io::{BufRead, BufReader, Read};
|
||||||
|
use std::str::FromStr;
|
||||||
|
use util::hash::*;
|
||||||
|
use util::sha3::*;
|
||||||
|
use chainfilter::{BloomIndex, FilterDataSource, ChainFilter};
|
||||||
|
|
||||||
|
/// In memory cache for blooms.
|
||||||
|
///
|
||||||
|
/// Stores all blooms in HashMap, which indexes them by `BloomIndex`.
|
||||||
|
pub struct MemoryCache {
|
||||||
|
blooms: HashMap<BloomIndex, H2048>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for MemoryCache {
|
||||||
|
fn default() -> Self {
|
||||||
|
MemoryCache::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MemoryCache {
|
||||||
|
/// Default constructor for MemoryCache
|
||||||
|
pub fn new() -> Self {
|
||||||
|
MemoryCache { blooms: HashMap::new() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// inserts all blooms into cache
|
||||||
|
///
|
||||||
|
/// if bloom at given index already exists, overwrites it
|
||||||
|
pub fn insert_blooms(&mut self, blooms: HashMap<BloomIndex, H2048>) {
|
||||||
|
self.blooms.extend(blooms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FilterDataSource for MemoryCache {
|
||||||
|
fn bloom_at_index(&self, index: &BloomIndex) -> Option<H2048> {
|
||||||
|
self.blooms.get(index).cloned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_bloom<T>(hashable: &T) -> H2048 where T: Hashable {
|
||||||
|
let mut bloom = H2048::new();
|
||||||
|
bloom.shift_bloomed(&hashable.sha3());
|
||||||
|
bloom
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_topic_basic_search() {
|
||||||
|
let index_size = 16;
|
||||||
|
let bloom_levels = 3;
|
||||||
|
|
||||||
|
let mut cache = MemoryCache::new();
|
||||||
|
let topic = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dba").unwrap();
|
||||||
|
|
||||||
|
let modified_blooms = {
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let block_number = 23;
|
||||||
|
filter.add_bloom(&to_bloom(&topic), block_number)
|
||||||
|
};
|
||||||
|
|
||||||
|
// number of modified blooms should always be equal number of levels
|
||||||
|
assert_eq!(modified_blooms.len(), bloom_levels as usize);
|
||||||
|
cache.insert_blooms(modified_blooms);
|
||||||
|
|
||||||
|
{
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let blocks = filter.blocks_with_bloom(&to_bloom(&topic), 0, 100);
|
||||||
|
assert_eq!(blocks.len(), 1);
|
||||||
|
assert_eq!(blocks[0], 23);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let blocks = filter.blocks_with_bloom(&to_bloom(&topic), 0, 22);
|
||||||
|
assert_eq!(blocks.len(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let blocks = filter.blocks_with_bloom(&to_bloom(&topic), 23, 23);
|
||||||
|
assert_eq!(blocks.len(), 1);
|
||||||
|
assert_eq!(blocks[0], 23);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let blocks = filter.blocks_with_bloom(&to_bloom(&topic), 24, 100);
|
||||||
|
assert_eq!(blocks.len(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_reset_chain_head_simple() {
|
||||||
|
let index_size = 16;
|
||||||
|
let bloom_levels = 3;
|
||||||
|
|
||||||
|
let mut cache = MemoryCache::new();
|
||||||
|
let topic_0 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dba").unwrap();
|
||||||
|
let topic_1 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbb").unwrap();
|
||||||
|
let topic_2 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbc").unwrap();
|
||||||
|
let topic_3 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbd").unwrap();
|
||||||
|
let topic_4 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbe").unwrap();
|
||||||
|
let topic_5 = H256::from_str("8d936b1bd3fc635710969ccfba471fb17d598d9d1971b538dd712e1e4b4f4dbf").unwrap();
|
||||||
|
|
||||||
|
let modified_blooms_0 = {
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let block_number = 14;
|
||||||
|
filter.add_bloom(&to_bloom(&topic_0), block_number)
|
||||||
|
};
|
||||||
|
|
||||||
|
cache.insert_blooms(modified_blooms_0);
|
||||||
|
|
||||||
|
let modified_blooms_1 = {
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let block_number = 15;
|
||||||
|
filter.add_bloom(&to_bloom(&topic_1), block_number)
|
||||||
|
};
|
||||||
|
|
||||||
|
cache.insert_blooms(modified_blooms_1);
|
||||||
|
|
||||||
|
let modified_blooms_2 = {
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let block_number = 16;
|
||||||
|
filter.add_bloom(&to_bloom(&topic_2), block_number)
|
||||||
|
};
|
||||||
|
|
||||||
|
cache.insert_blooms(modified_blooms_2);
|
||||||
|
|
||||||
|
let modified_blooms_3 = {
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let block_number = 17;
|
||||||
|
filter.add_bloom(&to_bloom(&topic_3), block_number)
|
||||||
|
};
|
||||||
|
|
||||||
|
cache.insert_blooms(modified_blooms_3);
|
||||||
|
|
||||||
|
|
||||||
|
let reset_modified_blooms = {
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
filter.reset_chain_head(&[to_bloom(&topic_4), to_bloom(&topic_5)], 15, 17)
|
||||||
|
};
|
||||||
|
|
||||||
|
cache.insert_blooms(reset_modified_blooms);
|
||||||
|
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_0), 0, 100), vec![14]);
|
||||||
|
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_1), 0, 100), vec![]);
|
||||||
|
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_2), 0, 100), vec![]);
|
||||||
|
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_3), 0, 100), vec![]);
|
||||||
|
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_4), 0, 100), vec![15]);
|
||||||
|
assert_eq!(filter.blocks_with_bloom(&to_bloom(&topic_5), 0, 100), vec![16]);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn for_each_bloom<F>(bytes: &[u8], mut f: F) where F: FnMut(usize, &H2048) {
|
||||||
|
let mut reader = BufReader::new(bytes);
|
||||||
|
let mut line = String::new();
|
||||||
|
while reader.read_line(&mut line).unwrap() > 0 {
|
||||||
|
{
|
||||||
|
let mut number_bytes = vec![];
|
||||||
|
let mut bloom_bytes = [0; 512];
|
||||||
|
|
||||||
|
let mut line_reader = BufReader::new(line.as_ref() as &[u8]);
|
||||||
|
line_reader.read_until(b' ', &mut number_bytes).unwrap();
|
||||||
|
line_reader.consume(2);
|
||||||
|
line_reader.read_exact(&mut bloom_bytes).unwrap();
|
||||||
|
|
||||||
|
let number = String::from_utf8(number_bytes).map(|s| s[..s.len() -1].to_owned()).unwrap().parse::<usize>().unwrap();
|
||||||
|
let bloom = H2048::from_str(&String::from_utf8(bloom_bytes.to_vec()).unwrap()).unwrap();
|
||||||
|
f(number, &bloom);
|
||||||
|
}
|
||||||
|
line.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn for_each_log<F>(bytes: &[u8], mut f: F) where F: FnMut(usize, &Address, &[H256]) {
|
||||||
|
let mut reader = BufReader::new(bytes);
|
||||||
|
let mut line = String::new();
|
||||||
|
while reader.read_line(&mut line).unwrap() > 0 {
|
||||||
|
{
|
||||||
|
let mut number_bytes = vec![];
|
||||||
|
let mut address_bytes = [0;42];
|
||||||
|
let mut topic = [0;66];
|
||||||
|
let mut topics_bytes = vec![];
|
||||||
|
|
||||||
|
let mut line_reader = BufReader::new(line.as_ref() as &[u8]);
|
||||||
|
line_reader.read_until(b' ', &mut number_bytes).unwrap();
|
||||||
|
line_reader.read_exact(&mut address_bytes).unwrap();
|
||||||
|
line_reader.consume(1);
|
||||||
|
while let Ok(_) = line_reader.read_exact(&mut topic) {
|
||||||
|
line_reader.consume(1);
|
||||||
|
topics_bytes.push(topic.to_vec());
|
||||||
|
}
|
||||||
|
|
||||||
|
let number = String::from_utf8(number_bytes).map(|s| s[..s.len() -1].to_owned()).unwrap().parse::<usize>().unwrap();
|
||||||
|
let address = Address::from_str(&String::from_utf8(address_bytes.to_vec()).map(|a| a[2..].to_owned()).unwrap()).unwrap();
|
||||||
|
let topics: Vec<H256> = topics_bytes
|
||||||
|
.into_iter()
|
||||||
|
.map(|t| H256::from_str(&String::from_utf8(t).map(|t| t[2..].to_owned()).unwrap()).unwrap())
|
||||||
|
.collect();
|
||||||
|
f(number, &address, &topics);
|
||||||
|
}
|
||||||
|
line.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// tests chain filter on real data between blocks 300_000 and 400_000
|
||||||
|
#[test]
|
||||||
|
fn test_chainfilter_real_data_short_searches() {
|
||||||
|
let index_size = 16;
|
||||||
|
let bloom_levels = 3;
|
||||||
|
|
||||||
|
let mut cache = MemoryCache::new();
|
||||||
|
|
||||||
|
for_each_bloom(include_bytes!("blooms.txt"), | block_number, bloom | {
|
||||||
|
let modified_blooms = {
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
filter.add_bloom(bloom, block_number)
|
||||||
|
};
|
||||||
|
|
||||||
|
// number of modified blooms should always be equal number of levels
|
||||||
|
assert_eq!(modified_blooms.len(), bloom_levels as usize);
|
||||||
|
cache.insert_blooms(modified_blooms);
|
||||||
|
});
|
||||||
|
|
||||||
|
for_each_log(include_bytes!("logs.txt"), | block_number, address, topics | {
|
||||||
|
println!("block_number: {:?}", block_number);
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let blocks = filter.blocks_with_bloom(&to_bloom(address), block_number, block_number);
|
||||||
|
assert_eq!(blocks.len(), 1);
|
||||||
|
for (i, topic) in topics.iter().enumerate() {
|
||||||
|
println!("topic: {:?}", i);
|
||||||
|
let blocks = filter.blocks_with_bloom(&to_bloom(topic), block_number, block_number);
|
||||||
|
assert_eq!(blocks.len(), 1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// tests chain filter on real data between blocks 300_000 and 400_000
|
||||||
|
#[test]
|
||||||
|
fn test_chainfilter_real_data_single_search() {
|
||||||
|
let index_size = 16;
|
||||||
|
let bloom_levels = 3;
|
||||||
|
|
||||||
|
let mut cache = MemoryCache::new();
|
||||||
|
|
||||||
|
for_each_bloom(include_bytes!("blooms.txt"), | block_number, bloom | {
|
||||||
|
let modified_blooms = {
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
filter.add_bloom(bloom, block_number)
|
||||||
|
};
|
||||||
|
|
||||||
|
// number of modified blooms should always be equal number of levels
|
||||||
|
assert_eq!(modified_blooms.len(), bloom_levels as usize);
|
||||||
|
cache.insert_blooms(modified_blooms);
|
||||||
|
});
|
||||||
|
|
||||||
|
let address = Address::from_str("c4395759e26469baa0e6421bdc1d0232c6f4b6c3").unwrap();
|
||||||
|
let filter = ChainFilter::new(&cache, index_size, bloom_levels);
|
||||||
|
let blocks = filter.blocks_with_bloom(&to_bloom(&address), 300_000, 400_000);
|
||||||
|
// bloom may return more blocks, but our log density is low, so it should be fine
|
||||||
|
assert_eq!(blocks.len(), 3);
|
||||||
|
assert_eq!(blocks[0], 392697);
|
||||||
|
assert_eq!(blocks[1], 396348);
|
||||||
|
assert_eq!(blocks[2], 399804);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,464 +0,0 @@
|
|||||||
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
|
||||||
// This file is part of Parity.
|
|
||||||
|
|
||||||
// Parity is free software: you can redistribute it and/or modify
|
|
||||||
// it under the terms of the GNU General Public License as published by
|
|
||||||
// the Free Software Foundation, either version 3 of the License, or
|
|
||||||
// (at your option) any later version.
|
|
||||||
|
|
||||||
// Parity is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
// GNU General Public License for more details.
|
|
||||||
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
//! Blockchain database client.
|
|
||||||
|
|
||||||
use util::*;
|
|
||||||
use util::panics::*;
|
|
||||||
use rocksdb::{Options, DB, DBCompactionStyle};
|
|
||||||
use blockchain::{BlockChain, BlockProvider, CacheSize};
|
|
||||||
use views::BlockView;
|
|
||||||
use error::*;
|
|
||||||
use header::BlockNumber;
|
|
||||||
use state::State;
|
|
||||||
use spec::Spec;
|
|
||||||
use engine::Engine;
|
|
||||||
use views::HeaderView;
|
|
||||||
use block_queue::{BlockQueue, BlockQueueInfo};
|
|
||||||
use service::{NetSyncMessage, SyncMessage};
|
|
||||||
use env_info::LastHashes;
|
|
||||||
use verification::*;
|
|
||||||
use block::*;
|
|
||||||
use transaction::LocalizedTransaction;
|
|
||||||
use extras::TransactionAddress;
|
|
||||||
pub use blockchain::TreeRoute;
|
|
||||||
|
|
||||||
/// Uniquely identifies block.
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub enum BlockId {
|
|
||||||
/// Block's sha3.
|
|
||||||
/// Querying by hash is always faster.
|
|
||||||
Hash(H256),
|
|
||||||
/// Block number within canon blockchain.
|
|
||||||
Number(BlockNumber),
|
|
||||||
/// Earliest block (genesis).
|
|
||||||
Earliest,
|
|
||||||
/// Latest mined block.
|
|
||||||
Latest
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Uniquely identifies transaction.
|
|
||||||
#[derive(Debug, PartialEq, Clone)]
|
|
||||||
pub enum TransactionId {
|
|
||||||
/// Transaction's sha3.
|
|
||||||
Hash(H256),
|
|
||||||
/// Block id and transaction index within this block.
|
|
||||||
/// Querying by block position is always faster.
|
|
||||||
Location(BlockId, usize)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// General block status
|
|
||||||
#[derive(Debug, Eq, PartialEq)]
|
|
||||||
pub enum BlockStatus {
|
|
||||||
/// Part of the blockchain.
|
|
||||||
InChain,
|
|
||||||
/// Queued for import.
|
|
||||||
Queued,
|
|
||||||
/// Known as bad.
|
|
||||||
Bad,
|
|
||||||
/// Unknown.
|
|
||||||
Unknown,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Information about the blockchain gthered together.
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct BlockChainInfo {
|
|
||||||
/// Blockchain difficulty.
|
|
||||||
pub total_difficulty: U256,
|
|
||||||
/// Block queue difficulty.
|
|
||||||
pub pending_total_difficulty: U256,
|
|
||||||
/// Genesis block hash.
|
|
||||||
pub genesis_hash: H256,
|
|
||||||
/// Best blockchain block hash.
|
|
||||||
pub best_block_hash: H256,
|
|
||||||
/// Best blockchain block number.
|
|
||||||
pub best_block_number: BlockNumber
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for BlockChainInfo {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "#{}.{}", self.best_block_number, self.best_block_hash)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
|
||||||
pub trait BlockChainClient : Sync + Send {
|
|
||||||
/// Get raw block header data by block id.
|
|
||||||
fn block_header(&self, id: BlockId) -> Option<Bytes>;
|
|
||||||
|
|
||||||
/// Get raw block body data by block id.
|
|
||||||
/// Block body is an RLP list of two items: uncles and transactions.
|
|
||||||
fn block_body(&self, id: BlockId) -> Option<Bytes>;
|
|
||||||
|
|
||||||
/// Get raw block data by block header hash.
|
|
||||||
fn block(&self, id: BlockId) -> Option<Bytes>;
|
|
||||||
|
|
||||||
/// Get block status by block header hash.
|
|
||||||
fn block_status(&self, id: BlockId) -> BlockStatus;
|
|
||||||
|
|
||||||
/// Get block total difficulty.
|
|
||||||
fn block_total_difficulty(&self, id: BlockId) -> Option<U256>;
|
|
||||||
|
|
||||||
/// Get address code.
|
|
||||||
fn code(&self, address: &Address) -> Option<Bytes>;
|
|
||||||
|
|
||||||
/// Get transaction with given hash.
|
|
||||||
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction>;
|
|
||||||
|
|
||||||
/// Get a tree route between `from` and `to`.
|
|
||||||
/// See `BlockChain::tree_route`.
|
|
||||||
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute>;
|
|
||||||
|
|
||||||
/// Get latest state node
|
|
||||||
fn state_data(&self, hash: &H256) -> Option<Bytes>;
|
|
||||||
|
|
||||||
/// Get raw block receipts data by block header hash.
|
|
||||||
fn block_receipts(&self, hash: &H256) -> Option<Bytes>;
|
|
||||||
|
|
||||||
/// Import a block into the blockchain.
|
|
||||||
fn import_block(&self, bytes: Bytes) -> ImportResult;
|
|
||||||
|
|
||||||
/// Get block queue information.
|
|
||||||
fn queue_info(&self) -> BlockQueueInfo;
|
|
||||||
|
|
||||||
/// Clear block queue and abort all import activity.
|
|
||||||
fn clear_queue(&self);
|
|
||||||
|
|
||||||
/// Get blockchain information.
|
|
||||||
fn chain_info(&self) -> BlockChainInfo;
|
|
||||||
|
|
||||||
/// Get the best block header.
|
|
||||||
fn best_block_header(&self) -> Bytes {
|
|
||||||
self.block_header(BlockId::Hash(self.chain_info().best_block_hash)).unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Clone, Debug, Eq, PartialEq)]
|
|
||||||
/// Report on the status of a client.
|
|
||||||
pub struct ClientReport {
|
|
||||||
/// How many blocks have been imported so far.
|
|
||||||
pub blocks_imported: usize,
|
|
||||||
/// How many transactions have been applied so far.
|
|
||||||
pub transactions_applied: usize,
|
|
||||||
/// How much gas has been processed so far.
|
|
||||||
pub gas_processed: U256,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ClientReport {
|
|
||||||
/// Alter internal reporting to reflect the additional `block` has been processed.
|
|
||||||
pub fn accrue_block(&mut self, block: &PreVerifiedBlock) {
|
|
||||||
self.blocks_imported += 1;
|
|
||||||
self.transactions_applied += block.transactions.len();
|
|
||||||
self.gas_processed += block.header.gas_used;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Blockchain database client backed by a persistent database. Owns and manages a blockchain and a block queue.
|
|
||||||
/// Call `import_block()` to import a block asynchronously; `flush_queue()` flushes the queue.
|
|
||||||
pub struct Client {
|
|
||||||
chain: Arc<RwLock<BlockChain>>,
|
|
||||||
engine: Arc<Box<Engine>>,
|
|
||||||
state_db: Mutex<JournalDB>,
|
|
||||||
block_queue: RwLock<BlockQueue>,
|
|
||||||
report: RwLock<ClientReport>,
|
|
||||||
import_lock: Mutex<()>,
|
|
||||||
panic_handler: Arc<PanicHandler>,
|
|
||||||
}
|
|
||||||
|
|
||||||
const HISTORY: u64 = 1000;
|
|
||||||
const CLIENT_DB_VER_STR: &'static str = "2.1";
|
|
||||||
|
|
||||||
impl Client {
|
|
||||||
/// Create a new client with given spec and DB path.
|
|
||||||
pub fn new(spec: Spec, path: &Path, message_channel: IoChannel<NetSyncMessage> ) -> Result<Arc<Client>, Error> {
|
|
||||||
let mut dir = path.to_path_buf();
|
|
||||||
dir.push(H64::from(spec.genesis_header().hash()).hex());
|
|
||||||
//TODO: sec/fat: pruned/full versioning
|
|
||||||
dir.push(format!("v{}-sec-pruned", CLIENT_DB_VER_STR));
|
|
||||||
let path = dir.as_path();
|
|
||||||
let gb = spec.genesis_block();
|
|
||||||
let chain = Arc::new(RwLock::new(BlockChain::new(&gb, path)));
|
|
||||||
let mut opts = Options::new();
|
|
||||||
opts.set_max_open_files(256);
|
|
||||||
opts.create_if_missing(true);
|
|
||||||
opts.set_use_fsync(false);
|
|
||||||
opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction);
|
|
||||||
/*
|
|
||||||
opts.set_bytes_per_sync(8388608);
|
|
||||||
opts.set_disable_data_sync(false);
|
|
||||||
opts.set_block_cache_size_mb(1024);
|
|
||||||
opts.set_table_cache_num_shard_bits(6);
|
|
||||||
opts.set_max_write_buffer_number(32);
|
|
||||||
opts.set_write_buffer_size(536870912);
|
|
||||||
opts.set_target_file_size_base(1073741824);
|
|
||||||
opts.set_min_write_buffer_number_to_merge(4);
|
|
||||||
opts.set_level_zero_stop_writes_trigger(2000);
|
|
||||||
opts.set_level_zero_slowdown_writes_trigger(0);
|
|
||||||
opts.set_compaction_style(DBUniversalCompaction);
|
|
||||||
opts.set_max_background_compactions(4);
|
|
||||||
opts.set_max_background_flushes(4);
|
|
||||||
opts.set_filter_deletes(false);
|
|
||||||
opts.set_disable_auto_compactions(false);*/
|
|
||||||
|
|
||||||
let mut state_path = path.to_path_buf();
|
|
||||||
state_path.push("state");
|
|
||||||
let db = Arc::new(DB::open(&opts, state_path.to_str().unwrap()).unwrap());
|
|
||||||
|
|
||||||
let engine = Arc::new(try!(spec.to_engine()));
|
|
||||||
let mut state_db = JournalDB::new_with_arc(db.clone());
|
|
||||||
if state_db.is_empty() && engine.spec().ensure_db_good(&mut state_db) {
|
|
||||||
state_db.commit(0, &engine.spec().genesis_header().hash(), None).expect("Error commiting genesis state to state DB");
|
|
||||||
}
|
|
||||||
|
|
||||||
let block_queue = BlockQueue::new(engine.clone(), message_channel);
|
|
||||||
let panic_handler = PanicHandler::new_in_arc();
|
|
||||||
panic_handler.forward_from(&block_queue);
|
|
||||||
|
|
||||||
Ok(Arc::new(Client {
|
|
||||||
chain: chain,
|
|
||||||
engine: engine,
|
|
||||||
state_db: Mutex::new(state_db),
|
|
||||||
block_queue: RwLock::new(block_queue),
|
|
||||||
report: RwLock::new(Default::default()),
|
|
||||||
import_lock: Mutex::new(()),
|
|
||||||
panic_handler: panic_handler
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Flush the block import queue.
|
|
||||||
pub fn flush_queue(&self) {
|
|
||||||
self.block_queue.write().unwrap().flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is triggered by a message coming from a block queue when the block is ready for insertion
|
|
||||||
pub fn import_verified_blocks(&self, io: &IoChannel<NetSyncMessage>) -> usize {
|
|
||||||
let mut ret = 0;
|
|
||||||
let mut bad = HashSet::new();
|
|
||||||
let _import_lock = self.import_lock.lock();
|
|
||||||
let blocks = self.block_queue.write().unwrap().drain(128);
|
|
||||||
let mut good_blocks = Vec::with_capacity(128);
|
|
||||||
for block in blocks {
|
|
||||||
if bad.contains(&block.header.parent_hash) {
|
|
||||||
self.block_queue.write().unwrap().mark_as_bad(&block.header.hash());
|
|
||||||
bad.insert(block.header.hash());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let header = &block.header;
|
|
||||||
if let Err(e) = verify_block_family(&header, &block.bytes, self.engine.deref().deref(), self.chain.read().unwrap().deref()) {
|
|
||||||
warn!(target: "client", "Stage 3 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
|
||||||
self.block_queue.write().unwrap().mark_as_bad(&header.hash());
|
|
||||||
bad.insert(block.header.hash());
|
|
||||||
break;
|
|
||||||
};
|
|
||||||
let parent = match self.chain.read().unwrap().block_header(&header.parent_hash) {
|
|
||||||
Some(p) => p,
|
|
||||||
None => {
|
|
||||||
warn!(target: "client", "Block import failed for #{} ({}): Parent not found ({}) ", header.number(), header.hash(), header.parent_hash);
|
|
||||||
self.block_queue.write().unwrap().mark_as_bad(&header.hash());
|
|
||||||
bad.insert(block.header.hash());
|
|
||||||
break;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
// build last hashes
|
|
||||||
let mut last_hashes = LastHashes::new();
|
|
||||||
last_hashes.resize(256, H256::new());
|
|
||||||
last_hashes[0] = header.parent_hash.clone();
|
|
||||||
for i in 0..255 {
|
|
||||||
match self.chain.read().unwrap().block_details(&last_hashes[i]) {
|
|
||||||
Some(details) => {
|
|
||||||
last_hashes[i + 1] = details.parent.clone();
|
|
||||||
},
|
|
||||||
None => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let db = self.state_db.lock().unwrap().clone();
|
|
||||||
let result = match enact_verified(&block, self.engine.deref().deref(), db, &parent, &last_hashes) {
|
|
||||||
Ok(b) => b,
|
|
||||||
Err(e) => {
|
|
||||||
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
|
||||||
bad.insert(block.header.hash());
|
|
||||||
self.block_queue.write().unwrap().mark_as_bad(&header.hash());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Err(e) = verify_block_final(&header, result.block().header()) {
|
|
||||||
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
|
||||||
self.block_queue.write().unwrap().mark_as_bad(&header.hash());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
good_blocks.push(header.hash().clone());
|
|
||||||
|
|
||||||
self.chain.write().unwrap().insert_block(&block.bytes); //TODO: err here?
|
|
||||||
let ancient = if header.number() >= HISTORY { Some(header.number() - HISTORY) } else { None };
|
|
||||||
match result.drain().commit(header.number(), &header.hash(), ancient.map(|n|(n, self.chain.read().unwrap().block_hash(n).unwrap()))) {
|
|
||||||
Ok(_) => (),
|
|
||||||
Err(e) => {
|
|
||||||
warn!(target: "client", "State DB commit failed: {:?}", e);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.report.write().unwrap().accrue_block(&block);
|
|
||||||
trace!(target: "client", "Imported #{} ({})", header.number(), header.hash());
|
|
||||||
ret += 1;
|
|
||||||
}
|
|
||||||
self.block_queue.write().unwrap().mark_as_good(&good_blocks);
|
|
||||||
if !good_blocks.is_empty() && self.block_queue.read().unwrap().queue_info().is_empty() {
|
|
||||||
io.send(NetworkIoMessage::User(SyncMessage::BlockVerified)).unwrap();
|
|
||||||
}
|
|
||||||
ret
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get a copy of the best block's state.
|
|
||||||
pub fn state(&self) -> State {
|
|
||||||
State::from_existing(self.state_db.lock().unwrap().clone(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get info on the cache.
|
|
||||||
pub fn cache_info(&self) -> CacheSize {
|
|
||||||
self.chain.read().unwrap().cache_size()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Get the report.
|
|
||||||
pub fn report(&self) -> ClientReport {
|
|
||||||
self.report.read().unwrap().clone()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Tick the client.
|
|
||||||
pub fn tick(&self) {
|
|
||||||
self.chain.read().unwrap().collect_garbage();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Set up the cache behaviour.
|
|
||||||
pub fn configure_cache(&self, pref_cache_size: usize, max_cache_size: usize) {
|
|
||||||
self.chain.write().unwrap().configure_cache(pref_cache_size, max_cache_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_hash(chain: &BlockChain, id: BlockId) -> Option<H256> {
|
|
||||||
match id {
|
|
||||||
BlockId::Hash(hash) => Some(hash),
|
|
||||||
BlockId::Number(number) => chain.block_hash(number),
|
|
||||||
BlockId::Earliest => chain.block_hash(0),
|
|
||||||
BlockId::Latest => Some(chain.best_block_hash())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BlockChainClient for Client {
|
|
||||||
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
|
||||||
let chain = self.chain.read().unwrap();
|
|
||||||
Self::block_hash(&chain, id).and_then(|hash| chain.block(&hash).map(|bytes| BlockView::new(&bytes).rlp().at(0).as_raw().to_vec()))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
|
||||||
let chain = self.chain.read().unwrap();
|
|
||||||
Self::block_hash(&chain, id).and_then(|hash| {
|
|
||||||
chain.block(&hash).map(|bytes| {
|
|
||||||
let rlp = Rlp::new(&bytes);
|
|
||||||
let mut body = RlpStream::new_list(2);
|
|
||||||
body.append_raw(rlp.at(1).as_raw(), 1);
|
|
||||||
body.append_raw(rlp.at(2).as_raw(), 1);
|
|
||||||
body.out()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block(&self, id: BlockId) -> Option<Bytes> {
|
|
||||||
let chain = self.chain.read().unwrap();
|
|
||||||
Self::block_hash(&chain, id).and_then(|hash| {
|
|
||||||
chain.block(&hash)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_status(&self, id: BlockId) -> BlockStatus {
|
|
||||||
let chain = self.chain.read().unwrap();
|
|
||||||
match Self::block_hash(&chain, id) {
|
|
||||||
Some(ref hash) if chain.is_known(hash) => BlockStatus::InChain,
|
|
||||||
Some(hash) => self.block_queue.read().unwrap().block_status(&hash),
|
|
||||||
None => BlockStatus::Unknown
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_total_difficulty(&self, id: BlockId) -> Option<U256> {
|
|
||||||
let chain = self.chain.read().unwrap();
|
|
||||||
Self::block_hash(&chain, id).and_then(|hash| chain.block_details(&hash)).map(|d| d.total_difficulty)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn code(&self, address: &Address) -> Option<Bytes> {
|
|
||||||
self.state().code(address)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction> {
|
|
||||||
let chain = self.chain.read().unwrap();
|
|
||||||
match id {
|
|
||||||
TransactionId::Hash(ref hash) => chain.transaction_address(hash),
|
|
||||||
TransactionId::Location(id, index) => Self::block_hash(&chain, id).map(|hash| TransactionAddress {
|
|
||||||
block_hash: hash,
|
|
||||||
index: index
|
|
||||||
})
|
|
||||||
}.and_then(|address| chain.transaction(&address))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> {
|
|
||||||
self.chain.read().unwrap().tree_route(from.clone(), to.clone())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn state_data(&self, _hash: &H256) -> Option<Bytes> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_receipts(&self, _hash: &H256) -> Option<Bytes> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn import_block(&self, bytes: Bytes) -> ImportResult {
|
|
||||||
let header = BlockView::new(&bytes).header();
|
|
||||||
if self.chain.read().unwrap().is_known(&header.hash()) {
|
|
||||||
return Err(ImportError::AlreadyInChain);
|
|
||||||
}
|
|
||||||
if self.block_status(BlockId::Hash(header.parent_hash)) == BlockStatus::Unknown {
|
|
||||||
return Err(ImportError::UnknownParent);
|
|
||||||
}
|
|
||||||
self.block_queue.write().unwrap().import_block(bytes)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn queue_info(&self) -> BlockQueueInfo {
|
|
||||||
self.block_queue.read().unwrap().queue_info()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn clear_queue(&self) {
|
|
||||||
self.block_queue.write().unwrap().clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn chain_info(&self) -> BlockChainInfo {
|
|
||||||
let chain = self.chain.read().unwrap();
|
|
||||||
BlockChainInfo {
|
|
||||||
total_difficulty: chain.best_block_total_difficulty(),
|
|
||||||
pending_total_difficulty: chain.best_block_total_difficulty(),
|
|
||||||
genesis_hash: chain.genesis_hash(),
|
|
||||||
best_block_hash: chain.best_block_hash(),
|
|
||||||
best_block_number: From::from(chain.best_block_number())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MayPanic for Client {
|
|
||||||
fn on_panic<F>(&self, closure: F) where F: OnPanicListener {
|
|
||||||
self.panic_handler.on_panic(closure);
|
|
||||||
}
|
|
||||||
}
|
|
693
ethcore/src/client/client.rs
Normal file
693
ethcore/src/client/client.rs
Normal file
@ -0,0 +1,693 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Blockchain database client.
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
use util::*;
|
||||||
|
use util::panics::*;
|
||||||
|
use views::BlockView;
|
||||||
|
use error::*;
|
||||||
|
use header::{BlockNumber, Header};
|
||||||
|
use state::State;
|
||||||
|
use spec::Spec;
|
||||||
|
use engine::Engine;
|
||||||
|
use views::HeaderView;
|
||||||
|
use service::{NetSyncMessage, SyncMessage};
|
||||||
|
use env_info::LastHashes;
|
||||||
|
use verification::*;
|
||||||
|
use block::*;
|
||||||
|
use transaction::{LocalizedTransaction, SignedTransaction};
|
||||||
|
use extras::TransactionAddress;
|
||||||
|
use filter::Filter;
|
||||||
|
use log_entry::LocalizedLogEntry;
|
||||||
|
use block_queue::{BlockQueue, BlockQueueInfo};
|
||||||
|
use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute};
|
||||||
|
use client::{BlockId, TransactionId, UncleId, ClientConfig, BlockChainClient};
|
||||||
|
use env_info::EnvInfo;
|
||||||
|
use executive::{Executive, Executed};
|
||||||
|
use receipt::LocalizedReceipt;
|
||||||
|
pub use blockchain::CacheSize as BlockChainCacheSize;
|
||||||
|
|
||||||
|
/// General block status
|
||||||
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
|
pub enum BlockStatus {
|
||||||
|
/// Part of the blockchain.
|
||||||
|
InChain,
|
||||||
|
/// Queued for import.
|
||||||
|
Queued,
|
||||||
|
/// Known as bad.
|
||||||
|
Bad,
|
||||||
|
/// Unknown.
|
||||||
|
Unknown,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Information about the blockchain gathered together.
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct BlockChainInfo {
|
||||||
|
/// Blockchain difficulty.
|
||||||
|
pub total_difficulty: U256,
|
||||||
|
/// Block queue difficulty.
|
||||||
|
pub pending_total_difficulty: U256,
|
||||||
|
/// Genesis block hash.
|
||||||
|
pub genesis_hash: H256,
|
||||||
|
/// Best blockchain block hash.
|
||||||
|
pub best_block_hash: H256,
|
||||||
|
/// Best blockchain block number.
|
||||||
|
pub best_block_number: BlockNumber
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for BlockChainInfo {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "#{}.{}", self.best_block_number, self.best_block_hash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Report on the status of a client.
|
||||||
|
#[derive(Default, Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub struct ClientReport {
|
||||||
|
/// How many blocks have been imported so far.
|
||||||
|
pub blocks_imported: usize,
|
||||||
|
/// How many transactions have been applied so far.
|
||||||
|
pub transactions_applied: usize,
|
||||||
|
/// How much gas has been processed so far.
|
||||||
|
pub gas_processed: U256,
|
||||||
|
/// Memory used by state DB
|
||||||
|
pub state_db_mem: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ClientReport {
|
||||||
|
/// Alter internal reporting to reflect the additional `block` has been processed.
|
||||||
|
pub fn accrue_block(&mut self, block: &PreverifiedBlock) {
|
||||||
|
self.blocks_imported += 1;
|
||||||
|
self.transactions_applied += block.transactions.len();
|
||||||
|
self.gas_processed = self.gas_processed + block.header.gas_used;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Blockchain database client backed by a persistent database. Owns and manages a blockchain and a block queue.
|
||||||
|
/// Call `import_block()` to import a block asynchronously; `flush_queue()` flushes the queue.
|
||||||
|
pub struct Client<V = CanonVerifier> where V: Verifier {
|
||||||
|
chain: Arc<BlockChain>,
|
||||||
|
engine: Arc<Box<Engine>>,
|
||||||
|
state_db: Mutex<Box<JournalDB>>,
|
||||||
|
block_queue: BlockQueue,
|
||||||
|
report: RwLock<ClientReport>,
|
||||||
|
import_lock: Mutex<()>,
|
||||||
|
panic_handler: Arc<PanicHandler>,
|
||||||
|
verifier: PhantomData<V>,
|
||||||
|
}
|
||||||
|
|
||||||
|
const HISTORY: u64 = 1200;
|
||||||
|
// DO NOT TOUCH THIS ANY MORE UNLESS YOU REALLY KNOW WHAT YOU'RE DOING.
|
||||||
|
// Altering it will force a blanket DB update for *all* JournalDB-derived
|
||||||
|
// databases.
|
||||||
|
// Instead, add/upgrade the version string of the individual JournalDB-derived database
|
||||||
|
// of which you actually want force an upgrade.
|
||||||
|
const CLIENT_DB_VER_STR: &'static str = "5.3";
|
||||||
|
|
||||||
|
impl Client<CanonVerifier> {
|
||||||
|
/// Create a new client with given spec and DB path.
|
||||||
|
pub fn new(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel<NetSyncMessage> ) -> Result<Arc<Client>, Error> {
|
||||||
|
Client::<CanonVerifier>::new_with_verifier(config, spec, path, message_channel)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V> Client<V> where V: Verifier {
|
||||||
|
/// Create a new client with given spec and DB path and custom verifier.
|
||||||
|
pub fn new_with_verifier(config: ClientConfig, spec: Spec, path: &Path, message_channel: IoChannel<NetSyncMessage> ) -> Result<Arc<Client<V>>, Error> {
|
||||||
|
let mut dir = path.to_path_buf();
|
||||||
|
dir.push(H64::from(spec.genesis_header().hash()).hex());
|
||||||
|
//TODO: sec/fat: pruned/full versioning
|
||||||
|
// version here is a bit useless now, since it's controlled only be the pruning algo.
|
||||||
|
dir.push(format!("v{}-sec-{}", CLIENT_DB_VER_STR, config.pruning));
|
||||||
|
let path = dir.as_path();
|
||||||
|
let gb = spec.genesis_block();
|
||||||
|
let chain = Arc::new(BlockChain::new(config.blockchain, &gb, path));
|
||||||
|
let mut state_path = path.to_path_buf();
|
||||||
|
state_path.push("state");
|
||||||
|
|
||||||
|
let engine = Arc::new(try!(spec.to_engine()));
|
||||||
|
let state_path_str = state_path.to_str().unwrap();
|
||||||
|
let mut state_db = journaldb::new(state_path_str, config.pruning);
|
||||||
|
|
||||||
|
if state_db.is_empty() && engine.spec().ensure_db_good(state_db.as_hashdb_mut()) {
|
||||||
|
state_db.commit(0, &engine.spec().genesis_header().hash(), None).expect("Error commiting genesis state to state DB");
|
||||||
|
}
|
||||||
|
|
||||||
|
let block_queue = BlockQueue::new(config.queue, engine.clone(), message_channel);
|
||||||
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
|
panic_handler.forward_from(&block_queue);
|
||||||
|
|
||||||
|
Ok(Arc::new(Client {
|
||||||
|
chain: chain,
|
||||||
|
engine: engine,
|
||||||
|
state_db: Mutex::new(state_db),
|
||||||
|
block_queue: block_queue,
|
||||||
|
report: RwLock::new(Default::default()),
|
||||||
|
import_lock: Mutex::new(()),
|
||||||
|
panic_handler: panic_handler,
|
||||||
|
verifier: PhantomData,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Flush the block import queue.
|
||||||
|
pub fn flush_queue(&self) {
|
||||||
|
self.block_queue.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn build_last_hashes(&self, parent_hash: H256) -> LastHashes {
|
||||||
|
let mut last_hashes = LastHashes::new();
|
||||||
|
last_hashes.resize(256, H256::new());
|
||||||
|
last_hashes[0] = parent_hash;
|
||||||
|
for i in 0..255 {
|
||||||
|
match self.chain.block_details(&last_hashes[i]) {
|
||||||
|
Some(details) => {
|
||||||
|
last_hashes[i + 1] = details.parent.clone();
|
||||||
|
},
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_hashes
|
||||||
|
}
|
||||||
|
|
||||||
|
fn check_and_close_block(&self, block: &PreverifiedBlock) -> Result<ClosedBlock, ()> {
|
||||||
|
let engine = self.engine.deref().deref();
|
||||||
|
let header = &block.header;
|
||||||
|
|
||||||
|
// Check the block isn't so old we won't be able to enact it.
|
||||||
|
let best_block_number = self.chain.best_block_number();
|
||||||
|
if best_block_number >= HISTORY && header.number() <= best_block_number - HISTORY {
|
||||||
|
warn!(target: "client", "Block import failed for #{} ({})\nBlock is ancient (current best block: #{}).", header.number(), header.hash(), best_block_number);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify Block Family
|
||||||
|
let verify_family_result = V::verify_block_family(&header, &block.bytes, engine, self.chain.deref());
|
||||||
|
if let Err(e) = verify_family_result {
|
||||||
|
warn!(target: "client", "Stage 3 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||||
|
return Err(());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Check if Parent is in chain
|
||||||
|
let chain_has_parent = self.chain.block_header(&header.parent_hash);
|
||||||
|
if let None = chain_has_parent {
|
||||||
|
warn!(target: "client", "Block import failed for #{} ({}): Parent not found ({}) ", header.number(), header.hash(), header.parent_hash);
|
||||||
|
return Err(());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Enact Verified Block
|
||||||
|
let parent = chain_has_parent.unwrap();
|
||||||
|
let last_hashes = self.build_last_hashes(header.parent_hash.clone());
|
||||||
|
let db = self.state_db.lock().unwrap().spawn();
|
||||||
|
|
||||||
|
let enact_result = enact_verified(&block, engine, self.chain.have_tracing(), db, &parent, last_hashes);
|
||||||
|
if let Err(e) = enact_result {
|
||||||
|
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||||
|
return Err(());
|
||||||
|
};
|
||||||
|
|
||||||
|
// Final Verification
|
||||||
|
let closed_block = enact_result.unwrap();
|
||||||
|
if let Err(e) = V::verify_block_final(&header, closed_block.block().header()) {
|
||||||
|
warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||||
|
return Err(());
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(closed_block)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_enacted_retracted(&self, import_results: Vec<ImportRoute>) -> (Vec<H256>, Vec<H256>) {
|
||||||
|
fn map_to_vec(map: Vec<(H256, bool)>) -> Vec<H256> {
|
||||||
|
map.into_iter().map(|(k, _v)| k).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
// In ImportRoute we get all the blocks that have been enacted and retracted by single insert.
|
||||||
|
// Because we are doing multiple inserts some of the blocks that were enacted in import `k`
|
||||||
|
// could be retracted in import `k+1`. This is why to understand if after all inserts
|
||||||
|
// the block is enacted or retracted we iterate over all routes and at the end final state
|
||||||
|
// will be in the hashmap
|
||||||
|
let map = import_results.into_iter().fold(HashMap::new(), |mut map, route| {
|
||||||
|
for hash in route.enacted {
|
||||||
|
map.insert(hash, true);
|
||||||
|
}
|
||||||
|
for hash in route.retracted {
|
||||||
|
map.insert(hash, false);
|
||||||
|
}
|
||||||
|
map
|
||||||
|
});
|
||||||
|
|
||||||
|
// Split to enacted retracted (using hashmap value)
|
||||||
|
let (enacted, retracted) = map.into_iter().partition(|&(_k, v)| v);
|
||||||
|
// And convert tuples to keys
|
||||||
|
(map_to_vec(enacted), map_to_vec(retracted))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This is triggered by a message coming from a block queue when the block is ready for insertion
|
||||||
|
pub fn import_verified_blocks(&self, io: &IoChannel<NetSyncMessage>) -> usize {
|
||||||
|
let max_blocks_to_import = 128;
|
||||||
|
|
||||||
|
let mut imported_blocks = Vec::with_capacity(max_blocks_to_import);
|
||||||
|
let mut invalid_blocks = HashSet::new();
|
||||||
|
let mut import_results = Vec::with_capacity(max_blocks_to_import);
|
||||||
|
|
||||||
|
let _import_lock = self.import_lock.lock();
|
||||||
|
let blocks = self.block_queue.drain(max_blocks_to_import);
|
||||||
|
|
||||||
|
let original_best = self.chain_info().best_block_hash;
|
||||||
|
|
||||||
|
for block in blocks {
|
||||||
|
let header = &block.header;
|
||||||
|
|
||||||
|
if invalid_blocks.contains(&header.parent_hash) {
|
||||||
|
invalid_blocks.insert(header.hash());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let closed_block = self.check_and_close_block(&block);
|
||||||
|
if let Err(_) = closed_block {
|
||||||
|
invalid_blocks.insert(header.hash());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
imported_blocks.push(header.hash());
|
||||||
|
|
||||||
|
// Are we committing an era?
|
||||||
|
let ancient = if header.number() >= HISTORY {
|
||||||
|
let n = header.number() - HISTORY;
|
||||||
|
Some((n, self.chain.block_hash(n).unwrap()))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// Commit results
|
||||||
|
let closed_block = closed_block.unwrap();
|
||||||
|
let receipts = closed_block.block().receipts().clone();
|
||||||
|
closed_block.drain()
|
||||||
|
.commit(header.number(), &header.hash(), ancient)
|
||||||
|
.expect("State DB commit failed.");
|
||||||
|
|
||||||
|
// And update the chain after commit to prevent race conditions
|
||||||
|
// (when something is in chain but you are not able to fetch details)
|
||||||
|
let route = self.chain.insert_block(&block.bytes, receipts);
|
||||||
|
import_results.push(route);
|
||||||
|
|
||||||
|
self.report.write().unwrap().accrue_block(&block);
|
||||||
|
trace!(target: "client", "Imported #{} ({})", header.number(), header.hash());
|
||||||
|
}
|
||||||
|
|
||||||
|
let imported = imported_blocks.len();
|
||||||
|
let invalid_blocks = invalid_blocks.into_iter().collect::<Vec<H256>>();
|
||||||
|
|
||||||
|
{
|
||||||
|
if !invalid_blocks.is_empty() {
|
||||||
|
self.block_queue.mark_as_bad(&invalid_blocks);
|
||||||
|
}
|
||||||
|
if !imported_blocks.is_empty() {
|
||||||
|
self.block_queue.mark_as_good(&imported_blocks);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if !imported_blocks.is_empty() && self.block_queue.queue_info().is_empty() {
|
||||||
|
let (enacted, retracted) = self.calculate_enacted_retracted(import_results);
|
||||||
|
io.send(NetworkIoMessage::User(SyncMessage::NewChainBlocks {
|
||||||
|
imported: imported_blocks,
|
||||||
|
invalid: invalid_blocks,
|
||||||
|
enacted: enacted,
|
||||||
|
retracted: retracted,
|
||||||
|
})).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
if self.chain_info().best_block_hash != original_best {
|
||||||
|
io.send(NetworkIoMessage::User(SyncMessage::NewChainHead)).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
imported
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a copy of the best block's state.
|
||||||
|
pub fn state(&self) -> State {
|
||||||
|
State::from_existing(self.state_db.lock().unwrap().spawn(), HeaderView::new(&self.best_block_header()).state_root(), self.engine.account_start_nonce())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get info on the cache.
|
||||||
|
pub fn blockchain_cache_info(&self) -> BlockChainCacheSize {
|
||||||
|
self.chain.cache_size()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the report.
|
||||||
|
pub fn report(&self) -> ClientReport {
|
||||||
|
let mut report = self.report.read().unwrap().clone();
|
||||||
|
report.state_db_mem = self.state_db.lock().unwrap().mem_used();
|
||||||
|
report
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tick the client.
|
||||||
|
pub fn tick(&self) {
|
||||||
|
self.chain.collect_garbage();
|
||||||
|
self.block_queue.collect_garbage();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set up the cache behaviour.
|
||||||
|
pub fn configure_cache(&self, pref_cache_size: usize, max_cache_size: usize) {
|
||||||
|
self.chain.configure_cache(pref_cache_size, max_cache_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_hash(chain: &BlockChain, id: BlockId) -> Option<H256> {
|
||||||
|
match id {
|
||||||
|
BlockId::Hash(hash) => Some(hash),
|
||||||
|
BlockId::Number(number) => chain.block_hash(number),
|
||||||
|
BlockId::Earliest => chain.block_hash(0),
|
||||||
|
BlockId::Latest => Some(chain.best_block_hash())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_number(&self, id: BlockId) -> Option<BlockNumber> {
|
||||||
|
match id {
|
||||||
|
BlockId::Number(number) => Some(number),
|
||||||
|
BlockId::Hash(ref hash) => self.chain.block_number(hash),
|
||||||
|
BlockId::Earliest => Some(0),
|
||||||
|
BlockId::Latest => Some(self.chain.best_block_number())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transaction_address(&self, id: TransactionId) -> Option<TransactionAddress> {
|
||||||
|
match id {
|
||||||
|
TransactionId::Hash(ref hash) => self.chain.transaction_address(hash),
|
||||||
|
TransactionId::Location(id, index) => Self::block_hash(&self.chain, id).map(|hash| TransactionAddress {
|
||||||
|
block_hash: hash,
|
||||||
|
index: index
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V> BlockChainClient for Client<V> where V: Verifier {
|
||||||
|
fn call(&self, t: &SignedTransaction) -> Result<Executed, Error> {
|
||||||
|
let header = self.block_header(BlockId::Latest).unwrap();
|
||||||
|
let view = HeaderView::new(&header);
|
||||||
|
let last_hashes = self.build_last_hashes(view.hash());
|
||||||
|
let env_info = EnvInfo {
|
||||||
|
number: view.number(),
|
||||||
|
author: view.author(),
|
||||||
|
timestamp: view.timestamp(),
|
||||||
|
difficulty: view.difficulty(),
|
||||||
|
last_hashes: last_hashes,
|
||||||
|
gas_used: U256::zero(),
|
||||||
|
gas_limit: U256::max_value(),
|
||||||
|
};
|
||||||
|
// that's just a copy of the state.
|
||||||
|
let mut state = self.state();
|
||||||
|
let sender = try!(t.sender());
|
||||||
|
let balance = state.balance(&sender);
|
||||||
|
// give the sender max balance
|
||||||
|
state.sub_balance(&sender, &balance);
|
||||||
|
state.add_balance(&sender, &U256::max_value());
|
||||||
|
Executive::new(&mut state, &env_info, self.engine.deref().deref()).transact(t, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO [todr] Should be moved to miner crate eventually.
|
||||||
|
fn try_seal(&self, block: ClosedBlock, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
|
||||||
|
block.try_seal(self.engine.deref().deref(), seal)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO [todr] Should be moved to miner crate eventually.
|
||||||
|
fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>)
|
||||||
|
-> Option<(ClosedBlock, HashSet<H256>)> {
|
||||||
|
let engine = self.engine.deref().deref();
|
||||||
|
let h = self.chain.best_block_hash();
|
||||||
|
|
||||||
|
let mut b = OpenBlock::new(
|
||||||
|
engine,
|
||||||
|
false, // TODO: this will need to be parameterised once we want to do immediate mining insertion.
|
||||||
|
self.state_db.lock().unwrap().spawn(),
|
||||||
|
match self.chain.block_header(&h) { Some(ref x) => x, None => {return None} },
|
||||||
|
self.build_last_hashes(h.clone()),
|
||||||
|
author,
|
||||||
|
gas_floor_target,
|
||||||
|
extra_data,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add uncles
|
||||||
|
self.chain
|
||||||
|
.find_uncle_headers(&h, engine.maximum_uncle_age())
|
||||||
|
.unwrap()
|
||||||
|
.into_iter()
|
||||||
|
.take(engine.maximum_uncle_count())
|
||||||
|
.foreach(|h| {
|
||||||
|
b.push_uncle(h).unwrap();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add transactions
|
||||||
|
let block_number = b.block().header().number();
|
||||||
|
let min_tx_gas = U256::from(self.engine.schedule(&b.env_info()).tx_gas);
|
||||||
|
let mut invalid_transactions = HashSet::new();
|
||||||
|
|
||||||
|
for tx in transactions {
|
||||||
|
// Push transaction to block
|
||||||
|
let hash = tx.hash();
|
||||||
|
let import = b.push_transaction(tx, None);
|
||||||
|
|
||||||
|
match import {
|
||||||
|
Err(Error::Execution(ExecutionError::BlockGasLimitReached { gas_limit, gas_used, .. })) => {
|
||||||
|
trace!(target: "miner", "Skipping adding transaction to block because of gas limit: {:?}", hash);
|
||||||
|
// Exit early if gas left is smaller then min_tx_gas
|
||||||
|
if gas_limit - gas_used < min_tx_gas {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(e) => {
|
||||||
|
invalid_transactions.insert(hash);
|
||||||
|
trace!(target: "miner",
|
||||||
|
"Error adding transaction to block: number={}. transaction_hash={:?}, Error: {:?}",
|
||||||
|
block_number, hash, e);
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// And close
|
||||||
|
let b = b.close();
|
||||||
|
trace!(target: "miner", "Sealing: number={}, hash={}, diff={}",
|
||||||
|
b.block().header().number(),
|
||||||
|
b.hash(),
|
||||||
|
b.block().header().difficulty()
|
||||||
|
);
|
||||||
|
Some((b, invalid_transactions))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||||
|
Self::block_hash(&self.chain, id).and_then(|hash| self.chain.block(&hash).map(|bytes| BlockView::new(&bytes).rlp().at(0).as_raw().to_vec()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
||||||
|
Self::block_hash(&self.chain, id).and_then(|hash| {
|
||||||
|
self.chain.block(&hash).map(|bytes| {
|
||||||
|
let rlp = Rlp::new(&bytes);
|
||||||
|
let mut body = RlpStream::new_list(2);
|
||||||
|
body.append_raw(rlp.at(1).as_raw(), 1);
|
||||||
|
body.append_raw(rlp.at(2).as_raw(), 1);
|
||||||
|
body.out()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block(&self, id: BlockId) -> Option<Bytes> {
|
||||||
|
Self::block_hash(&self.chain, id).and_then(|hash| {
|
||||||
|
self.chain.block(&hash)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_status(&self, id: BlockId) -> BlockStatus {
|
||||||
|
match Self::block_hash(&self.chain, id) {
|
||||||
|
Some(ref hash) if self.chain.is_known(hash) => BlockStatus::InChain,
|
||||||
|
Some(hash) => self.block_queue.block_status(&hash),
|
||||||
|
None => BlockStatus::Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_total_difficulty(&self, id: BlockId) -> Option<U256> {
|
||||||
|
Self::block_hash(&self.chain, id).and_then(|hash| self.chain.block_details(&hash)).map(|d| d.total_difficulty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nonce(&self, address: &Address) -> U256 {
|
||||||
|
self.state().nonce(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_hash(&self, id: BlockId) -> Option<H256> {
|
||||||
|
Self::block_hash(&self.chain, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn code(&self, address: &Address) -> Option<Bytes> {
|
||||||
|
self.state().code(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn balance(&self, address: &Address) -> U256 {
|
||||||
|
self.state().balance(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn storage_at(&self, address: &Address, position: &H256) -> H256 {
|
||||||
|
self.state().storage_at(address, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction> {
|
||||||
|
self.transaction_address(id).and_then(|address| self.chain.transaction(&address))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uncle(&self, id: UncleId) -> Option<Header> {
|
||||||
|
let index = id.1;
|
||||||
|
self.block(id.0).and_then(|block| BlockView::new(&block).uncle_at(index))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transaction_receipt(&self, id: TransactionId) -> Option<LocalizedReceipt> {
|
||||||
|
self.transaction_address(id).and_then(|address| {
|
||||||
|
let t = self.chain.block(&address.block_hash)
|
||||||
|
.and_then(|block| BlockView::new(&block).localized_transaction_at(address.index));
|
||||||
|
|
||||||
|
match (t, self.chain.transaction_receipt(&address)) {
|
||||||
|
(Some(tx), Some(receipt)) => {
|
||||||
|
let block_hash = tx.block_hash.clone();
|
||||||
|
let block_number = tx.block_number.clone();
|
||||||
|
let transaction_hash = tx.hash();
|
||||||
|
let transaction_index = tx.transaction_index;
|
||||||
|
Some(LocalizedReceipt {
|
||||||
|
transaction_hash: tx.hash(),
|
||||||
|
transaction_index: tx.transaction_index,
|
||||||
|
block_hash: tx.block_hash,
|
||||||
|
block_number: tx.block_number,
|
||||||
|
// TODO: to fix this, query all previous transaction receipts and retrieve their gas usage
|
||||||
|
cumulative_gas_used: receipt.gas_used,
|
||||||
|
gas_used: receipt.gas_used,
|
||||||
|
// TODO: to fix this, store created contract address in db
|
||||||
|
contract_address: None,
|
||||||
|
logs: receipt.logs.into_iter().enumerate().map(|(i, log)| LocalizedLogEntry {
|
||||||
|
entry: log,
|
||||||
|
block_hash: block_hash.clone(),
|
||||||
|
block_number: block_number,
|
||||||
|
transaction_hash: transaction_hash.clone(),
|
||||||
|
transaction_index: transaction_index,
|
||||||
|
log_index: i
|
||||||
|
}).collect()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> {
|
||||||
|
match self.chain.is_known(from) && self.chain.is_known(to) {
|
||||||
|
true => Some(self.chain.tree_route(from.clone(), to.clone())),
|
||||||
|
false => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn state_data(&self, hash: &H256) -> Option<Bytes> {
|
||||||
|
self.state_db.lock().unwrap().state(hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_receipts(&self, hash: &H256) -> Option<Bytes> {
|
||||||
|
self.chain.block_receipts(hash).map(|receipts| rlp::encode(&receipts).to_vec())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn import_block(&self, bytes: Bytes) -> ImportResult {
|
||||||
|
{
|
||||||
|
let header = BlockView::new(&bytes).header_view();
|
||||||
|
if self.chain.is_known(&header.sha3()) {
|
||||||
|
return Err(x!(ImportError::AlreadyInChain));
|
||||||
|
}
|
||||||
|
if self.block_status(BlockId::Hash(header.parent_hash())) == BlockStatus::Unknown {
|
||||||
|
return Err(x!(BlockError::UnknownParent(header.parent_hash())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.block_queue.import_block(bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn queue_info(&self) -> BlockQueueInfo {
|
||||||
|
self.block_queue.queue_info()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_queue(&self) {
|
||||||
|
self.block_queue.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn chain_info(&self) -> BlockChainInfo {
|
||||||
|
BlockChainInfo {
|
||||||
|
total_difficulty: self.chain.best_block_total_difficulty(),
|
||||||
|
pending_total_difficulty: self.chain.best_block_total_difficulty(),
|
||||||
|
genesis_hash: self.chain.genesis_hash(),
|
||||||
|
best_block_hash: self.chain.best_block_hash(),
|
||||||
|
best_block_number: From::from(self.chain.best_block_number())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockId, to_block: BlockId) -> Option<Vec<BlockNumber>> {
|
||||||
|
match (self.block_number(from_block), self.block_number(to_block)) {
|
||||||
|
(Some(from), Some(to)) => Some(self.chain.blocks_with_bloom(bloom, from, to)),
|
||||||
|
_ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn logs(&self, filter: Filter) -> Vec<LocalizedLogEntry> {
|
||||||
|
// TODO: lock blockchain only once
|
||||||
|
|
||||||
|
let mut blocks = filter.bloom_possibilities().iter()
|
||||||
|
.filter_map(|bloom| self.blocks_with_bloom(bloom, filter.from_block.clone(), filter.to_block.clone()))
|
||||||
|
.flat_map(|m| m)
|
||||||
|
// remove duplicate elements
|
||||||
|
.collect::<HashSet<u64>>()
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<u64>>();
|
||||||
|
|
||||||
|
blocks.sort();
|
||||||
|
|
||||||
|
blocks.into_iter()
|
||||||
|
.filter_map(|number| self.chain.block_hash(number).map(|hash| (number, hash)))
|
||||||
|
.filter_map(|(number, hash)| self.chain.block_receipts(&hash).map(|r| (number, hash, r.receipts)))
|
||||||
|
.filter_map(|(number, hash, receipts)| self.chain.block(&hash).map(|ref b| (number, hash, receipts, BlockView::new(b).transaction_hashes())))
|
||||||
|
.flat_map(|(number, hash, receipts, hashes)| {
|
||||||
|
let mut log_index = 0;
|
||||||
|
receipts.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.flat_map(|(index, receipt)| {
|
||||||
|
log_index += receipt.logs.len();
|
||||||
|
receipt.logs.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|tuple| filter.matches(&tuple.1))
|
||||||
|
.map(|(i, log)| LocalizedLogEntry {
|
||||||
|
entry: log,
|
||||||
|
block_hash: hash.clone(),
|
||||||
|
block_number: number,
|
||||||
|
transaction_hash: hashes.get(index).cloned().unwrap_or_else(H256::new),
|
||||||
|
transaction_index: index,
|
||||||
|
log_index: log_index + i
|
||||||
|
})
|
||||||
|
.collect::<Vec<LocalizedLogEntry>>()
|
||||||
|
})
|
||||||
|
.collect::<Vec<LocalizedLogEntry>>()
|
||||||
|
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MayPanic for Client {
|
||||||
|
fn on_panic<F>(&self, closure: F) where F: OnPanicListener {
|
||||||
|
self.panic_handler.on_panic(closure);
|
||||||
|
}
|
||||||
|
}
|
32
ethcore/src/client/config.rs
Normal file
32
ethcore/src/client/config.rs
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
pub use block_queue::BlockQueueConfig;
|
||||||
|
pub use blockchain::BlockChainConfig;
|
||||||
|
use util::journaldb;
|
||||||
|
|
||||||
|
/// Client configuration. Includes configs for all sub-systems.
|
||||||
|
#[derive(Debug, Default)]
|
||||||
|
pub struct ClientConfig {
|
||||||
|
/// Block queue configuration.
|
||||||
|
pub queue: BlockQueueConfig,
|
||||||
|
/// Blockchain configuration.
|
||||||
|
pub blockchain: BlockChainConfig,
|
||||||
|
/// The JournalDB ("pruning") algorithm to use.
|
||||||
|
pub pruning: journaldb::Algorithm,
|
||||||
|
/// The name of the client instance.
|
||||||
|
pub name: String,
|
||||||
|
}
|
52
ethcore/src/client/ids.rs
Normal file
52
ethcore/src/client/ids.rs
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Unique identifiers.
|
||||||
|
|
||||||
|
use util::hash::H256;
|
||||||
|
use header::BlockNumber;
|
||||||
|
|
||||||
|
/// Uniquely identifies block.
|
||||||
|
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
|
||||||
|
pub enum BlockId {
|
||||||
|
/// Block's sha3.
|
||||||
|
/// Querying by hash is always faster.
|
||||||
|
Hash(H256),
|
||||||
|
/// Block number within canon blockchain.
|
||||||
|
Number(BlockNumber),
|
||||||
|
/// Earliest block (genesis).
|
||||||
|
Earliest,
|
||||||
|
/// Latest mined block.
|
||||||
|
Latest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Uniquely identifies transaction.
|
||||||
|
#[derive(Debug, PartialEq, Clone, Hash, Eq)]
|
||||||
|
pub enum TransactionId {
|
||||||
|
/// Transaction's sha3.
|
||||||
|
Hash(H256),
|
||||||
|
/// Block id and transaction index within this block.
|
||||||
|
/// Querying by block position is always faster.
|
||||||
|
Location(BlockId, usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Uniquely identifies Uncle.
|
||||||
|
pub struct UncleId (
|
||||||
|
/// Block id.
|
||||||
|
pub BlockId,
|
||||||
|
/// Position in block.
|
||||||
|
pub usize
|
||||||
|
);
|
132
ethcore/src/client/mod.rs
Normal file
132
ethcore/src/client/mod.rs
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Blockchain database client.
|
||||||
|
|
||||||
|
mod client;
|
||||||
|
mod config;
|
||||||
|
mod ids;
|
||||||
|
mod test_client;
|
||||||
|
|
||||||
|
pub use self::client::*;
|
||||||
|
pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig};
|
||||||
|
pub use self::ids::{BlockId, TransactionId, UncleId};
|
||||||
|
pub use self::test_client::{TestBlockChainClient, EachBlockWith};
|
||||||
|
pub use executive::Executed;
|
||||||
|
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use util::bytes::Bytes;
|
||||||
|
use util::hash::{Address, H256, H2048};
|
||||||
|
use util::numbers::U256;
|
||||||
|
use blockchain::TreeRoute;
|
||||||
|
use block_queue::BlockQueueInfo;
|
||||||
|
use block::{ClosedBlock, SealedBlock};
|
||||||
|
use header::{BlockNumber, Header};
|
||||||
|
use transaction::{LocalizedTransaction, SignedTransaction};
|
||||||
|
use log_entry::LocalizedLogEntry;
|
||||||
|
use filter::Filter;
|
||||||
|
use error::{ImportResult, Error};
|
||||||
|
use receipt::LocalizedReceipt;
|
||||||
|
|
||||||
|
/// Blockchain database client. Owns and manages a blockchain and a block queue.
|
||||||
|
pub trait BlockChainClient : Sync + Send {
|
||||||
|
/// Get raw block header data by block id.
|
||||||
|
fn block_header(&self, id: BlockId) -> Option<Bytes>;
|
||||||
|
|
||||||
|
/// Get raw block body data by block id.
|
||||||
|
/// Block body is an RLP list of two items: uncles and transactions.
|
||||||
|
fn block_body(&self, id: BlockId) -> Option<Bytes>;
|
||||||
|
|
||||||
|
/// Get raw block data by block header hash.
|
||||||
|
fn block(&self, id: BlockId) -> Option<Bytes>;
|
||||||
|
|
||||||
|
/// Get block status by block header hash.
|
||||||
|
fn block_status(&self, id: BlockId) -> BlockStatus;
|
||||||
|
|
||||||
|
/// Get block total difficulty.
|
||||||
|
fn block_total_difficulty(&self, id: BlockId) -> Option<U256>;
|
||||||
|
|
||||||
|
/// Get address nonce.
|
||||||
|
fn nonce(&self, address: &Address) -> U256;
|
||||||
|
|
||||||
|
/// Get block hash.
|
||||||
|
fn block_hash(&self, id: BlockId) -> Option<H256>;
|
||||||
|
|
||||||
|
/// Get address code.
|
||||||
|
fn code(&self, address: &Address) -> Option<Bytes>;
|
||||||
|
|
||||||
|
/// Get address balance.
|
||||||
|
fn balance(&self, address: &Address) -> U256;
|
||||||
|
|
||||||
|
/// Get value of the storage at given position.
|
||||||
|
fn storage_at(&self, address: &Address, position: &H256) -> H256;
|
||||||
|
|
||||||
|
/// Get transaction with given hash.
|
||||||
|
fn transaction(&self, id: TransactionId) -> Option<LocalizedTransaction>;
|
||||||
|
|
||||||
|
/// Get uncle with given id.
|
||||||
|
fn uncle(&self, id: UncleId) -> Option<Header>;
|
||||||
|
|
||||||
|
/// Get transaction receipt with given hash.
|
||||||
|
fn transaction_receipt(&self, id: TransactionId) -> Option<LocalizedReceipt>;
|
||||||
|
|
||||||
|
/// Get a tree route between `from` and `to`.
|
||||||
|
/// See `BlockChain::tree_route`.
|
||||||
|
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute>;
|
||||||
|
|
||||||
|
/// Get latest state node
|
||||||
|
fn state_data(&self, hash: &H256) -> Option<Bytes>;
|
||||||
|
|
||||||
|
/// Get raw block receipts data by block header hash.
|
||||||
|
fn block_receipts(&self, hash: &H256) -> Option<Bytes>;
|
||||||
|
|
||||||
|
/// Import a block into the blockchain.
|
||||||
|
fn import_block(&self, bytes: Bytes) -> ImportResult;
|
||||||
|
|
||||||
|
/// Get block queue information.
|
||||||
|
fn queue_info(&self) -> BlockQueueInfo;
|
||||||
|
|
||||||
|
/// Clear block queue and abort all import activity.
|
||||||
|
fn clear_queue(&self);
|
||||||
|
|
||||||
|
/// Get blockchain information.
|
||||||
|
fn chain_info(&self) -> BlockChainInfo;
|
||||||
|
|
||||||
|
/// Get the best block header.
|
||||||
|
fn best_block_header(&self) -> Bytes {
|
||||||
|
// TODO: lock blockchain only once
|
||||||
|
self.block_header(BlockId::Hash(self.chain_info().best_block_hash)).unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns numbers of blocks containing given bloom.
|
||||||
|
fn blocks_with_bloom(&self, bloom: &H2048, from_block: BlockId, to_block: BlockId) -> Option<Vec<BlockNumber>>;
|
||||||
|
|
||||||
|
/// Returns logs matching given filter.
|
||||||
|
fn logs(&self, filter: Filter) -> Vec<LocalizedLogEntry>;
|
||||||
|
|
||||||
|
// TODO [todr] Should be moved to miner crate eventually.
|
||||||
|
/// Returns ClosedBlock prepared for sealing.
|
||||||
|
fn prepare_sealing(&self, author: Address, gas_floor_target: U256, extra_data: Bytes, transactions: Vec<SignedTransaction>)
|
||||||
|
-> Option<(ClosedBlock, HashSet<H256>)>;
|
||||||
|
|
||||||
|
// TODO [todr] Should be moved to miner crate eventually.
|
||||||
|
/// Attempts to seal given block. Returns `SealedBlock` on success and the same block in case of error.
|
||||||
|
fn try_seal(&self, block: ClosedBlock, seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock>;
|
||||||
|
|
||||||
|
/// Makes a non-persistent transaction call.
|
||||||
|
fn call(&self, t: &SignedTransaction) -> Result<Executed, Error>;
|
||||||
|
}
|
||||||
|
|
407
ethcore/src/client/test_client.rs
Normal file
407
ethcore/src/client/test_client.rs
Normal file
@ -0,0 +1,407 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Test client.
|
||||||
|
|
||||||
|
use util::*;
|
||||||
|
use transaction::{Transaction, LocalizedTransaction, SignedTransaction, Action};
|
||||||
|
use blockchain::TreeRoute;
|
||||||
|
use client::{BlockChainClient, BlockChainInfo, BlockStatus, BlockId, TransactionId, UncleId};
|
||||||
|
use header::{Header as BlockHeader, BlockNumber};
|
||||||
|
use filter::Filter;
|
||||||
|
use log_entry::LocalizedLogEntry;
|
||||||
|
use receipt::{Receipt, LocalizedReceipt};
|
||||||
|
use extras::BlockReceipts;
|
||||||
|
use error::{ImportResult};
|
||||||
|
|
||||||
|
use block_queue::BlockQueueInfo;
|
||||||
|
use block::{SealedBlock, ClosedBlock};
|
||||||
|
use executive::Executed;
|
||||||
|
use error::Error;
|
||||||
|
|
||||||
|
/// Test client.
|
||||||
|
pub struct TestBlockChainClient {
|
||||||
|
/// Blocks.
|
||||||
|
pub blocks: RwLock<HashMap<H256, Bytes>>,
|
||||||
|
/// Mapping of numbers to hashes.
|
||||||
|
pub numbers: RwLock<HashMap<usize, H256>>,
|
||||||
|
/// Genesis block hash.
|
||||||
|
pub genesis_hash: H256,
|
||||||
|
/// Last block hash.
|
||||||
|
pub last_hash: RwLock<H256>,
|
||||||
|
/// Difficulty.
|
||||||
|
pub difficulty: RwLock<U256>,
|
||||||
|
/// Balances.
|
||||||
|
pub balances: RwLock<HashMap<Address, U256>>,
|
||||||
|
/// Storage.
|
||||||
|
pub storage: RwLock<HashMap<(Address, H256), H256>>,
|
||||||
|
/// Code.
|
||||||
|
pub code: RwLock<HashMap<Address, Bytes>>,
|
||||||
|
/// Execution result.
|
||||||
|
pub execution_result: RwLock<Option<Executed>>,
|
||||||
|
/// Transaction receipts.
|
||||||
|
pub receipts: RwLock<HashMap<TransactionId, LocalizedReceipt>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
/// Used for generating test client blocks.
|
||||||
|
pub enum EachBlockWith {
|
||||||
|
/// Plain block.
|
||||||
|
Nothing,
|
||||||
|
/// Block with an uncle.
|
||||||
|
Uncle,
|
||||||
|
/// Block with a transaction.
|
||||||
|
Transaction,
|
||||||
|
/// Block with an uncle and transaction.
|
||||||
|
UncleAndTransaction
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TestBlockChainClient {
|
||||||
|
fn default() -> Self {
|
||||||
|
TestBlockChainClient::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TestBlockChainClient {
|
||||||
|
/// Creates new test client.
|
||||||
|
pub fn new() -> Self {
|
||||||
|
|
||||||
|
let mut client = TestBlockChainClient {
|
||||||
|
blocks: RwLock::new(HashMap::new()),
|
||||||
|
numbers: RwLock::new(HashMap::new()),
|
||||||
|
genesis_hash: H256::new(),
|
||||||
|
last_hash: RwLock::new(H256::new()),
|
||||||
|
difficulty: RwLock::new(From::from(0)),
|
||||||
|
balances: RwLock::new(HashMap::new()),
|
||||||
|
storage: RwLock::new(HashMap::new()),
|
||||||
|
code: RwLock::new(HashMap::new()),
|
||||||
|
execution_result: RwLock::new(None),
|
||||||
|
receipts: RwLock::new(HashMap::new()),
|
||||||
|
};
|
||||||
|
client.add_blocks(1, EachBlockWith::Nothing); // add genesis block
|
||||||
|
client.genesis_hash = client.last_hash.read().unwrap().clone();
|
||||||
|
client
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the transaction receipt result
|
||||||
|
pub fn set_transaction_receipt(&self, id: TransactionId, receipt: LocalizedReceipt) {
|
||||||
|
self.receipts.write().unwrap().insert(id, receipt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the execution result.
|
||||||
|
pub fn set_execution_result(&self, result: Executed) {
|
||||||
|
*self.execution_result.write().unwrap() = Some(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set the balance of account `address` to `balance`.
|
||||||
|
pub fn set_balance(&self, address: Address, balance: U256) {
|
||||||
|
self.balances.write().unwrap().insert(address, balance);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set `code` at `address`.
|
||||||
|
pub fn set_code(&self, address: Address, code: Bytes) {
|
||||||
|
self.code.write().unwrap().insert(address, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Set storage `position` to `value` for account `address`.
|
||||||
|
pub fn set_storage(&self, address: Address, position: H256, value: H256) {
|
||||||
|
self.storage.write().unwrap().insert((address, position), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add blocks to test client.
|
||||||
|
pub fn add_blocks(&self, count: usize, with: EachBlockWith) {
|
||||||
|
let len = self.numbers.read().unwrap().len();
|
||||||
|
for n in len..(len + count) {
|
||||||
|
let mut header = BlockHeader::new();
|
||||||
|
header.difficulty = From::from(n);
|
||||||
|
header.parent_hash = self.last_hash.read().unwrap().clone();
|
||||||
|
header.number = n as BlockNumber;
|
||||||
|
header.gas_limit = U256::from(1_000_000);
|
||||||
|
let uncles = match with {
|
||||||
|
EachBlockWith::Uncle | EachBlockWith::UncleAndTransaction => {
|
||||||
|
let mut uncles = RlpStream::new_list(1);
|
||||||
|
let mut uncle_header = BlockHeader::new();
|
||||||
|
uncle_header.difficulty = From::from(n);
|
||||||
|
uncle_header.parent_hash = self.last_hash.read().unwrap().clone();
|
||||||
|
uncle_header.number = n as BlockNumber;
|
||||||
|
uncles.append(&uncle_header);
|
||||||
|
header.uncles_hash = uncles.as_raw().sha3();
|
||||||
|
uncles
|
||||||
|
},
|
||||||
|
_ => RlpStream::new_list(0)
|
||||||
|
};
|
||||||
|
let txs = match with {
|
||||||
|
EachBlockWith::Transaction | EachBlockWith::UncleAndTransaction => {
|
||||||
|
let mut txs = RlpStream::new_list(1);
|
||||||
|
let keypair = KeyPair::create().unwrap();
|
||||||
|
let tx = Transaction {
|
||||||
|
action: Action::Create,
|
||||||
|
value: U256::from(100),
|
||||||
|
data: "3331600055".from_hex().unwrap(),
|
||||||
|
gas: U256::from(100_000),
|
||||||
|
gas_price: U256::one(),
|
||||||
|
nonce: U256::zero()
|
||||||
|
};
|
||||||
|
let signed_tx = tx.sign(&keypair.secret());
|
||||||
|
txs.append(&signed_tx);
|
||||||
|
txs.out()
|
||||||
|
},
|
||||||
|
_ => rlp::NULL_RLP.to_vec()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut rlp = RlpStream::new_list(3);
|
||||||
|
rlp.append(&header);
|
||||||
|
rlp.append_raw(&txs, 1);
|
||||||
|
rlp.append_raw(uncles.as_raw(), 1);
|
||||||
|
self.import_block(rlp.as_raw().to_vec()).unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO:
|
||||||
|
pub fn corrupt_block(&mut self, n: BlockNumber) {
|
||||||
|
let hash = self.block_hash(BlockId::Number(n)).unwrap();
|
||||||
|
let mut header: BlockHeader = decode(&self.block_header(BlockId::Number(n)).unwrap());
|
||||||
|
header.parent_hash = H256::new();
|
||||||
|
let mut rlp = RlpStream::new_list(3);
|
||||||
|
rlp.append(&header);
|
||||||
|
rlp.append_raw(&rlp::NULL_RLP, 1);
|
||||||
|
rlp.append_raw(&rlp::NULL_RLP, 1);
|
||||||
|
self.blocks.write().unwrap().insert(hash, rlp.out());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// TODO:
|
||||||
|
pub fn block_hash_delta_minus(&mut self, delta: usize) -> H256 {
|
||||||
|
let blocks_read = self.numbers.read().unwrap();
|
||||||
|
let index = blocks_read.len() - delta;
|
||||||
|
blocks_read[&index].clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_hash(&self, id: BlockId) -> Option<H256> {
|
||||||
|
match id {
|
||||||
|
BlockId::Hash(hash) => Some(hash),
|
||||||
|
BlockId::Number(n) => self.numbers.read().unwrap().get(&(n as usize)).cloned(),
|
||||||
|
BlockId::Earliest => self.numbers.read().unwrap().get(&0).cloned(),
|
||||||
|
BlockId::Latest => self.numbers.read().unwrap().get(&(self.numbers.read().unwrap().len() - 1)).cloned()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockChainClient for TestBlockChainClient {
|
||||||
|
fn call(&self, _t: &SignedTransaction) -> Result<Executed, Error> {
|
||||||
|
Ok(self.execution_result.read().unwrap().clone().unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_total_difficulty(&self, _id: BlockId) -> Option<U256> {
|
||||||
|
Some(U256::zero())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_hash(&self, _id: BlockId) -> Option<H256> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn nonce(&self, _address: &Address) -> U256 {
|
||||||
|
U256::zero()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn code(&self, address: &Address) -> Option<Bytes> {
|
||||||
|
self.code.read().unwrap().get(address).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn balance(&self, address: &Address) -> U256 {
|
||||||
|
self.balances.read().unwrap().get(address).cloned().unwrap_or_else(U256::zero)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn storage_at(&self, address: &Address, position: &H256) -> H256 {
|
||||||
|
self.storage.read().unwrap().get(&(address.clone(), position.clone())).cloned().unwrap_or_else(H256::new)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transaction(&self, _id: TransactionId) -> Option<LocalizedTransaction> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn uncle(&self, _id: UncleId) -> Option<BlockHeader> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn transaction_receipt(&self, id: TransactionId) -> Option<LocalizedReceipt> {
|
||||||
|
self.receipts.read().unwrap().get(&id).cloned()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn blocks_with_bloom(&self, _bloom: &H2048, _from_block: BlockId, _to_block: BlockId) -> Option<Vec<BlockNumber>> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn logs(&self, _filter: Filter) -> Vec<LocalizedLogEntry> {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_sealing(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes, _transactions: Vec<SignedTransaction>) -> Option<(ClosedBlock, HashSet<H256>)> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_seal(&self, block: ClosedBlock, _seal: Vec<Bytes>) -> Result<SealedBlock, ClosedBlock> {
|
||||||
|
Err(block)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_header(&self, id: BlockId) -> Option<Bytes> {
|
||||||
|
self.block_hash(id).and_then(|hash| self.blocks.read().unwrap().get(&hash).map(|r| Rlp::new(r).at(0).as_raw().to_vec()))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_body(&self, id: BlockId) -> Option<Bytes> {
|
||||||
|
self.block_hash(id).and_then(|hash| self.blocks.read().unwrap().get(&hash).map(|r| {
|
||||||
|
let mut stream = RlpStream::new_list(2);
|
||||||
|
stream.append_raw(Rlp::new(&r).at(1).as_raw(), 1);
|
||||||
|
stream.append_raw(Rlp::new(&r).at(2).as_raw(), 1);
|
||||||
|
stream.out()
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block(&self, id: BlockId) -> Option<Bytes> {
|
||||||
|
self.block_hash(id).and_then(|hash| self.blocks.read().unwrap().get(&hash).cloned())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_status(&self, id: BlockId) -> BlockStatus {
|
||||||
|
match id {
|
||||||
|
BlockId::Number(number) if (number as usize) < self.blocks.read().unwrap().len() => BlockStatus::InChain,
|
||||||
|
BlockId::Hash(ref hash) if self.blocks.read().unwrap().get(hash).is_some() => BlockStatus::InChain,
|
||||||
|
_ => BlockStatus::Unknown
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// works only if blocks are one after another 1 -> 2 -> 3
|
||||||
|
fn tree_route(&self, from: &H256, to: &H256) -> Option<TreeRoute> {
|
||||||
|
Some(TreeRoute {
|
||||||
|
ancestor: H256::new(),
|
||||||
|
index: 0,
|
||||||
|
blocks: {
|
||||||
|
let numbers_read = self.numbers.read().unwrap();
|
||||||
|
let mut adding = false;
|
||||||
|
|
||||||
|
let mut blocks = Vec::new();
|
||||||
|
for (_, hash) in numbers_read.iter().sort_by(|tuple1, tuple2| tuple1.0.cmp(tuple2.0)) {
|
||||||
|
if hash == to {
|
||||||
|
if adding {
|
||||||
|
blocks.push(hash.clone());
|
||||||
|
}
|
||||||
|
adding = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if hash == from {
|
||||||
|
adding = true;
|
||||||
|
}
|
||||||
|
if adding {
|
||||||
|
blocks.push(hash.clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if adding { Vec::new() } else { blocks }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: returns just hashes instead of node state rlp(?)
|
||||||
|
fn state_data(&self, hash: &H256) -> Option<Bytes> {
|
||||||
|
// starts with 'f' ?
|
||||||
|
if *hash > H256::from("f000000000000000000000000000000000000000000000000000000000000000") {
|
||||||
|
let mut rlp = RlpStream::new();
|
||||||
|
rlp.append(&hash.clone());
|
||||||
|
return Some(rlp.out());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn block_receipts(&self, hash: &H256) -> Option<Bytes> {
|
||||||
|
// starts with 'f' ?
|
||||||
|
if *hash > H256::from("f000000000000000000000000000000000000000000000000000000000000000") {
|
||||||
|
let receipt = BlockReceipts::new(vec![Receipt::new(
|
||||||
|
H256::zero(),
|
||||||
|
U256::zero(),
|
||||||
|
vec![])]);
|
||||||
|
let mut rlp = RlpStream::new();
|
||||||
|
rlp.append(&receipt);
|
||||||
|
return Some(rlp.out());
|
||||||
|
}
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
||||||
|
fn import_block(&self, b: Bytes) -> ImportResult {
|
||||||
|
let header = Rlp::new(&b).val_at::<BlockHeader>(0);
|
||||||
|
let h = header.hash();
|
||||||
|
let number: usize = header.number as usize;
|
||||||
|
if number > self.blocks.read().unwrap().len() {
|
||||||
|
panic!("Unexpected block number. Expected {}, got {}", self.blocks.read().unwrap().len(), number);
|
||||||
|
}
|
||||||
|
if number > 0 {
|
||||||
|
match self.blocks.read().unwrap().get(&header.parent_hash) {
|
||||||
|
Some(parent) => {
|
||||||
|
let parent = Rlp::new(parent).val_at::<BlockHeader>(0);
|
||||||
|
if parent.number != (header.number - 1) {
|
||||||
|
panic!("Unexpected block parent");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
panic!("Unknown block parent {:?} for block {}", header.parent_hash, number);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let len = self.numbers.read().unwrap().len();
|
||||||
|
if number == len {
|
||||||
|
{
|
||||||
|
let mut difficulty = self.difficulty.write().unwrap();
|
||||||
|
*difficulty.deref_mut() = *difficulty.deref() + header.difficulty;
|
||||||
|
}
|
||||||
|
mem::replace(self.last_hash.write().unwrap().deref_mut(), h.clone());
|
||||||
|
self.blocks.write().unwrap().insert(h.clone(), b);
|
||||||
|
self.numbers.write().unwrap().insert(number, h.clone());
|
||||||
|
let mut parent_hash = header.parent_hash;
|
||||||
|
if number > 0 {
|
||||||
|
let mut n = number - 1;
|
||||||
|
while n > 0 && self.numbers.read().unwrap()[&n] != parent_hash {
|
||||||
|
*self.numbers.write().unwrap().get_mut(&n).unwrap() = parent_hash.clone();
|
||||||
|
n -= 1;
|
||||||
|
parent_hash = Rlp::new(&self.blocks.read().unwrap()[&parent_hash]).val_at::<BlockHeader>(0).parent_hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.blocks.write().unwrap().insert(h.clone(), b.to_vec());
|
||||||
|
}
|
||||||
|
Ok(h)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn queue_info(&self) -> BlockQueueInfo {
|
||||||
|
BlockQueueInfo {
|
||||||
|
verified_queue_size: 0,
|
||||||
|
unverified_queue_size: 0,
|
||||||
|
verifying_queue_size: 0,
|
||||||
|
max_queue_size: 0,
|
||||||
|
max_mem_use: 0,
|
||||||
|
mem_used: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_queue(&self) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn chain_info(&self) -> BlockChainInfo {
|
||||||
|
BlockChainInfo {
|
||||||
|
total_difficulty: *self.difficulty.read().unwrap(),
|
||||||
|
pending_total_difficulty: *self.difficulty.read().unwrap(),
|
||||||
|
genesis_hash: self.genesis_hash.clone(),
|
||||||
|
best_block_hash: self.last_hash.read().unwrap().clone(),
|
||||||
|
best_block_number: self.blocks.read().unwrap().len() as BlockNumber - 1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,4 +25,5 @@ pub use account::*;
|
|||||||
pub use transaction::*;
|
pub use transaction::*;
|
||||||
pub use log_entry::*;
|
pub use log_entry::*;
|
||||||
pub use receipt::*;
|
pub use receipt::*;
|
||||||
pub use action_params::*;
|
pub use action_params::*;
|
||||||
|
pub use trace::*;
|
@ -30,8 +30,6 @@ pub trait Engine : Sync + Send {
|
|||||||
|
|
||||||
/// The number of additional header fields required for this engine.
|
/// The number of additional header fields required for this engine.
|
||||||
fn seal_fields(&self) -> usize { 0 }
|
fn seal_fields(&self) -> usize { 0 }
|
||||||
/// Default values of the additional fields RLP-encoded in a raw (non-list) harness.
|
|
||||||
fn seal_rlp(&self) -> Bytes { vec![] }
|
|
||||||
|
|
||||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||||
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
||||||
@ -49,6 +47,8 @@ pub trait Engine : Sync + Send {
|
|||||||
fn maximum_extra_data_size(&self) -> usize { decode(&self.spec().engine_params.get("maximumExtraDataSize").unwrap()) }
|
fn maximum_extra_data_size(&self) -> usize { decode(&self.spec().engine_params.get("maximumExtraDataSize").unwrap()) }
|
||||||
/// Maximum number of uncles a block is allowed to declare.
|
/// Maximum number of uncles a block is allowed to declare.
|
||||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
fn maximum_uncle_count(&self) -> usize { 2 }
|
||||||
|
/// The number of generations back that uncles can be.
|
||||||
|
fn maximum_uncle_age(&self) -> usize { 6 }
|
||||||
/// The nonce with which accounts begin.
|
/// The nonce with which accounts begin.
|
||||||
fn account_start_nonce(&self) -> U256 { decode(&self.spec().engine_params.get("accountStartNonce").unwrap()) }
|
fn account_start_nonce(&self) -> U256 { decode(&self.spec().engine_params.get("accountStartNonce").unwrap()) }
|
||||||
|
|
||||||
@ -76,9 +76,20 @@ pub trait Engine : Sync + Send {
|
|||||||
/// Verify a particular transaction is valid.
|
/// Verify a particular transaction is valid.
|
||||||
fn verify_transaction(&self, _t: &SignedTransaction, _header: &Header) -> Result<(), Error> { Ok(()) }
|
fn verify_transaction(&self, _t: &SignedTransaction, _header: &Header) -> Result<(), Error> { Ok(()) }
|
||||||
|
|
||||||
/// Don't forget to call Super::populateFromParent when subclassing & overriding.
|
/// Verify the seal of a block. This is an auxilliary method that actually just calls other `verify_` methods
|
||||||
|
/// to get the job done. By default it must pass `verify_basic` and `verify_block_unordered`. If more or fewer
|
||||||
|
/// methods are needed for an Engine, this may be overridden.
|
||||||
|
fn verify_block_seal(&self, header: &Header) -> Result<(), Error> {
|
||||||
|
self.verify_block_basic(header, None).and_then(|_| self.verify_block_unordered(header, None))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Don't forget to call Super::populate_from_parent when subclassing & overriding.
|
||||||
// TODO: consider including State in the params.
|
// TODO: consider including State in the params.
|
||||||
fn populate_from_parent(&self, _header: &mut Header, _parent: &Header) {}
|
fn populate_from_parent(&self, header: &mut Header, parent: &Header, _gas_floor_target: U256) {
|
||||||
|
header.difficulty = parent.difficulty;
|
||||||
|
header.gas_limit = parent.gas_limit;
|
||||||
|
header.note_dirty();
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic
|
// TODO: builtin contract routing - to do this properly, it will require removing the built-in configuration-reading logic
|
||||||
// from Spec into here and removing the Spec::builtins field.
|
// from Spec into here and removing the Spec::builtins field.
|
||||||
@ -92,4 +103,14 @@ pub trait Engine : Sync + Send {
|
|||||||
fn execute_builtin(&self, a: &Address, input: &[u8], output: &mut [u8]) { self.spec().builtins.get(a).unwrap().execute(input, output); }
|
fn execute_builtin(&self, a: &Address, input: &[u8], output: &mut [u8]) { self.spec().builtins.get(a).unwrap().execute(input, output); }
|
||||||
|
|
||||||
// TODO: sealing stuff - though might want to leave this for later.
|
// TODO: sealing stuff - though might want to leave this for later.
|
||||||
|
|
||||||
|
/// Get a named parameter from the `spec()`'s `engine_params` item and convert to u64, or 0 if that fails.
|
||||||
|
fn u64_param(&self, name: &str) -> u64 {
|
||||||
|
self.spec().engine_params.get(name).map_or(0u64, |a| decode(&a))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a named parameter from the `spec()`'s `engine_params` item and convert to U256, or 0 if that fails.
|
||||||
|
fn u256_param(&self, name: &str) -> U256 {
|
||||||
|
self.spec().engine_params.get(name).map_or(x!(0), |a| decode(&a))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,8 +63,33 @@ pub enum ExecutionError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// Errors concerning transaction proessing.
|
/// Errors concerning transaction processing.
|
||||||
pub enum TransactionError {
|
pub enum TransactionError {
|
||||||
|
/// Transaction is already imported to the queue
|
||||||
|
AlreadyImported,
|
||||||
|
/// Transaction is not valid anymore (state already has higher nonce)
|
||||||
|
Old,
|
||||||
|
/// Transaction's gas price is below threshold.
|
||||||
|
InsufficientGasPrice {
|
||||||
|
/// Minimal expected gas price
|
||||||
|
minimal: U256,
|
||||||
|
/// Transaction gas price
|
||||||
|
got: U256,
|
||||||
|
},
|
||||||
|
/// Sender doesn't have enough funds to pay for this transaction
|
||||||
|
InsufficientBalance {
|
||||||
|
/// Senders balance
|
||||||
|
balance: U256,
|
||||||
|
/// Transaction cost
|
||||||
|
cost: U256,
|
||||||
|
},
|
||||||
|
/// Transactions gas is higher then current gas limit
|
||||||
|
GasLimitExceeded {
|
||||||
|
/// Current gas limit
|
||||||
|
limit: U256,
|
||||||
|
/// Declared transaction gas
|
||||||
|
got: U256,
|
||||||
|
},
|
||||||
/// Transaction's gas limit (aka gas) is invalid.
|
/// Transaction's gas limit (aka gas) is invalid.
|
||||||
InvalidGasLimit(OutOfBounds<U256>),
|
InvalidGasLimit(OutOfBounds<U256>),
|
||||||
}
|
}
|
||||||
@ -131,25 +156,14 @@ pub enum BlockError {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// Import to the block queue result
|
/// Import to the block queue result
|
||||||
pub enum ImportError {
|
pub enum ImportError {
|
||||||
/// Bad block detected
|
/// Already in the block chain.
|
||||||
Bad(Option<Error>),
|
|
||||||
/// Already in the block chain
|
|
||||||
AlreadyInChain,
|
AlreadyInChain,
|
||||||
/// Already in the block queue
|
/// Already in the block queue.
|
||||||
AlreadyQueued,
|
AlreadyQueued,
|
||||||
/// Unknown parent
|
/// Already marked as bad from a previous import (could mean parent is bad).
|
||||||
UnknownParent,
|
KnownBad,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for ImportError {
|
|
||||||
fn from(err: Error) -> ImportError {
|
|
||||||
ImportError::Bad(Some(err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Result of import block operation.
|
|
||||||
pub type ImportResult = Result<H256, ImportError>;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
/// General error type which should be capable of representing all errors in ethcore.
|
/// General error type which should be capable of representing all errors in ethcore.
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@ -163,14 +177,29 @@ pub enum Error {
|
|||||||
Execution(ExecutionError),
|
Execution(ExecutionError),
|
||||||
/// Error concerning transaction processing.
|
/// Error concerning transaction processing.
|
||||||
Transaction(TransactionError),
|
Transaction(TransactionError),
|
||||||
|
/// Error concerning block import.
|
||||||
|
Import(ImportError),
|
||||||
|
/// PoW hash is invalid or out of date.
|
||||||
|
PowHashInvalid,
|
||||||
|
/// The value of the nonce or mishash is invalid.
|
||||||
|
PowInvalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Result of import block operation.
|
||||||
|
pub type ImportResult = Result<H256, Error>;
|
||||||
|
|
||||||
impl From<TransactionError> for Error {
|
impl From<TransactionError> for Error {
|
||||||
fn from(err: TransactionError) -> Error {
|
fn from(err: TransactionError) -> Error {
|
||||||
Error::Transaction(err)
|
Error::Transaction(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ImportError> for Error {
|
||||||
|
fn from(err: ImportError) -> Error {
|
||||||
|
Error::Import(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<BlockError> for Error {
|
impl From<BlockError> for Error {
|
||||||
fn from(err: BlockError) -> Error {
|
fn from(err: BlockError) -> Error {
|
||||||
Error::Block(err)
|
Error::Block(err)
|
||||||
|
@ -57,16 +57,6 @@ impl Ethash {
|
|||||||
u256_params: RwLock::new(HashMap::new())
|
u256_params: RwLock::new(HashMap::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn u64_param(&self, name: &str) -> u64 {
|
|
||||||
*self.u64_params.write().unwrap().entry(name.to_owned()).or_insert_with(||
|
|
||||||
self.spec().engine_params.get(name).map_or(0u64, |a| decode(&a)))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn u256_param(&self, name: &str) -> U256 {
|
|
||||||
*self.u256_params.write().unwrap().entry(name.to_owned()).or_insert_with(||
|
|
||||||
self.spec().engine_params.get(name).map_or(x!(0), |a| decode(&a)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Engine for Ethash {
|
impl Engine for Ethash {
|
||||||
@ -74,8 +64,6 @@ impl Engine for Ethash {
|
|||||||
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
|
fn version(&self) -> SemanticVersion { SemanticVersion::new(1, 0, 0) }
|
||||||
// Two fields - mix
|
// Two fields - mix
|
||||||
fn seal_fields(&self) -> usize { 2 }
|
fn seal_fields(&self) -> usize { 2 }
|
||||||
// Two empty data items in RLP.
|
|
||||||
fn seal_rlp(&self) -> Bytes { encode(&H64::new()).to_vec() }
|
|
||||||
|
|
||||||
/// Additional engine-specific information for the user/developer concerning `header`.
|
/// Additional engine-specific information for the user/developer concerning `header`.
|
||||||
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
fn extra_info(&self, _header: &Header) -> HashMap<String, String> { HashMap::new() }
|
||||||
@ -87,20 +75,16 @@ impl Engine for Ethash {
|
|||||||
|
|
||||||
fn schedule(&self, env_info: &EnvInfo) -> Schedule {
|
fn schedule(&self, env_info: &EnvInfo) -> Schedule {
|
||||||
trace!(target: "client", "Creating schedule. param={:?}, fCML={}", self.spec().engine_params.get("frontierCompatibilityModeLimit"), self.u64_param("frontierCompatibilityModeLimit"));
|
trace!(target: "client", "Creating schedule. param={:?}, fCML={}", self.spec().engine_params.get("frontierCompatibilityModeLimit"), self.u64_param("frontierCompatibilityModeLimit"));
|
||||||
match env_info.number < self.u64_param("frontierCompatibilityModeLimit") {
|
if env_info.number < self.u64_param("frontierCompatibilityModeLimit") {
|
||||||
true => {
|
Schedule::new_frontier()
|
||||||
Schedule::new_frontier()
|
} else {
|
||||||
},
|
Schedule::new_homestead()
|
||||||
_ => {
|
|
||||||
Schedule::new_homestead()
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256) {
|
||||||
header.difficulty = self.calculate_difficuty(header, parent);
|
header.difficulty = self.calculate_difficuty(header, parent);
|
||||||
header.gas_limit = {
|
header.gas_limit = {
|
||||||
let gas_floor_target: U256 = x!(3141562);
|
|
||||||
let gas_limit = parent.gas_limit;
|
let gas_limit = parent.gas_limit;
|
||||||
let bound_divisor = self.u256_param("gasLimitBoundDivisor");
|
let bound_divisor = self.u256_param("gasLimitBoundDivisor");
|
||||||
if gas_limit < gas_floor_target {
|
if gas_limit < gas_floor_target {
|
||||||
@ -109,7 +93,7 @@ impl Engine for Ethash {
|
|||||||
max(gas_floor_target, gas_limit - gas_limit / bound_divisor + x!(1) + (header.gas_used * x!(6) / x!(5)) / bound_divisor)
|
max(gas_floor_target, gas_limit - gas_limit / bound_divisor + x!(1) + (header.gas_used * x!(6) / x!(5)) / bound_divisor)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
header.note_dirty();
|
||||||
// info!("ethash: populate_from_parent #{}: difficulty={} and gas_limit={}", header.number, header.difficulty, header.gas_limit);
|
// info!("ethash: populate_from_parent #{}: difficulty={} and gas_limit={}", header.number, header.difficulty, header.gas_limit);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,9 +131,10 @@ impl Engine for Ethash {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let difficulty = Ethash::boundary_to_difficulty(&Ethash::from_ethash(quick_get_difficulty(
|
let difficulty = Ethash::boundary_to_difficulty(&Ethash::from_ethash(quick_get_difficulty(
|
||||||
&Ethash::to_ethash(header.bare_hash()),
|
&Ethash::to_ethash(header.bare_hash()),
|
||||||
header.nonce().low_u64(),
|
header.nonce().low_u64(),
|
||||||
&Ethash::to_ethash(header.mix_hash()))));
|
&Ethash::to_ethash(header.mix_hash())
|
||||||
|
)));
|
||||||
if difficulty < header.difficulty {
|
if difficulty < header.difficulty {
|
||||||
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty), max: None, found: difficulty })));
|
return Err(From::from(BlockError::InvalidProofOfWork(OutOfBounds { min: Some(header.difficulty), max: None, found: difficulty })));
|
||||||
}
|
}
|
||||||
@ -189,7 +174,7 @@ impl Engine for Ethash {
|
|||||||
let min_gas = parent.gas_limit - parent.gas_limit / gas_limit_divisor;
|
let min_gas = parent.gas_limit - parent.gas_limit / gas_limit_divisor;
|
||||||
let max_gas = parent.gas_limit + parent.gas_limit / gas_limit_divisor;
|
let max_gas = parent.gas_limit + parent.gas_limit / gas_limit_divisor;
|
||||||
if header.gas_limit <= min_gas || header.gas_limit >= max_gas {
|
if header.gas_limit <= min_gas || header.gas_limit >= max_gas {
|
||||||
return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: Some(min_gas), max: Some(max_gas), found: header.gas_limit })));
|
return Err(From::from(BlockError::InvalidGasLimit(OutOfBounds { min: Some(min_gas), max: Some(max_gas), found: header.gas_limit })));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -204,9 +189,19 @@ impl Engine for Ethash {
|
|||||||
fn verify_transaction(&self, t: &SignedTransaction, _header: &Header) -> Result<(), Error> {
|
fn verify_transaction(&self, t: &SignedTransaction, _header: &Header) -> Result<(), Error> {
|
||||||
t.sender().map(|_|()) // Perform EC recovery and cache sender
|
t.sender().map(|_|()) // Perform EC recovery and cache sender
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn u64_param(&self, name: &str) -> u64 {
|
||||||
|
*self.u64_params.write().unwrap().entry(name.to_owned()).or_insert_with(||
|
||||||
|
self.spec().engine_params.get(name).map_or(0u64, |a| decode(&a)))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn u256_param(&self, name: &str) -> U256 {
|
||||||
|
*self.u256_params.write().unwrap().entry(name.to_owned()).or_insert_with(||
|
||||||
|
self.spec().engine_params.get(name).map_or(x!(0), |a| decode(&a)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(wrong_self_convention)] // to_ethash should take self
|
#[cfg_attr(feature="dev", allow(wrong_self_convention))] // to_ethash should take self
|
||||||
impl Ethash {
|
impl Ethash {
|
||||||
fn calculate_difficuty(&self, header: &Header, parent: &Header) -> U256 {
|
fn calculate_difficuty(&self, header: &Header, parent: &Header) -> U256 {
|
||||||
const EXP_DIFF_PERIOD: u64 = 100000;
|
const EXP_DIFF_PERIOD: u64 = 100000;
|
||||||
@ -220,8 +215,8 @@ impl Ethash {
|
|||||||
let frontier_limit = self.u64_param("frontierCompatibilityModeLimit");
|
let frontier_limit = self.u64_param("frontierCompatibilityModeLimit");
|
||||||
let mut target = if header.number < frontier_limit {
|
let mut target = if header.number < frontier_limit {
|
||||||
if header.timestamp >= parent.timestamp + duration_limit {
|
if header.timestamp >= parent.timestamp + duration_limit {
|
||||||
parent.difficulty - (parent.difficulty / difficulty_bound_divisor)
|
parent.difficulty - (parent.difficulty / difficulty_bound_divisor)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parent.difficulty + (parent.difficulty / difficulty_bound_divisor)
|
parent.difficulty + (parent.difficulty / difficulty_bound_divisor)
|
||||||
}
|
}
|
||||||
@ -243,11 +238,22 @@ impl Ethash {
|
|||||||
}
|
}
|
||||||
target
|
target
|
||||||
}
|
}
|
||||||
|
|
||||||
fn boundary_to_difficulty(boundary: &H256) -> U256 {
|
/// Convert an Ethash boundary to its original difficulty. Basically just `f(x) = 2^256 / x`.
|
||||||
|
pub fn boundary_to_difficulty(boundary: &H256) -> U256 {
|
||||||
U256::from((U512::one() << 256) / x!(U256::from(boundary.as_slice())))
|
U256::from((U512::one() << 256) / x!(U256::from(boundary.as_slice())))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`.
|
||||||
|
pub fn difficulty_to_boundary(difficulty: &U256) -> H256 {
|
||||||
|
x!(U256::from((U512::one() << 256) / x!(difficulty)))
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Given the `block_number`, determine the seed hash for Ethash.
|
||||||
|
pub fn get_seedhash(number: BlockNumber) -> H256 {
|
||||||
|
Self::from_ethash(ethash::get_seedhash(number))
|
||||||
|
}
|
||||||
|
|
||||||
fn to_ethash(hash: H256) -> EH256 {
|
fn to_ethash(hash: H256) -> EH256 {
|
||||||
unsafe { mem::transmute(hash) }
|
unsafe { mem::transmute(hash) }
|
||||||
}
|
}
|
||||||
@ -258,12 +264,20 @@ impl Ethash {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Header {
|
impl Header {
|
||||||
fn nonce(&self) -> H64 {
|
/// Get the none field of the header.
|
||||||
|
pub fn nonce(&self) -> H64 {
|
||||||
decode(&self.seal()[1])
|
decode(&self.seal()[1])
|
||||||
}
|
}
|
||||||
fn mix_hash(&self) -> H256 {
|
|
||||||
|
/// Get the mix hash field of the header.
|
||||||
|
pub fn mix_hash(&self) -> H256 {
|
||||||
decode(&self.seal()[0])
|
decode(&self.seal()[0])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the nonce and mix hash fields of the header.
|
||||||
|
pub fn set_nonce_and_mix_hash(&mut self, nonce: &H64, mix_hash: &H256) {
|
||||||
|
self.seal = vec![encode(mix_hash).to_vec(), encode(nonce).to_vec()];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -283,9 +297,9 @@ mod tests {
|
|||||||
let genesis_header = engine.spec().genesis_header();
|
let genesis_header = engine.spec().genesis_header();
|
||||||
let mut db_result = get_temp_journal_db();
|
let mut db_result = get_temp_journal_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
engine.spec().ensure_db_good(&mut db);
|
engine.spec().ensure_db_good(db.as_hashdb_mut());
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
let b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
|
let b = OpenBlock::new(engine.deref(), false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]);
|
||||||
let b = b.close();
|
let b = b.close();
|
||||||
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
|
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
|
||||||
}
|
}
|
||||||
@ -296,9 +310,9 @@ mod tests {
|
|||||||
let genesis_header = engine.spec().genesis_header();
|
let genesis_header = engine.spec().genesis_header();
|
||||||
let mut db_result = get_temp_journal_db();
|
let mut db_result = get_temp_journal_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
engine.spec().ensure_db_good(&mut db);
|
engine.spec().ensure_db_good(db.as_hashdb_mut());
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
let mut b = OpenBlock::new(engine.deref(), db, &genesis_header, &last_hashes, Address::zero(), vec![]);
|
let mut b = OpenBlock::new(engine.deref(), false, db, &genesis_header, last_hashes, Address::zero(), x!(3141562), vec![]);
|
||||||
let mut uncle = Header::new();
|
let mut uncle = Header::new();
|
||||||
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
|
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
|
||||||
uncle.author = uncle_author.clone();
|
uncle.author = uncle_author.clone();
|
||||||
|
@ -61,7 +61,7 @@ mod tests {
|
|||||||
let genesis_header = engine.spec().genesis_header();
|
let genesis_header = engine.spec().genesis_header();
|
||||||
let mut db_result = get_temp_journal_db();
|
let mut db_result = get_temp_journal_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
engine.spec().ensure_db_good(&mut db);
|
engine.spec().ensure_db_good(db.as_hashdb_mut());
|
||||||
let s = State::from_existing(db, genesis_header.state_root.clone(), engine.account_start_nonce());
|
let s = State::from_existing(db, genesis_header.state_root.clone(), engine.account_start_nonce());
|
||||||
assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000001")), U256::from(1u64));
|
assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000001")), U256::from(1u64));
|
||||||
assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000002")), U256::from(1u64));
|
assert_eq!(s.balance(&address_from_hex("0000000000000000000000000000000000000002")), U256::from(1u64));
|
||||||
|
@ -65,7 +65,7 @@ pub enum Error {
|
|||||||
|
|
||||||
/// Evm result.
|
/// Evm result.
|
||||||
///
|
///
|
||||||
/// Returns gas_left if execution is successfull, otherwise error.
|
/// Returns gas_left if execution is successful, otherwise error.
|
||||||
pub type Result = result::Result<U256, Error>;
|
pub type Result = result::Result<U256, Error>;
|
||||||
|
|
||||||
/// Evm interface.
|
/// Evm interface.
|
||||||
|
@ -16,9 +16,7 @@
|
|||||||
|
|
||||||
//! Interface for Evm externalities.
|
//! Interface for Evm externalities.
|
||||||
|
|
||||||
use common::Bytes;
|
use util::common::*;
|
||||||
use util::hash::*;
|
|
||||||
use util::uint::*;
|
|
||||||
use evm::{Schedule, Error};
|
use evm::{Schedule, Error};
|
||||||
use env_info::*;
|
use env_info::*;
|
||||||
|
|
||||||
@ -60,22 +58,23 @@ pub trait Ext {
|
|||||||
fn blockhash(&self, number: &U256) -> H256;
|
fn blockhash(&self, number: &U256) -> H256;
|
||||||
|
|
||||||
/// Creates new contract.
|
/// Creates new contract.
|
||||||
///
|
///
|
||||||
/// Returns gas_left and contract address if contract creation was succesfull.
|
/// Returns gas_left and contract address if contract creation was succesfull.
|
||||||
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult;
|
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult;
|
||||||
|
|
||||||
/// Message call.
|
/// Message call.
|
||||||
///
|
///
|
||||||
/// Returns Err, if we run out of gas.
|
/// Returns Err, if we run out of gas.
|
||||||
/// Otherwise returns call_result which contains gas left
|
/// Otherwise returns call_result which contains gas left
|
||||||
/// and true if subcall was successfull.
|
/// and true if subcall was successfull.
|
||||||
fn call(&mut self,
|
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
||||||
gas: &U256,
|
fn call(&mut self,
|
||||||
sender_address: &Address,
|
gas: &U256,
|
||||||
receive_address: &Address,
|
sender_address: &Address,
|
||||||
|
receive_address: &Address,
|
||||||
value: Option<U256>,
|
value: Option<U256>,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
code_address: &Address,
|
code_address: &Address,
|
||||||
output: &mut [u8]) -> MessageCallResult;
|
output: &mut [u8]) -> MessageCallResult;
|
||||||
|
|
||||||
/// Returns code at given address
|
/// Returns code at given address
|
||||||
@ -99,7 +98,7 @@ pub trait Ext {
|
|||||||
fn env_info(&self) -> &EnvInfo;
|
fn env_info(&self) -> &EnvInfo;
|
||||||
|
|
||||||
/// Returns current depth of execution.
|
/// Returns current depth of execution.
|
||||||
///
|
///
|
||||||
/// If contract A calls contract B, and contract B calls C,
|
/// If contract A calls contract B, and contract B calls C,
|
||||||
/// then A depth is 0, B is 1, C is 2 and so on.
|
/// then A depth is 0, B is 1, C is 2 and so on.
|
||||||
fn depth(&self) -> usize;
|
fn depth(&self) -> usize;
|
||||||
|
@ -25,7 +25,7 @@ use evm::Evm;
|
|||||||
/// Type of EVM to use.
|
/// Type of EVM to use.
|
||||||
pub enum VMType {
|
pub enum VMType {
|
||||||
/// JIT EVM
|
/// JIT EVM
|
||||||
#[cfg(feature="jit")]
|
#[cfg(feature = "jit")]
|
||||||
Jit,
|
Jit,
|
||||||
/// RUST EVM
|
/// RUST EVM
|
||||||
Interpreter
|
Interpreter
|
||||||
@ -52,13 +52,13 @@ impl fmt::Display for VMType {
|
|||||||
#[cfg(feature = "json-tests")]
|
#[cfg(feature = "json-tests")]
|
||||||
impl VMType {
|
impl VMType {
|
||||||
/// Return all possible VMs (JIT, Interpreter)
|
/// Return all possible VMs (JIT, Interpreter)
|
||||||
#[cfg(feature="jit")]
|
#[cfg(feature = "jit")]
|
||||||
pub fn all() -> Vec<VMType> {
|
pub fn all() -> Vec<VMType> {
|
||||||
vec![VMType::Jit, VMType::Interpreter]
|
vec![VMType::Jit, VMType::Interpreter]
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return all possible VMs (Interpreter)
|
/// Return all possible VMs (Interpreter)
|
||||||
#[cfg(not(feature="jit"))]
|
#[cfg(not(feature = "jit"))]
|
||||||
pub fn all() -> Vec<VMType> {
|
pub fn all() -> Vec<VMType> {
|
||||||
vec![VMType::Interpreter]
|
vec![VMType::Interpreter]
|
||||||
}
|
}
|
||||||
@ -66,12 +66,12 @@ impl VMType {
|
|||||||
|
|
||||||
/// Evm factory. Creates appropriate Evm.
|
/// Evm factory. Creates appropriate Evm.
|
||||||
pub struct Factory {
|
pub struct Factory {
|
||||||
evm : VMType
|
evm: VMType
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Factory {
|
impl Factory {
|
||||||
/// Create fresh instance of VM
|
/// Create fresh instance of VM
|
||||||
#[cfg(feature="jit")]
|
#[cfg(feature = "jit")]
|
||||||
pub fn create(&self) -> Box<Evm> {
|
pub fn create(&self) -> Box<Evm> {
|
||||||
match self.evm {
|
match self.evm {
|
||||||
VMType::Jit => {
|
VMType::Jit => {
|
||||||
@ -84,7 +84,7 @@ impl Factory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create fresh instance of VM
|
/// Create fresh instance of VM
|
||||||
#[cfg(not(feature="jit"))]
|
#[cfg(not(feature = "jit"))]
|
||||||
pub fn create(&self) -> Box<Evm> {
|
pub fn create(&self) -> Box<Evm> {
|
||||||
match self.evm {
|
match self.evm {
|
||||||
VMType::Interpreter => {
|
VMType::Interpreter => {
|
||||||
|
@ -243,7 +243,7 @@ struct CodeReader<'a> {
|
|||||||
code: &'a Bytes
|
code: &'a Bytes
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(len_without_is_empty)]
|
#[cfg_attr(feature="dev", allow(len_without_is_empty))]
|
||||||
impl<'a> CodeReader<'a> {
|
impl<'a> CodeReader<'a> {
|
||||||
/// Get `no_of_bytes` from code and convert to U256. Move PC
|
/// Get `no_of_bytes` from code and convert to U256. Move PC
|
||||||
fn read(&mut self, no_of_bytes: usize) -> U256 {
|
fn read(&mut self, no_of_bytes: usize) -> U256 {
|
||||||
@ -258,7 +258,7 @@ impl<'a> CodeReader<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(enum_variant_names)]
|
#[cfg_attr(feature="dev", allow(enum_variant_names))]
|
||||||
enum InstructionCost {
|
enum InstructionCost {
|
||||||
Gas(U256),
|
Gas(U256),
|
||||||
GasMem(U256, U256),
|
GasMem(U256, U256),
|
||||||
@ -299,7 +299,7 @@ impl evm::Evm for Interpreter {
|
|||||||
let (gas_cost, mem_size) = try!(self.get_gas_cost_mem(ext, instruction, &mut mem, &stack));
|
let (gas_cost, mem_size) = try!(self.get_gas_cost_mem(ext, instruction, &mut mem, &stack));
|
||||||
try!(self.verify_gas(¤t_gas, &gas_cost));
|
try!(self.verify_gas(¤t_gas, &gas_cost));
|
||||||
mem.expand(mem_size);
|
mem.expand(mem_size);
|
||||||
current_gas -= gas_cost;
|
current_gas = current_gas - gas_cost; //TODO: use operator -=
|
||||||
|
|
||||||
evm_debug!({
|
evm_debug!({
|
||||||
println!("[0x{:x}][{}(0x{:x}) Gas: {:x}\n Gas Before: {:x}",
|
println!("[0x{:x}][{}(0x{:x}) Gas: {:x}\n Gas Before: {:x}",
|
||||||
@ -320,7 +320,7 @@ impl evm::Evm for Interpreter {
|
|||||||
match result {
|
match result {
|
||||||
InstructionResult::Ok => {},
|
InstructionResult::Ok => {},
|
||||||
InstructionResult::UnusedGas(gas) => {
|
InstructionResult::UnusedGas(gas) => {
|
||||||
current_gas += gas;
|
current_gas = current_gas + gas; //TODO: use operator +=
|
||||||
},
|
},
|
||||||
InstructionResult::UseAllGas => {
|
InstructionResult::UseAllGas => {
|
||||||
current_gas = U256::zero();
|
current_gas = U256::zero();
|
||||||
@ -347,13 +347,14 @@ impl evm::Evm for Interpreter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Interpreter {
|
impl Interpreter {
|
||||||
#[allow(cyclomatic_complexity)]
|
#[cfg_attr(feature="dev", allow(cyclomatic_complexity))]
|
||||||
fn get_gas_cost_mem(&self,
|
fn get_gas_cost_mem(
|
||||||
ext: &evm::Ext,
|
&self,
|
||||||
instruction: Instruction,
|
ext: &evm::Ext,
|
||||||
mem: &mut Memory,
|
instruction: Instruction,
|
||||||
stack: &Stack<U256>
|
mem: &mut Memory,
|
||||||
) -> Result<(U256, usize), evm::Error> {
|
stack: &Stack<U256>
|
||||||
|
) -> Result<(U256, usize), evm::Error> {
|
||||||
let schedule = ext.schedule();
|
let schedule = ext.schedule();
|
||||||
let info = instructions::get_info(instruction);
|
let info = instructions::get_info(instruction);
|
||||||
|
|
||||||
@ -521,15 +522,17 @@ impl Interpreter {
|
|||||||
Ok(overflowing!(offset.overflowing_add(size.clone())))
|
Ok(overflowing!(offset.overflowing_add(size.clone())))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec_instruction(&self,
|
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
||||||
gas: Gas,
|
fn exec_instruction(
|
||||||
params: &ActionParams,
|
&self,
|
||||||
ext: &mut evm::Ext,
|
gas: Gas,
|
||||||
instruction: Instruction,
|
params: &ActionParams,
|
||||||
code: &mut CodeReader,
|
ext: &mut evm::Ext,
|
||||||
mem: &mut Memory,
|
instruction: Instruction,
|
||||||
stack: &mut Stack<U256>
|
code: &mut CodeReader,
|
||||||
) -> Result<InstructionResult, evm::Error> {
|
mem: &mut Memory,
|
||||||
|
stack: &mut Stack<U256>
|
||||||
|
) -> Result<InstructionResult, evm::Error> {
|
||||||
match instruction {
|
match instruction {
|
||||||
instructions::JUMP => {
|
instructions::JUMP => {
|
||||||
let jump = stack.pop_back();
|
let jump = stack.pop_back();
|
||||||
@ -581,9 +584,10 @@ impl Interpreter {
|
|||||||
let code_address = stack.pop_back();
|
let code_address = stack.pop_back();
|
||||||
let code_address = u256_to_address(&code_address);
|
let code_address = u256_to_address(&code_address);
|
||||||
|
|
||||||
let value = match instruction == instructions::DELEGATECALL {
|
let value = if instruction == instructions::DELEGATECALL {
|
||||||
true => None,
|
None
|
||||||
false => Some(stack.pop_back())
|
} else {
|
||||||
|
Some(stack.pop_back())
|
||||||
};
|
};
|
||||||
|
|
||||||
let in_off = stack.pop_back();
|
let in_off = stack.pop_back();
|
||||||
|
@ -25,9 +25,8 @@ struct FakeLogEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Debug)]
|
#[derive(PartialEq, Eq, Hash, Debug)]
|
||||||
#[allow(enum_variant_names)] // Common prefix is C ;)
|
|
||||||
enum FakeCallType {
|
enum FakeCallType {
|
||||||
CALL, CREATE
|
Call, Create
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Hash, Debug)]
|
#[derive(PartialEq, Eq, Hash, Debug)]
|
||||||
@ -56,7 +55,7 @@ struct FakeExt {
|
|||||||
info: EnvInfo,
|
info: EnvInfo,
|
||||||
schedule: Schedule,
|
schedule: Schedule,
|
||||||
balances: HashMap<Address, U256>,
|
balances: HashMap<Address, U256>,
|
||||||
calls: HashSet<FakeCall>
|
calls: HashSet<FakeCall>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FakeExt {
|
impl FakeExt {
|
||||||
@ -94,7 +93,7 @@ impl Ext for FakeExt {
|
|||||||
|
|
||||||
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult {
|
fn create(&mut self, gas: &U256, value: &U256, code: &[u8]) -> ContractCreateResult {
|
||||||
self.calls.insert(FakeCall {
|
self.calls.insert(FakeCall {
|
||||||
call_type: FakeCallType::CREATE,
|
call_type: FakeCallType::Create,
|
||||||
gas: *gas,
|
gas: *gas,
|
||||||
sender_address: None,
|
sender_address: None,
|
||||||
receive_address: None,
|
receive_address: None,
|
||||||
@ -115,7 +114,7 @@ impl Ext for FakeExt {
|
|||||||
_output: &mut [u8]) -> MessageCallResult {
|
_output: &mut [u8]) -> MessageCallResult {
|
||||||
|
|
||||||
self.calls.insert(FakeCall {
|
self.calls.insert(FakeCall {
|
||||||
call_type: FakeCallType::CALL,
|
call_type: FakeCallType::Call,
|
||||||
gas: *gas,
|
gas: *gas,
|
||||||
sender_address: Some(sender_address.clone()),
|
sender_address: Some(sender_address.clone()),
|
||||||
receive_address: Some(receive_address.clone()),
|
receive_address: Some(receive_address.clone()),
|
||||||
@ -347,7 +346,7 @@ fn test_log_empty(factory: super::Factory) {
|
|||||||
assert_eq!(gas_left, U256::from(99_619));
|
assert_eq!(gas_left, U256::from(99_619));
|
||||||
assert_eq!(ext.logs.len(), 1);
|
assert_eq!(ext.logs.len(), 1);
|
||||||
assert_eq!(ext.logs[0].topics.len(), 0);
|
assert_eq!(ext.logs[0].topics.len(), 0);
|
||||||
assert_eq!(ext.logs[0].data, vec![]);
|
assert!(ext.logs[0].data.is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
evm_test!{test_log_sender: test_log_sender_jit, test_log_sender_int}
|
evm_test!{test_log_sender: test_log_sender_jit, test_log_sender_int}
|
||||||
@ -909,7 +908,7 @@ fn test_calls(factory: super::Factory) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
assert_set_contains(&ext.calls, &FakeCall {
|
assert_set_contains(&ext.calls, &FakeCall {
|
||||||
call_type: FakeCallType::CALL,
|
call_type: FakeCallType::Call,
|
||||||
gas: U256::from(2556),
|
gas: U256::from(2556),
|
||||||
sender_address: Some(address.clone()),
|
sender_address: Some(address.clone()),
|
||||||
receive_address: Some(code_address.clone()),
|
receive_address: Some(code_address.clone()),
|
||||||
@ -918,7 +917,7 @@ fn test_calls(factory: super::Factory) {
|
|||||||
code_address: Some(code_address.clone())
|
code_address: Some(code_address.clone())
|
||||||
});
|
});
|
||||||
assert_set_contains(&ext.calls, &FakeCall {
|
assert_set_contains(&ext.calls, &FakeCall {
|
||||||
call_type: FakeCallType::CALL,
|
call_type: FakeCallType::Call,
|
||||||
gas: U256::from(2556),
|
gas: U256::from(2556),
|
||||||
sender_address: Some(address.clone()),
|
sender_address: Some(address.clone()),
|
||||||
receive_address: Some(address.clone()),
|
receive_address: Some(address.clone()),
|
||||||
|
@ -37,30 +37,39 @@ pub fn contract_address(address: &Address, nonce: &U256) -> Address {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Transaction execution receipt.
|
/// Transaction execution receipt.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, PartialEq, Clone)]
|
||||||
pub struct Executed {
|
pub struct Executed {
|
||||||
/// Gas paid up front for execution of transaction.
|
/// Gas paid up front for execution of transaction.
|
||||||
pub gas: U256,
|
pub gas: U256,
|
||||||
|
|
||||||
/// Gas used during execution of transaction.
|
/// Gas used during execution of transaction.
|
||||||
pub gas_used: U256,
|
pub gas_used: U256,
|
||||||
|
|
||||||
/// Gas refunded after the execution of transaction.
|
/// Gas refunded after the execution of transaction.
|
||||||
/// To get gas that was required up front, add `refunded` and `gas_used`.
|
/// To get gas that was required up front, add `refunded` and `gas_used`.
|
||||||
pub refunded: U256,
|
pub refunded: U256,
|
||||||
|
|
||||||
/// Cumulative gas used in current block so far.
|
/// Cumulative gas used in current block so far.
|
||||||
///
|
///
|
||||||
/// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)`
|
/// `cumulative_gas_used = gas_used(t0) + gas_used(t1) + ... gas_used(tn)`
|
||||||
///
|
///
|
||||||
/// where `tn` is current transaction.
|
/// where `tn` is current transaction.
|
||||||
pub cumulative_gas_used: U256,
|
pub cumulative_gas_used: U256,
|
||||||
|
|
||||||
/// Vector of logs generated by transaction.
|
/// Vector of logs generated by transaction.
|
||||||
pub logs: Vec<LogEntry>,
|
pub logs: Vec<LogEntry>,
|
||||||
|
|
||||||
/// Addresses of contracts created during execution of transaction.
|
/// Addresses of contracts created during execution of transaction.
|
||||||
/// Ordered from earliest creation.
|
/// Ordered from earliest creation.
|
||||||
///
|
///
|
||||||
/// eg. sender creates contract A and A in constructor creates contract B
|
/// eg. sender creates contract A and A in constructor creates contract B
|
||||||
///
|
///
|
||||||
/// B creation ends first, and it will be the first element of the vector.
|
/// B creation ends first, and it will be the first element of the vector.
|
||||||
pub contracts_created: Vec<Address>
|
pub contracts_created: Vec<Address>,
|
||||||
|
/// Transaction output.
|
||||||
|
pub output: Bytes,
|
||||||
|
/// The trace of this transaction.
|
||||||
|
pub trace: Option<Trace>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transaction execution result.
|
/// Transaction execution result.
|
||||||
@ -71,38 +80,37 @@ pub struct Executive<'a> {
|
|||||||
state: &'a mut State,
|
state: &'a mut State,
|
||||||
info: &'a EnvInfo,
|
info: &'a EnvInfo,
|
||||||
engine: &'a Engine,
|
engine: &'a Engine,
|
||||||
depth: usize
|
depth: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Executive<'a> {
|
impl<'a> Executive<'a> {
|
||||||
/// Basic constructor.
|
/// Basic constructor.
|
||||||
pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine) -> Self {
|
pub fn new(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine) -> Self {
|
||||||
Executive::new_with_depth(state, info, engine, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Populates executive from parent properties. Increments executive depth.
|
|
||||||
pub fn from_parent(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize) -> Self {
|
|
||||||
Executive::new_with_depth(state, info, engine, depth + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Helper constructor. Should be used to create `Executive` with desired depth.
|
|
||||||
/// Private.
|
|
||||||
fn new_with_depth(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, depth: usize) -> Self {
|
|
||||||
Executive {
|
Executive {
|
||||||
state: state,
|
state: state,
|
||||||
info: info,
|
info: info,
|
||||||
engine: engine,
|
engine: engine,
|
||||||
depth: depth
|
depth: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Populates executive from parent properties. Increments executive depth.
|
||||||
|
pub fn from_parent(state: &'a mut State, info: &'a EnvInfo, engine: &'a Engine, parent_depth: usize) -> Self {
|
||||||
|
Executive {
|
||||||
|
state: state,
|
||||||
|
info: info,
|
||||||
|
engine: engine,
|
||||||
|
depth: parent_depth + 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates `Externalities` from `Executive`.
|
/// Creates `Externalities` from `Executive`.
|
||||||
pub fn as_externalities<'_>(&'_ mut self, origin_info: OriginInfo, substate: &'_ mut Substate, output: OutputPolicy<'_>) -> Externalities {
|
pub fn as_externalities<'_>(&'_ mut self, origin_info: OriginInfo, substate: &'_ mut Substate, output: OutputPolicy<'_, '_>) -> Externalities {
|
||||||
Externalities::new(self.state, self.info, self.engine, self.depth, origin_info, substate, output)
|
Externalities::new(self.state, self.info, self.engine, self.depth, origin_info, substate, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This funtion should be used to execute transaction.
|
/// This funtion should be used to execute transaction.
|
||||||
pub fn transact(&'a mut self, t: &SignedTransaction) -> Result<Executed, Error> {
|
pub fn transact(&'a mut self, t: &SignedTransaction, tracing: bool) -> Result<Executed, Error> {
|
||||||
let sender = try!(t.sender());
|
let sender = try!(t.sender());
|
||||||
let nonce = self.state.nonce(&sender);
|
let nonce = self.state.nonce(&sender);
|
||||||
|
|
||||||
@ -143,9 +151,9 @@ impl<'a> Executive<'a> {
|
|||||||
self.state.inc_nonce(&sender);
|
self.state.inc_nonce(&sender);
|
||||||
self.state.sub_balance(&sender, &U256::from(gas_cost));
|
self.state.sub_balance(&sender, &U256::from(gas_cost));
|
||||||
|
|
||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new(tracing);
|
||||||
|
|
||||||
let res = match t.action {
|
let (gas_left, output) = match t.action {
|
||||||
Action::Create => {
|
Action::Create => {
|
||||||
let new_address = contract_address(&sender, &nonce);
|
let new_address = contract_address(&sender, &nonce);
|
||||||
let params = ActionParams {
|
let params = ActionParams {
|
||||||
@ -159,7 +167,7 @@ impl<'a> Executive<'a> {
|
|||||||
code: Some(t.data.clone()),
|
code: Some(t.data.clone()),
|
||||||
data: None,
|
data: None,
|
||||||
};
|
};
|
||||||
self.create(params, &mut substate)
|
(self.create(params, &mut substate), vec![])
|
||||||
},
|
},
|
||||||
Action::Call(ref address) => {
|
Action::Call(ref address) => {
|
||||||
let params = ActionParams {
|
let params = ActionParams {
|
||||||
@ -175,12 +183,12 @@ impl<'a> Executive<'a> {
|
|||||||
};
|
};
|
||||||
// TODO: move output upstream
|
// TODO: move output upstream
|
||||||
let mut out = vec![];
|
let mut out = vec![];
|
||||||
self.call(params, &mut substate, BytesRef::Flexible(&mut out))
|
(self.call(params, &mut substate, BytesRef::Flexible(&mut out)), out)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// finalize here!
|
// finalize here!
|
||||||
Ok(try!(self.finalize(t, substate, res)))
|
Ok(try!(self.finalize(t, substate, gas_left, output)))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn exec_vm(&mut self, params: ActionParams, unconfirmed_substate: &mut Substate, output_policy: OutputPolicy) -> evm::Result {
|
fn exec_vm(&mut self, params: ActionParams, unconfirmed_substate: &mut Substate, output_policy: OutputPolicy) -> evm::Result {
|
||||||
@ -188,6 +196,7 @@ impl<'a> Executive<'a> {
|
|||||||
if (self.depth + 1) % MAX_VM_DEPTH_FOR_THREAD != 0 {
|
if (self.depth + 1) % MAX_VM_DEPTH_FOR_THREAD != 0 {
|
||||||
let mut ext = self.as_externalities(OriginInfo::from(¶ms), unconfirmed_substate, output_policy);
|
let mut ext = self.as_externalities(OriginInfo::from(¶ms), unconfirmed_substate, output_policy);
|
||||||
let vm_factory = self.engine.vm_factory();
|
let vm_factory = self.engine.vm_factory();
|
||||||
|
trace!(target: "executive", "ext.schedule.have_delegate_call: {}", ext.schedule().have_delegate_call);
|
||||||
return vm_factory.create().exec(params, &mut ext);
|
return vm_factory.create().exec(params, &mut ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,25 +246,49 @@ impl<'a> Executive<'a> {
|
|||||||
Err(evm::Error::OutOfGas)
|
Err(evm::Error::OutOfGas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if params.code.is_some() {
|
|
||||||
// if destination is a contract, do normal message call
|
|
||||||
|
|
||||||
// part of substate that may be reverted
|
|
||||||
let mut unconfirmed_substate = Substate::new();
|
|
||||||
|
|
||||||
let res = {
|
|
||||||
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::Return(output))
|
|
||||||
};
|
|
||||||
|
|
||||||
trace!("exec: sstore-clears={}\n", unconfirmed_substate.sstore_clears_count);
|
|
||||||
trace!("exec: substate={:?}; unconfirmed_substate={:?}\n", substate, unconfirmed_substate);
|
|
||||||
self.enact_result(&res, substate, unconfirmed_substate);
|
|
||||||
trace!("exec: new substate={:?}\n", substate);
|
|
||||||
res
|
|
||||||
} else {
|
} else {
|
||||||
// otherwise, nothing
|
// if destination is a contract, do normal message call
|
||||||
self.state.clear_snapshot();
|
|
||||||
Ok(params.gas)
|
// don't trace if it's DELEGATECALL or CALLCODE.
|
||||||
|
let should_trace = if let ActionValue::Transfer(_) = params.value {
|
||||||
|
params.code_address == params.address && substate.subtraces.is_some()
|
||||||
|
} else { false };
|
||||||
|
|
||||||
|
// transaction tracing stuff. None if there's no tracing.
|
||||||
|
let (mut trace_info, mut trace_output) = if should_trace {
|
||||||
|
(Some((TraceAction::from_call(¶ms), self.depth)), Some(vec![]))
|
||||||
|
} else { (None, None) };
|
||||||
|
|
||||||
|
if params.code.is_some() {
|
||||||
|
// part of substate that may be reverted
|
||||||
|
let mut unconfirmed_substate = Substate::new(should_trace);
|
||||||
|
|
||||||
|
let res = {
|
||||||
|
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::Return(output, trace_output.as_mut()))
|
||||||
|
};
|
||||||
|
|
||||||
|
trace!(target: "executive", "res={:?}", res);
|
||||||
|
|
||||||
|
// if there's tracing, make up trace_info's result with trace_output and some arithmetic.
|
||||||
|
if let Some((TraceAction::Call(ref mut c), _)) = trace_info {
|
||||||
|
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, trace_output.expect("trace_info is Some: so should_trace: qed")));
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!(target: "executive", "substate={:?}; unconfirmed_substate={:?}\n", substate, unconfirmed_substate);
|
||||||
|
|
||||||
|
self.enact_result(&res, substate, unconfirmed_substate, trace_info);
|
||||||
|
trace!(target: "executive", "enacted: substate={:?}\n", substate);
|
||||||
|
res
|
||||||
|
} else {
|
||||||
|
// otherwise it's just a basic transaction, only do tracing, if necessary.
|
||||||
|
trace!(target: "executive", "Basic message (send funds) should_trace={}", should_trace);
|
||||||
|
self.state.clear_snapshot();
|
||||||
|
if let Some((TraceAction::Call(ref mut c), _)) = trace_info {
|
||||||
|
c.result = Some((x!(0), vec![]));
|
||||||
|
}
|
||||||
|
substate.accrue_trace(if should_trace {Some(vec![])} else {None}, trace_info);
|
||||||
|
Ok(params.gas)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +300,7 @@ impl<'a> Executive<'a> {
|
|||||||
self.state.snapshot();
|
self.state.snapshot();
|
||||||
|
|
||||||
// part of substate that may be reverted
|
// part of substate that may be reverted
|
||||||
let mut unconfirmed_substate = Substate::new();
|
let mut unconfirmed_substate = Substate::new(substate.subtraces.is_some());
|
||||||
|
|
||||||
// create contract and transfer value to it if necessary
|
// create contract and transfer value to it if necessary
|
||||||
let prev_bal = self.state.balance(¶ms.address);
|
let prev_bal = self.state.balance(¶ms.address);
|
||||||
@ -278,15 +311,26 @@ impl<'a> Executive<'a> {
|
|||||||
self.state.new_contract(¶ms.address, prev_bal);
|
self.state.new_contract(¶ms.address, prev_bal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let mut trace_info = substate.subtraces.as_ref().map(|_| (TraceAction::from_create(¶ms), self.depth));
|
||||||
|
let mut trace_output = trace_info.as_ref().map(|_| vec![]);
|
||||||
|
let created = params.address.clone();
|
||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::InitContract)
|
self.exec_vm(params, &mut unconfirmed_substate, OutputPolicy::InitContract(trace_output.as_mut()))
|
||||||
};
|
};
|
||||||
self.enact_result(&res, substate, unconfirmed_substate);
|
|
||||||
|
if let Some((TraceAction::Create(ref mut c), _)) = trace_info {
|
||||||
|
c.result = res.as_ref().ok().map(|gas_left| (c.gas - *gas_left, created, trace_output.expect("trace_info is Some: qed")));
|
||||||
|
}
|
||||||
|
|
||||||
|
trace!(target: "executive", "trace_info={:?}", trace_info);
|
||||||
|
|
||||||
|
self.enact_result(&res, substate, unconfirmed_substate, trace_info);
|
||||||
res
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finalizes the transaction (does refunds and suicides).
|
/// Finalizes the transaction (does refunds and suicides).
|
||||||
fn finalize(&mut self, t: &SignedTransaction, substate: Substate, result: evm::Result) -> ExecutionResult {
|
fn finalize(&mut self, t: &SignedTransaction, substate: Substate, result: evm::Result, output: Bytes) -> ExecutionResult {
|
||||||
let schedule = self.engine.schedule(self.info);
|
let schedule = self.engine.schedule(self.info);
|
||||||
|
|
||||||
// refunds from SSTORE nonzero -> zero
|
// refunds from SSTORE nonzero -> zero
|
||||||
@ -317,6 +361,8 @@ impl<'a> Executive<'a> {
|
|||||||
self.state.kill_account(address);
|
self.state.kill_account(address);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let trace = substate.subtraces.and_then(|mut v| v.pop());
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
|
Err(evm::Error::Internal) => Err(ExecutionError::Internal),
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
@ -326,7 +372,9 @@ impl<'a> Executive<'a> {
|
|||||||
refunded: U256::zero(),
|
refunded: U256::zero(),
|
||||||
cumulative_gas_used: self.info.gas_used + t.gas,
|
cumulative_gas_used: self.info.gas_used + t.gas,
|
||||||
logs: vec![],
|
logs: vec![],
|
||||||
contracts_created: vec![]
|
contracts_created: vec![],
|
||||||
|
output: output,
|
||||||
|
trace: trace,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
@ -337,12 +385,14 @@ impl<'a> Executive<'a> {
|
|||||||
cumulative_gas_used: self.info.gas_used + gas_used,
|
cumulative_gas_used: self.info.gas_used + gas_used,
|
||||||
logs: substate.logs,
|
logs: substate.logs,
|
||||||
contracts_created: substate.contracts_created,
|
contracts_created: substate.contracts_created,
|
||||||
|
output: output,
|
||||||
|
trace: trace,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enact_result(&mut self, result: &evm::Result, substate: &mut Substate, un_substate: Substate) {
|
fn enact_result(&mut self, result: &evm::Result, substate: &mut Substate, un_substate: Substate, maybe_info: Option<(TraceAction, usize)>) {
|
||||||
match *result {
|
match *result {
|
||||||
Err(evm::Error::OutOfGas)
|
Err(evm::Error::OutOfGas)
|
||||||
| Err(evm::Error::BadJumpDestination {..})
|
| Err(evm::Error::BadJumpDestination {..})
|
||||||
@ -350,10 +400,11 @@ impl<'a> Executive<'a> {
|
|||||||
| Err(evm::Error::StackUnderflow {..})
|
| Err(evm::Error::StackUnderflow {..})
|
||||||
| Err(evm::Error::OutOfStack {..}) => {
|
| Err(evm::Error::OutOfStack {..}) => {
|
||||||
self.state.revert_snapshot();
|
self.state.revert_snapshot();
|
||||||
|
substate.accrue_trace(un_substate.subtraces, maybe_info)
|
||||||
},
|
},
|
||||||
Ok(_) | Err(evm::Error::Internal) => {
|
Ok(_) | Err(evm::Error::Internal) => {
|
||||||
self.state.clear_snapshot();
|
self.state.clear_snapshot();
|
||||||
substate.accrue(un_substate)
|
substate.accrue(un_substate, maybe_info)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -391,7 +442,7 @@ mod tests {
|
|||||||
state.add_balance(&sender, &U256::from(0x100u64));
|
state.add_balance(&sender, &U256::from(0x100u64));
|
||||||
let info = EnvInfo::default();
|
let info = EnvInfo::default();
|
||||||
let engine = TestEngine::new(0, factory);
|
let engine = TestEngine::new(0, factory);
|
||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new(false);
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
@ -408,8 +459,8 @@ mod tests {
|
|||||||
// TODO: just test state root.
|
// TODO: just test state root.
|
||||||
}
|
}
|
||||||
|
|
||||||
evm_test!{test_create_contract: test_create_contract_jit, test_create_contract_int}
|
evm_test!{test_create_contract_out_of_depth: test_create_contract_out_of_depth_jit, test_create_contract_out_of_depth_int}
|
||||||
fn test_create_contract(factory: Factory) {
|
fn test_create_contract_out_of_depth(factory: Factory) {
|
||||||
// code:
|
// code:
|
||||||
//
|
//
|
||||||
// 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes?
|
// 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes?
|
||||||
@ -450,7 +501,7 @@ mod tests {
|
|||||||
state.add_balance(&sender, &U256::from(100));
|
state.add_balance(&sender, &U256::from(100));
|
||||||
let info = EnvInfo::default();
|
let info = EnvInfo::default();
|
||||||
let engine = TestEngine::new(0, factory);
|
let engine = TestEngine::new(0, factory);
|
||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new(false);
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
@ -462,6 +513,137 @@ mod tests {
|
|||||||
assert_eq!(substate.contracts_created.len(), 0);
|
assert_eq!(substate.contracts_created.len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
evm_test!{test_call_to_create: test_call_to_create_jit, test_call_to_create_int}
|
||||||
|
fn test_call_to_create(factory: Factory) {
|
||||||
|
// code:
|
||||||
|
//
|
||||||
|
// 7c 601080600c6000396000f3006000355415600957005b60203560003555 - push 29 bytes?
|
||||||
|
// 60 00 - push 0
|
||||||
|
// 52
|
||||||
|
// 60 1d - push 29
|
||||||
|
// 60 03 - push 3
|
||||||
|
// 60 17 - push 17
|
||||||
|
// f0 - create
|
||||||
|
// 60 00 - push 0
|
||||||
|
// 55 sstore
|
||||||
|
//
|
||||||
|
// other code:
|
||||||
|
//
|
||||||
|
// 60 10 - push 16
|
||||||
|
// 80 - duplicate first stack item
|
||||||
|
// 60 0c - push 12
|
||||||
|
// 60 00 - push 0
|
||||||
|
// 39 - copy current code to memory
|
||||||
|
// 60 00 - push 0
|
||||||
|
// f3 - return
|
||||||
|
|
||||||
|
let code = "7c601080600c6000396000f3006000355415600957005b60203560003555600052601d60036017f0600055".from_hex().unwrap();
|
||||||
|
|
||||||
|
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
|
let address = contract_address(&sender, &U256::zero());
|
||||||
|
// TODO: add tests for 'callcreate'
|
||||||
|
//let next_address = contract_address(&address, &U256::zero());
|
||||||
|
let mut params = ActionParams::default();
|
||||||
|
params.address = address.clone();
|
||||||
|
params.code_address = address.clone();
|
||||||
|
params.sender = sender.clone();
|
||||||
|
params.origin = sender.clone();
|
||||||
|
params.gas = U256::from(100_000);
|
||||||
|
params.code = Some(code.clone());
|
||||||
|
params.value = ActionValue::Transfer(U256::from(100));
|
||||||
|
let mut state_result = get_temp_state();
|
||||||
|
let mut state = state_result.reference_mut();
|
||||||
|
state.add_balance(&sender, &U256::from(100));
|
||||||
|
let info = EnvInfo::default();
|
||||||
|
let engine = TestEngine::new(5, factory);
|
||||||
|
let mut substate = Substate::new(true);
|
||||||
|
|
||||||
|
let gas_left = {
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
|
let output = BytesRef::Fixed(&mut[0u8;0]);
|
||||||
|
ex.call(params, &mut substate, output).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("trace: {:?}", substate.subtraces);
|
||||||
|
let expected_trace = Some(vec![ Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("cd1722f3947def4cf144679da39c4c32bdc35681"),
|
||||||
|
to: x!("b010143a42d5980c7e5ef0e4a4416dc098a4fed3"),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(100000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(55248), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![Trace {
|
||||||
|
depth: 1,
|
||||||
|
action: TraceAction::Create(TraceCreate {
|
||||||
|
from: x!("b010143a42d5980c7e5ef0e4a4416dc098a4fed3"),
|
||||||
|
value: x!(23),
|
||||||
|
gas: x!(67979),
|
||||||
|
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85],
|
||||||
|
result: Some((x!(3224), x!("c6d80f262ae5e0f164e5fde365044d7ada2bfa34"), vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53])),
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
}]
|
||||||
|
} ]);
|
||||||
|
assert_eq!(substate.subtraces, expected_trace);
|
||||||
|
assert_eq!(gas_left, U256::from(44_752));
|
||||||
|
}
|
||||||
|
|
||||||
|
evm_test!{test_create_contract: test_create_contract_jit, test_create_contract_int}
|
||||||
|
fn test_create_contract(factory: Factory) {
|
||||||
|
// code:
|
||||||
|
//
|
||||||
|
// 60 10 - push 16
|
||||||
|
// 80 - duplicate first stack item
|
||||||
|
// 60 0c - push 12
|
||||||
|
// 60 00 - push 0
|
||||||
|
// 39 - copy current code to memory
|
||||||
|
// 60 00 - push 0
|
||||||
|
// f3 - return
|
||||||
|
|
||||||
|
let code = "601080600c6000396000f3006000355415600957005b60203560003555".from_hex().unwrap();
|
||||||
|
|
||||||
|
let sender = Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap();
|
||||||
|
let address = contract_address(&sender, &U256::zero());
|
||||||
|
// TODO: add tests for 'callcreate'
|
||||||
|
//let next_address = contract_address(&address, &U256::zero());
|
||||||
|
let mut params = ActionParams::default();
|
||||||
|
params.address = address.clone();
|
||||||
|
params.sender = sender.clone();
|
||||||
|
params.origin = sender.clone();
|
||||||
|
params.gas = U256::from(100_000);
|
||||||
|
params.code = Some(code.clone());
|
||||||
|
params.value = ActionValue::Transfer(x!(100));
|
||||||
|
let mut state_result = get_temp_state();
|
||||||
|
let mut state = state_result.reference_mut();
|
||||||
|
state.add_balance(&sender, &U256::from(100));
|
||||||
|
let info = EnvInfo::default();
|
||||||
|
let engine = TestEngine::new(5, factory);
|
||||||
|
let mut substate = Substate::new(true);
|
||||||
|
|
||||||
|
let gas_left = {
|
||||||
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
|
ex.create(params.clone(), &mut substate).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("trace: {:?}", substate.subtraces);
|
||||||
|
let expected_trace = Some(vec![Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Create(TraceCreate {
|
||||||
|
from: params.sender,
|
||||||
|
value: x!(100),
|
||||||
|
gas: params.gas,
|
||||||
|
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85],
|
||||||
|
result: Some((x!(3224), params.address, vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53])),
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
} ]);
|
||||||
|
assert_eq!(substate.subtraces, expected_trace);
|
||||||
|
assert_eq!(gas_left, U256::from(96_776));
|
||||||
|
}
|
||||||
|
|
||||||
evm_test!{test_create_contract_value_too_high: test_create_contract_value_too_high_jit, test_create_contract_value_too_high_int}
|
evm_test!{test_create_contract_value_too_high: test_create_contract_value_too_high_jit, test_create_contract_value_too_high_int}
|
||||||
fn test_create_contract_value_too_high(factory: Factory) {
|
fn test_create_contract_value_too_high(factory: Factory) {
|
||||||
// code:
|
// code:
|
||||||
@ -504,7 +686,7 @@ mod tests {
|
|||||||
state.add_balance(&sender, &U256::from(100));
|
state.add_balance(&sender, &U256::from(100));
|
||||||
let info = EnvInfo::default();
|
let info = EnvInfo::default();
|
||||||
let engine = TestEngine::new(0, factory);
|
let engine = TestEngine::new(0, factory);
|
||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new(false);
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
@ -556,7 +738,7 @@ mod tests {
|
|||||||
state.add_balance(&sender, &U256::from(100));
|
state.add_balance(&sender, &U256::from(100));
|
||||||
let info = EnvInfo::default();
|
let info = EnvInfo::default();
|
||||||
let engine = TestEngine::new(1024, factory);
|
let engine = TestEngine::new(1024, factory);
|
||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new(false);
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
@ -617,7 +799,7 @@ mod tests {
|
|||||||
|
|
||||||
let info = EnvInfo::default();
|
let info = EnvInfo::default();
|
||||||
let engine = TestEngine::new(0, factory);
|
let engine = TestEngine::new(0, factory);
|
||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new(false);
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
@ -662,7 +844,7 @@ mod tests {
|
|||||||
state.init_code(&address, code.clone());
|
state.init_code(&address, code.clone());
|
||||||
let info = EnvInfo::default();
|
let info = EnvInfo::default();
|
||||||
let engine = TestEngine::new(0, factory);
|
let engine = TestEngine::new(0, factory);
|
||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new(false);
|
||||||
|
|
||||||
let gas_left = {
|
let gas_left = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
@ -699,7 +881,7 @@ mod tests {
|
|||||||
|
|
||||||
let executed = {
|
let executed = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
ex.transact(&t).unwrap()
|
ex.transact(&t, false).unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(executed.gas, U256::from(100_000));
|
assert_eq!(executed.gas, U256::from(100_000));
|
||||||
@ -732,7 +914,7 @@ mod tests {
|
|||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
ex.transact(&t)
|
ex.transact(&t, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
@ -763,7 +945,7 @@ mod tests {
|
|||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
ex.transact(&t)
|
ex.transact(&t, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
@ -796,7 +978,7 @@ mod tests {
|
|||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
ex.transact(&t)
|
ex.transact(&t, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
@ -829,7 +1011,7 @@ mod tests {
|
|||||||
|
|
||||||
let res = {
|
let res = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
ex.transact(&t)
|
ex.transact(&t, false)
|
||||||
};
|
};
|
||||||
|
|
||||||
match res {
|
match res {
|
||||||
@ -859,7 +1041,7 @@ mod tests {
|
|||||||
state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap());
|
state.add_balance(&sender, &U256::from_str("152d02c7e14af6800000").unwrap());
|
||||||
let info = EnvInfo::default();
|
let info = EnvInfo::default();
|
||||||
let engine = TestEngine::new(0, factory);
|
let engine = TestEngine::new(0, factory);
|
||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new(false);
|
||||||
|
|
||||||
let result = {
|
let result = {
|
||||||
let mut ex = Executive::new(&mut state, &info, &engine);
|
let mut ex = Executive::new(&mut state, &info, &engine);
|
||||||
|
@ -23,12 +23,12 @@ use evm::{self, Schedule, Ext, ContractCreateResult, MessageCallResult};
|
|||||||
use substate::*;
|
use substate::*;
|
||||||
|
|
||||||
/// Policy for handling output data on `RETURN` opcode.
|
/// Policy for handling output data on `RETURN` opcode.
|
||||||
pub enum OutputPolicy<'a> {
|
pub enum OutputPolicy<'a, 'b> {
|
||||||
/// Return reference to fixed sized output.
|
/// Return reference to fixed sized output.
|
||||||
/// Used for message calls.
|
/// Used for message calls.
|
||||||
Return(BytesRef<'a>),
|
Return(BytesRef<'a>, Option<&'b mut Bytes>),
|
||||||
/// Init new contract as soon as `RETURN` is called.
|
/// Init new contract as soon as `RETURN` is called.
|
||||||
InitContract
|
InitContract(Option<&'b mut Bytes>),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Transaction properties that externalities need to know about.
|
/// Transaction properties that externalities need to know about.
|
||||||
@ -62,18 +62,19 @@ pub struct Externalities<'a> {
|
|||||||
origin_info: OriginInfo,
|
origin_info: OriginInfo,
|
||||||
substate: &'a mut Substate,
|
substate: &'a mut Substate,
|
||||||
schedule: Schedule,
|
schedule: Schedule,
|
||||||
output: OutputPolicy<'a>
|
output: OutputPolicy<'a, 'a>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Externalities<'a> {
|
impl<'a> Externalities<'a> {
|
||||||
/// Basic `Externalities` constructor.
|
/// Basic `Externalities` constructor.
|
||||||
pub fn new(state: &'a mut State,
|
pub fn new(state: &'a mut State,
|
||||||
env_info: &'a EnvInfo,
|
env_info: &'a EnvInfo,
|
||||||
engine: &'a Engine,
|
engine: &'a Engine,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
origin_info: OriginInfo,
|
origin_info: OriginInfo,
|
||||||
substate: &'a mut Substate,
|
substate: &'a mut Substate,
|
||||||
output: OutputPolicy<'a>) -> Self {
|
output: OutputPolicy<'a, 'a>
|
||||||
|
) -> Self {
|
||||||
Externalities {
|
Externalities {
|
||||||
state: state,
|
state: state,
|
||||||
env_info: env_info,
|
env_info: env_info,
|
||||||
@ -152,13 +153,15 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn call(&mut self,
|
fn call(&mut self,
|
||||||
gas: &U256,
|
gas: &U256,
|
||||||
sender_address: &Address,
|
sender_address: &Address,
|
||||||
receive_address: &Address,
|
receive_address: &Address,
|
||||||
value: Option<U256>,
|
value: Option<U256>,
|
||||||
data: &[u8],
|
data: &[u8],
|
||||||
code_address: &Address,
|
code_address: &Address,
|
||||||
output: &mut [u8]) -> MessageCallResult {
|
output: &mut [u8]
|
||||||
|
) -> MessageCallResult {
|
||||||
|
trace!(target: "externalities", "call");
|
||||||
|
|
||||||
let mut params = ActionParams {
|
let mut params = ActionParams {
|
||||||
sender: sender_address.clone(),
|
sender: sender_address.clone(),
|
||||||
@ -188,22 +191,33 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
self.state.code(address).unwrap_or_else(|| vec![])
|
self.state.code(address).unwrap_or_else(|| vec![])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(match_ref_pats)]
|
#[cfg_attr(feature="dev", allow(match_ref_pats))]
|
||||||
fn ret(&mut self, gas: &U256, data: &[u8]) -> Result<U256, evm::Error> {
|
fn ret(&mut self, gas: &U256, data: &[u8]) -> Result<U256, evm::Error> {
|
||||||
match &mut self.output {
|
let handle_copy = |to: &mut Option<&mut Bytes>| {
|
||||||
&mut OutputPolicy::Return(BytesRef::Fixed(ref mut slice)) => unsafe {
|
to.as_mut().map(|b| **b = data.to_owned());
|
||||||
|
};
|
||||||
|
match self.output {
|
||||||
|
OutputPolicy::Return(BytesRef::Fixed(ref mut slice), ref mut copy) => {
|
||||||
|
handle_copy(copy);
|
||||||
|
|
||||||
let len = cmp::min(slice.len(), data.len());
|
let len = cmp::min(slice.len(), data.len());
|
||||||
ptr::copy(data.as_ptr(), slice.as_mut_ptr(), len);
|
unsafe {
|
||||||
|
ptr::copy(data.as_ptr(), slice.as_mut_ptr(), len);
|
||||||
|
}
|
||||||
Ok(*gas)
|
Ok(*gas)
|
||||||
},
|
},
|
||||||
&mut OutputPolicy::Return(BytesRef::Flexible(ref mut vec)) => unsafe {
|
OutputPolicy::Return(BytesRef::Flexible(ref mut vec), ref mut copy) => {
|
||||||
|
handle_copy(copy);
|
||||||
|
|
||||||
vec.clear();
|
vec.clear();
|
||||||
vec.reserve(data.len());
|
vec.reserve(data.len());
|
||||||
ptr::copy(data.as_ptr(), vec.as_mut_ptr(), data.len());
|
unsafe {
|
||||||
vec.set_len(data.len());
|
ptr::copy(data.as_ptr(), vec.as_mut_ptr(), data.len());
|
||||||
|
vec.set_len(data.len());
|
||||||
|
}
|
||||||
Ok(*gas)
|
Ok(*gas)
|
||||||
},
|
},
|
||||||
&mut OutputPolicy::InitContract => {
|
OutputPolicy::InitContract(ref mut copy) => {
|
||||||
let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas);
|
let return_cost = U256::from(data.len()) * U256::from(self.schedule.create_data_gas);
|
||||||
if return_cost > *gas {
|
if return_cost > *gas {
|
||||||
return match self.schedule.exceptional_failed_code_deposit {
|
return match self.schedule.exceptional_failed_code_deposit {
|
||||||
@ -211,14 +225,16 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
false => Ok(*gas)
|
false => Ok(*gas)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle_copy(copy);
|
||||||
|
|
||||||
let mut code = vec![];
|
let mut code = vec![];
|
||||||
code.reserve(data.len());
|
code.reserve(data.len());
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::copy(data.as_ptr(), code.as_mut_ptr(), data.len());
|
ptr::copy(data.as_ptr(), code.as_mut_ptr(), data.len());
|
||||||
code.set_len(data.len());
|
code.set_len(data.len());
|
||||||
}
|
}
|
||||||
let address = &self.origin_info.address;
|
self.state.init_code(&self.origin_info.address, code);
|
||||||
self.state.init_code(address, code);
|
|
||||||
Ok(*gas - return_cost)
|
Ok(*gas - return_cost)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -226,7 +242,11 @@ impl<'a> Ext for Externalities<'a> {
|
|||||||
|
|
||||||
fn log(&mut self, topics: Vec<H256>, data: &[u8]) {
|
fn log(&mut self, topics: Vec<H256>, data: &[u8]) {
|
||||||
let address = self.origin_info.address.clone();
|
let address = self.origin_info.address.clone();
|
||||||
self.substate.logs.push(LogEntry::new(address, topics, data.to_vec()));
|
self.substate.logs.push(LogEntry {
|
||||||
|
address: address,
|
||||||
|
topics: topics,
|
||||||
|
data: data.to_vec()
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn suicide(&mut self, refund_address: &Address) {
|
fn suicide(&mut self, refund_address: &Address) {
|
||||||
@ -297,12 +317,18 @@ mod tests {
|
|||||||
env_info: EnvInfo
|
env_info: EnvInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for TestSetup {
|
||||||
|
fn default() -> Self {
|
||||||
|
TestSetup::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl TestSetup {
|
impl TestSetup {
|
||||||
fn new() -> TestSetup {
|
fn new() -> Self {
|
||||||
TestSetup {
|
TestSetup {
|
||||||
state: get_temp_state(),
|
state: get_temp_state(),
|
||||||
engine: get_test_spec().to_engine().unwrap(),
|
engine: get_test_spec().to_engine().unwrap(),
|
||||||
sub_state: Substate::new(),
|
sub_state: Substate::new(false),
|
||||||
env_info: get_test_env_info()
|
env_info: get_test_env_info()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -313,7 +339,7 @@ mod tests {
|
|||||||
let mut setup = TestSetup::new();
|
let mut setup = TestSetup::new();
|
||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
|
|
||||||
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
|
|
||||||
assert_eq!(ext.env_info().number, 100);
|
assert_eq!(ext.env_info().number, 100);
|
||||||
}
|
}
|
||||||
@ -322,7 +348,7 @@ mod tests {
|
|||||||
fn can_return_block_hash_no_env() {
|
fn can_return_block_hash_no_env() {
|
||||||
let mut setup = TestSetup::new();
|
let mut setup = TestSetup::new();
|
||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
|
|
||||||
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap());
|
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap());
|
||||||
|
|
||||||
@ -341,7 +367,7 @@ mod tests {
|
|||||||
env_info.last_hashes.push(test_hash.clone());
|
env_info.last_hashes.push(test_hash.clone());
|
||||||
}
|
}
|
||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
|
|
||||||
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap());
|
let hash = ext.blockhash(&U256::from_str("0000000000000000000000000000000000000000000000000000000000120000").unwrap());
|
||||||
|
|
||||||
@ -353,7 +379,7 @@ mod tests {
|
|||||||
fn can_call_fail_empty() {
|
fn can_call_fail_empty() {
|
||||||
let mut setup = TestSetup::new();
|
let mut setup = TestSetup::new();
|
||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
|
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
|
||||||
@ -377,7 +403,7 @@ mod tests {
|
|||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
ext.log(log_topics, &log_data);
|
ext.log(log_topics, &log_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -392,7 +418,7 @@ mod tests {
|
|||||||
let state = setup.state.reference_mut();
|
let state = setup.state.reference_mut();
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract);
|
let mut ext = Externalities::new(state, &setup.env_info, &*setup.engine, 0, get_test_origin(), &mut setup.sub_state, OutputPolicy::InitContract(None));
|
||||||
ext.suicide(&refund_account);
|
ext.suicide(&refund_account);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
use header::BlockNumber;
|
use header::BlockNumber;
|
||||||
use rocksdb::{DB, Writable};
|
use receipt::Receipt;
|
||||||
|
|
||||||
/// Represents index of extra data in database
|
/// Represents index of extra data in database
|
||||||
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
|
#[derive(Copy, Debug, Hash, Eq, PartialEq, Clone)]
|
||||||
@ -32,14 +32,16 @@ pub enum ExtrasIndex {
|
|||||||
/// Block log blooms index
|
/// Block log blooms index
|
||||||
BlockLogBlooms = 3,
|
BlockLogBlooms = 3,
|
||||||
/// Block blooms index
|
/// Block blooms index
|
||||||
BlocksBlooms = 4
|
BlocksBlooms = 4,
|
||||||
}
|
/// Block receipts index
|
||||||
|
BlockReceipts = 5,
|
||||||
|
}
|
||||||
|
|
||||||
/// trait used to write Extras data to db
|
/// trait used to write Extras data to db
|
||||||
pub trait ExtrasWritable {
|
pub trait ExtrasWritable {
|
||||||
/// Write extra data to db
|
/// Write extra data to db
|
||||||
fn put_extras<K, T>(&self, hash: &K, value: &T) where
|
fn put_extras<K, T>(&self, hash: &K, value: &T) where
|
||||||
T: ExtrasIndexable + Encodable,
|
T: ExtrasIndexable + Encodable,
|
||||||
K: ExtrasSliceConvertable;
|
K: ExtrasSliceConvertable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,16 +58,16 @@ pub trait ExtrasReadable {
|
|||||||
K: ExtrasSliceConvertable;
|
K: ExtrasSliceConvertable;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W> ExtrasWritable for W where W: Writable {
|
impl ExtrasWritable for DBTransaction {
|
||||||
fn put_extras<K, T>(&self, hash: &K, value: &T) where
|
fn put_extras<K, T>(&self, hash: &K, value: &T) where
|
||||||
T: ExtrasIndexable + Encodable,
|
T: ExtrasIndexable + Encodable,
|
||||||
K: ExtrasSliceConvertable {
|
K: ExtrasSliceConvertable {
|
||||||
|
|
||||||
self.put(&hash.to_extras_slice(T::extras_index()), &encode(value)).unwrap()
|
self.put(&hash.to_extras_slice(T::extras_index()), &encode(value)).unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtrasReadable for DB {
|
impl ExtrasReadable for Database {
|
||||||
fn get_extras<K, T>(&self, hash: &K) -> Option<T> where
|
fn get_extras<K, T>(&self, hash: &K) -> Option<T> where
|
||||||
T: ExtrasIndexable + Decodable,
|
T: ExtrasIndexable + Decodable,
|
||||||
K: ExtrasSliceConvertable {
|
K: ExtrasSliceConvertable {
|
||||||
@ -210,7 +212,19 @@ impl Encodable for BlockLogBlooms {
|
|||||||
/// Neighboring log blooms on certain level
|
/// Neighboring log blooms on certain level
|
||||||
pub struct BlocksBlooms {
|
pub struct BlocksBlooms {
|
||||||
/// List of block blooms.
|
/// List of block blooms.
|
||||||
pub blooms: [H2048; 16]
|
pub blooms: [H2048; 16],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for BlocksBlooms {
|
||||||
|
fn default() -> Self {
|
||||||
|
BlocksBlooms::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlocksBlooms {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
BlocksBlooms { blooms: unsafe { ::std::mem::zeroed() }}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ExtrasIndexable for BlocksBlooms {
|
impl ExtrasIndexable for BlocksBlooms {
|
||||||
@ -292,3 +306,43 @@ impl Encodable for TransactionAddress {
|
|||||||
s.append(&self.index);
|
s.append(&self.index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Contains all block receipts.
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct BlockReceipts {
|
||||||
|
pub receipts: Vec<Receipt>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockReceipts {
|
||||||
|
pub fn new(receipts: Vec<Receipt>) -> Self {
|
||||||
|
BlockReceipts {
|
||||||
|
receipts: receipts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decodable for BlockReceipts {
|
||||||
|
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||||
|
Ok(BlockReceipts {
|
||||||
|
receipts: try!(Decodable::decode(decoder))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Encodable for BlockReceipts {
|
||||||
|
fn rlp_append(&self, s: &mut RlpStream) {
|
||||||
|
s.append(&self.receipts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapSizeOf for BlockReceipts {
|
||||||
|
fn heap_size_of_children(&self) -> usize {
|
||||||
|
self.receipts.heap_size_of_children()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExtrasIndexable for BlockReceipts {
|
||||||
|
fn extras_index() -> ExtrasIndex {
|
||||||
|
ExtrasIndex::BlockReceipts
|
||||||
|
}
|
||||||
|
}
|
||||||
|
230
ethcore/src/filter.rs
Normal file
230
ethcore/src/filter.rs
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Blockchain filter
|
||||||
|
|
||||||
|
use util::hash::*;
|
||||||
|
use util::sha3::*;
|
||||||
|
use client::BlockId;
|
||||||
|
use log_entry::LogEntry;
|
||||||
|
|
||||||
|
/// Blockchain Filter.
|
||||||
|
pub struct Filter {
|
||||||
|
/// Blockchain will be searched from this block.
|
||||||
|
pub from_block: BlockId,
|
||||||
|
|
||||||
|
/// Till this block.
|
||||||
|
pub to_block: BlockId,
|
||||||
|
|
||||||
|
/// Search addresses.
|
||||||
|
///
|
||||||
|
/// If None, match all.
|
||||||
|
/// If specified, log must be produced by one of these addresses.
|
||||||
|
pub address: Option<Vec<Address>>,
|
||||||
|
|
||||||
|
/// Search topics.
|
||||||
|
///
|
||||||
|
/// If None, match all.
|
||||||
|
/// If specified, log must contain one of these topics.
|
||||||
|
pub topics: [Option<Vec<H256>>; 4],
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for Filter {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
let mut topics = [None, None, None, None];
|
||||||
|
for i in 0..4 {
|
||||||
|
topics[i] = self.topics[i].clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
Filter {
|
||||||
|
from_block: self.from_block.clone(),
|
||||||
|
to_block: self.to_block.clone(),
|
||||||
|
address: self.address.clone(),
|
||||||
|
topics: topics
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Filter {
|
||||||
|
/// Returns combinations of each address and topic.
|
||||||
|
pub fn bloom_possibilities(&self) -> Vec<H2048> {
|
||||||
|
let blooms = match self.address {
|
||||||
|
Some(ref addresses) if !addresses.is_empty() =>
|
||||||
|
addresses.iter().map(|ref address| {
|
||||||
|
let mut bloom = H2048::new();
|
||||||
|
bloom.shift_bloomed(&address.sha3());
|
||||||
|
bloom
|
||||||
|
}).collect(),
|
||||||
|
_ => vec![H2048::new()]
|
||||||
|
};
|
||||||
|
|
||||||
|
self.topics.iter().fold(blooms, | bs, topic | match *topic {
|
||||||
|
None => bs,
|
||||||
|
Some(ref topics) => bs.into_iter().flat_map(|bloom| {
|
||||||
|
topics.into_iter().map(|topic| {
|
||||||
|
let mut b = bloom.clone();
|
||||||
|
b.shift_bloomed(&topic.sha3());
|
||||||
|
b
|
||||||
|
}).collect::<Vec<H2048>>()
|
||||||
|
}).collect()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if given log entry matches filter.
|
||||||
|
pub fn matches(&self, log: &LogEntry) -> bool {
|
||||||
|
let matches = match self.address {
|
||||||
|
Some(ref addresses) if !addresses.is_empty() => addresses.iter().any(|address| &log.address == address),
|
||||||
|
_ => true
|
||||||
|
};
|
||||||
|
|
||||||
|
matches && self.topics.iter().enumerate().all(|(i, topic)| match *topic {
|
||||||
|
Some(ref topics) if !topics.is_empty() => topics.iter().any(|topic| log.topics.get(i) == Some(topic)),
|
||||||
|
_ => true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use std::str::FromStr;
|
||||||
|
use util::hash::*;
|
||||||
|
use filter::Filter;
|
||||||
|
use client::BlockId;
|
||||||
|
use log_entry::LogEntry;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bloom_possibilities_none() {
|
||||||
|
let none_filter = Filter {
|
||||||
|
from_block: BlockId::Earliest,
|
||||||
|
to_block: BlockId::Latest,
|
||||||
|
address: None,
|
||||||
|
topics: [None, None, None, None]
|
||||||
|
};
|
||||||
|
|
||||||
|
let possibilities = none_filter.bloom_possibilities();
|
||||||
|
assert_eq!(possibilities.len(), 1);
|
||||||
|
assert!(possibilities[0].is_zero())
|
||||||
|
}
|
||||||
|
|
||||||
|
// block 399849
|
||||||
|
#[test]
|
||||||
|
fn test_bloom_possibilities_single_address_and_topic() {
|
||||||
|
let filter = Filter {
|
||||||
|
from_block: BlockId::Earliest,
|
||||||
|
to_block: BlockId::Latest,
|
||||||
|
address: Some(vec![Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap()]),
|
||||||
|
topics: [
|
||||||
|
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
||||||
|
None, None, None
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
let possibilities = filter.bloom_possibilities();
|
||||||
|
assert_eq!(possibilities, vec![H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bloom_possibilities_single_address_and_many_topics() {
|
||||||
|
let filter = Filter {
|
||||||
|
from_block: BlockId::Earliest,
|
||||||
|
to_block: BlockId::Latest,
|
||||||
|
address: Some(vec![Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap()]),
|
||||||
|
topics: [
|
||||||
|
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
||||||
|
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
||||||
|
None, None
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
let possibilities = filter.bloom_possibilities();
|
||||||
|
assert_eq!(possibilities, vec![H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000").unwrap()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_bloom_possibilites_multiple_addresses_and_topics() {
|
||||||
|
let filter = Filter {
|
||||||
|
from_block: BlockId::Earliest,
|
||||||
|
to_block: BlockId::Latest,
|
||||||
|
address: Some(vec![
|
||||||
|
Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
|
||||||
|
Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
|
||||||
|
]),
|
||||||
|
topics: [
|
||||||
|
Some(vec![
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()
|
||||||
|
]),
|
||||||
|
Some(vec![
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()
|
||||||
|
]),
|
||||||
|
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
||||||
|
None
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
// number of possibilites should be equal 2 * 2 * 2 * 1 = 8
|
||||||
|
let possibilities = filter.bloom_possibilities();
|
||||||
|
assert_eq!(possibilities.len(), 8);
|
||||||
|
assert_eq!(possibilities[0], H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000004000000004000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000").unwrap());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_filter_matches() {
|
||||||
|
let filter = Filter {
|
||||||
|
from_block: BlockId::Earliest,
|
||||||
|
to_block: BlockId::Latest,
|
||||||
|
address: Some(vec![Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap()]),
|
||||||
|
topics: [
|
||||||
|
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap()]),
|
||||||
|
Some(vec![H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa").unwrap()]),
|
||||||
|
None, None
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
let entry0 = LogEntry {
|
||||||
|
address: Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
|
||||||
|
topics: vec![
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa").unwrap(),
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
||||||
|
],
|
||||||
|
data: vec![]
|
||||||
|
};
|
||||||
|
|
||||||
|
let entry1 = LogEntry {
|
||||||
|
address: Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5e").unwrap(),
|
||||||
|
topics: vec![
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23fa").unwrap(),
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
||||||
|
],
|
||||||
|
data: vec![]
|
||||||
|
};
|
||||||
|
|
||||||
|
let entry2 = LogEntry {
|
||||||
|
address: Address::from_str("b372018f3be9e171df0581136b59d2faf73a7d5d").unwrap(),
|
||||||
|
topics: vec![
|
||||||
|
H256::from_str("ff74e91598aed6ae5d2fdcf8b24cd2c7be49a0808112a305069355b7160f23f9").unwrap(),
|
||||||
|
],
|
||||||
|
data: vec![]
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(filter.matches(&entry0), true);
|
||||||
|
assert_eq!(filter.matches(&entry1), false);
|
||||||
|
assert_eq!(filter.matches(&entry2), false);
|
||||||
|
}
|
||||||
|
}
|
@ -29,7 +29,7 @@ pub type BlockNumber = u64;
|
|||||||
/// which is non-specific.
|
/// which is non-specific.
|
||||||
///
|
///
|
||||||
/// Doesn't do all that much on its own.
|
/// Doesn't do all that much on its own.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, Eq)]
|
||||||
pub struct Header {
|
pub struct Header {
|
||||||
// TODO: make all private.
|
// TODO: make all private.
|
||||||
/// Parent hash.
|
/// Parent hash.
|
||||||
@ -70,6 +70,25 @@ pub struct Header {
|
|||||||
pub bare_hash: RefCell<Option<H256>>,
|
pub bare_hash: RefCell<Option<H256>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PartialEq for Header {
|
||||||
|
fn eq(&self, c: &Header) -> bool {
|
||||||
|
self.parent_hash == c.parent_hash &&
|
||||||
|
self.timestamp == c.timestamp &&
|
||||||
|
self.number == c.number &&
|
||||||
|
self.author == c.author &&
|
||||||
|
self.transactions_root == c.transactions_root &&
|
||||||
|
self.uncles_hash == c.uncles_hash &&
|
||||||
|
self.extra_data == c.extra_data &&
|
||||||
|
self.state_root == c.state_root &&
|
||||||
|
self.receipts_root == c.receipts_root &&
|
||||||
|
self.log_bloom == c.log_bloom &&
|
||||||
|
self.gas_used == c.gas_used &&
|
||||||
|
self.gas_limit == c.gas_limit &&
|
||||||
|
self.difficulty == c.difficulty &&
|
||||||
|
self.seal == c.seal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Default for Header {
|
impl Default for Header {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Header {
|
Header {
|
||||||
@ -102,10 +121,12 @@ impl Header {
|
|||||||
Self::default()
|
Self::default()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the number field of the header.
|
/// Get the parent_hash field of the header.
|
||||||
pub fn number(&self) -> BlockNumber { self.number }
|
pub fn parent_hash(&self) -> &H256 { &self.parent_hash }
|
||||||
/// Get the timestamp field of the header.
|
/// Get the timestamp field of the header.
|
||||||
pub fn timestamp(&self) -> u64 { self.timestamp }
|
pub fn timestamp(&self) -> u64 { self.timestamp }
|
||||||
|
/// Get the number field of the header.
|
||||||
|
pub fn number(&self) -> BlockNumber { self.number }
|
||||||
/// Get the author field of the header.
|
/// Get the author field of the header.
|
||||||
pub fn author(&self) -> &Address { &self.author }
|
pub fn author(&self) -> &Address { &self.author }
|
||||||
|
|
||||||
@ -127,11 +148,13 @@ impl Header {
|
|||||||
// TODO: seal_at, set_seal_at &c.
|
// TODO: seal_at, set_seal_at &c.
|
||||||
|
|
||||||
/// Set the number field of the header.
|
/// Set the number field of the header.
|
||||||
pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); }
|
pub fn set_parent_hash(&mut self, a: H256) { self.parent_hash = a; self.note_dirty(); }
|
||||||
/// Set the timestamp field of the header.
|
/// Set the timestamp field of the header.
|
||||||
pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); }
|
pub fn set_timestamp(&mut self, a: u64) { self.timestamp = a; self.note_dirty(); }
|
||||||
/// Set the timestamp field of the header to the current time.
|
/// Set the timestamp field of the header to the current time.
|
||||||
pub fn set_timestamp_now(&mut self) { self.timestamp = now_utc().to_timespec().sec as u64; self.note_dirty(); }
|
pub fn set_timestamp_now(&mut self, but_later_than: u64) { self.timestamp = max(now_utc().to_timespec().sec as u64, but_later_than + 1); self.note_dirty(); }
|
||||||
|
/// Set the number field of the header.
|
||||||
|
pub fn set_number(&mut self, a: BlockNumber) { self.number = a; self.note_dirty(); }
|
||||||
/// Set the author field of the header.
|
/// Set the author field of the header.
|
||||||
pub fn set_author(&mut self, a: Address) { if a != self.author { self.author = a; self.note_dirty(); } }
|
pub fn set_author(&mut self, a: Address) { if a != self.author { self.author = a; self.note_dirty(); } }
|
||||||
|
|
||||||
|
@ -15,18 +15,20 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use super::test_common::*;
|
use super::test_common::*;
|
||||||
use client::{BlockChainClient,Client};
|
use client::{BlockChainClient, Client, ClientConfig};
|
||||||
use pod_state::*;
|
|
||||||
use block::Block;
|
use block::Block;
|
||||||
use ethereum;
|
use ethereum;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
|
use devtools::*;
|
||||||
|
use spec::Genesis;
|
||||||
|
use ethjson;
|
||||||
|
|
||||||
pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
||||||
init_log();
|
init_log();
|
||||||
let json = Json::from_str(::std::str::from_utf8(json_data).unwrap()).expect("Json is invalid");
|
let tests = ethjson::blockchain::Test::load(json_data).unwrap();
|
||||||
let mut failed = Vec::new();
|
let mut failed = Vec::new();
|
||||||
|
|
||||||
for (name, test) in json.as_object().unwrap() {
|
for (name, blockchain) in tests.deref() {
|
||||||
let mut fail = false;
|
let mut fail = false;
|
||||||
{
|
{
|
||||||
let mut fail_unless = |cond: bool| if !cond && !fail {
|
let mut fail_unless = |cond: bool| if !cond && !fail {
|
||||||
@ -38,37 +40,36 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
|||||||
|
|
||||||
flush!(" - {}...", name);
|
flush!(" - {}...", name);
|
||||||
|
|
||||||
let blocks: Vec<(Bytes, bool)> = test["blocks"].as_array().unwrap().iter().map(|e| (xjson!(&e["rlp"]), e.find("blockHeader").is_some())).collect();
|
|
||||||
let mut spec = match era {
|
let mut spec = match era {
|
||||||
ChainEra::Frontier => ethereum::new_frontier_test(),
|
ChainEra::Frontier => ethereum::new_frontier_test(),
|
||||||
ChainEra::Homestead => ethereum::new_homestead_test(),
|
ChainEra::Homestead => ethereum::new_homestead_test(),
|
||||||
};
|
};
|
||||||
let s = PodState::from_json(test.find("pre").unwrap());
|
|
||||||
spec.set_genesis_state(s);
|
let genesis = Genesis::from(blockchain.genesis());
|
||||||
spec.overwrite_genesis(test.find("genesisBlockHeader").unwrap());
|
let state = From::from(blockchain.pre_state.clone());
|
||||||
|
spec.set_genesis_state(state);
|
||||||
|
spec.overwrite_genesis_params(genesis);
|
||||||
assert!(spec.is_state_root_valid());
|
assert!(spec.is_state_root_valid());
|
||||||
let genesis_hash = spec.genesis_header().hash();
|
|
||||||
assert_eq!(genesis_hash, H256::from_json(&test.find("genesisBlockHeader").unwrap()["hash"]));
|
|
||||||
|
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
{
|
{
|
||||||
let client = Client::new(spec, temp.as_path(), IoChannel::disconnected()).unwrap();
|
let client = Client::new(ClientConfig::default(), spec, temp.as_path(), IoChannel::disconnected()).unwrap();
|
||||||
assert_eq!(client.chain_info().best_block_hash, genesis_hash);
|
for b in &blockchain.blocks_rlp() {
|
||||||
for (b, is_valid) in blocks.into_iter() {
|
|
||||||
if Block::is_good(&b) {
|
if Block::is_good(&b) {
|
||||||
let _ = client.import_block(b.clone());
|
let _ = client.import_block(b.clone());
|
||||||
|
client.flush_queue();
|
||||||
|
client.import_verified_blocks(&IoChannel::disconnected());
|
||||||
}
|
}
|
||||||
client.flush_queue();
|
|
||||||
let imported_ok = client.import_verified_blocks(&IoChannel::disconnected()) > 0;
|
|
||||||
assert_eq!(imported_ok, is_valid);
|
|
||||||
}
|
}
|
||||||
fail_unless(client.chain_info().best_block_hash == H256::from_json(&test["lastblockhash"]));
|
fail_unless(client.chain_info().best_block_hash == blockchain.best_block.clone().into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !fail {
|
if !fail {
|
||||||
flushln!("ok");
|
flushln!("ok");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("!!! {:?} tests from failed.", failed.len());
|
println!("!!! {:?} tests from failed.", failed.len());
|
||||||
failed
|
failed
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ impl<'a> TestExt<'a> {
|
|||||||
depth: usize,
|
depth: usize,
|
||||||
origin_info: OriginInfo,
|
origin_info: OriginInfo,
|
||||||
substate: &'a mut Substate,
|
substate: &'a mut Substate,
|
||||||
output: OutputPolicy<'a>,
|
output: OutputPolicy<'a, 'a>,
|
||||||
address: Address) -> Self {
|
address: Address) -> Self {
|
||||||
TestExt {
|
TestExt {
|
||||||
contract_address: contract_address(&address, &state.nonce(&address)),
|
contract_address: contract_address(&address, &state.nonce(&address)),
|
||||||
@ -227,19 +227,21 @@ fn do_json_test_for(vm: &VMType, json_data: &[u8]) -> Vec<String> {
|
|||||||
let out_of_gas = test.find("callcreates").map(|_calls| {
|
let out_of_gas = test.find("callcreates").map(|_calls| {
|
||||||
}).is_none();
|
}).is_none();
|
||||||
|
|
||||||
let mut substate = Substate::new();
|
let mut substate = Substate::new(false);
|
||||||
let mut output = vec![];
|
let mut output = vec![];
|
||||||
|
|
||||||
// execute
|
// execute
|
||||||
let (res, callcreates) = {
|
let (res, callcreates) = {
|
||||||
let mut ex = TestExt::new(&mut state,
|
let mut ex = TestExt::new(
|
||||||
&info,
|
&mut state,
|
||||||
&engine,
|
&info,
|
||||||
0,
|
&engine,
|
||||||
OriginInfo::from(¶ms),
|
0,
|
||||||
&mut substate,
|
OriginInfo::from(¶ms),
|
||||||
OutputPolicy::Return(BytesRef::Flexible(&mut output)),
|
&mut substate,
|
||||||
params.address.clone());
|
OutputPolicy::Return(BytesRef::Flexible(&mut output), None),
|
||||||
|
params.address.clone()
|
||||||
|
);
|
||||||
let evm = engine.vm_factory().create();
|
let evm = engine.vm_factory().create();
|
||||||
let res = evm.exec(params, &mut ex);
|
let res = evm.exec(params, &mut ex);
|
||||||
(res, ex.callcreates)
|
(res, ex.callcreates)
|
||||||
|
@ -69,7 +69,7 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
|||||||
let mut state = state_result.reference_mut();
|
let mut state = state_result.reference_mut();
|
||||||
state.populate_from(pre);
|
state.populate_from(pre);
|
||||||
state.commit();
|
state.commit();
|
||||||
let res = state.apply(&env, engine.deref(), &t);
|
let res = state.apply(&env, engine.deref(), &t, false);
|
||||||
|
|
||||||
if fail_unless(state.root() == &post_state_root) {
|
if fail_unless(state.root() == &post_state_root) {
|
||||||
println!("!!! {}: State mismatch (got: {}, expect: {}):", name, state.root(), post_state_root);
|
println!("!!! {}: State mismatch (got: {}, expect: {}):", name, state.root(), post_state_root);
|
||||||
@ -80,9 +80,9 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if let Ok(r) = res {
|
if let Ok(r) = res {
|
||||||
if fail_unless(logs == r.logs) {
|
if fail_unless(logs == r.receipt.logs) {
|
||||||
println!("!!! {}: Logs mismatch:", name);
|
println!("!!! {}: Logs mismatch:", name);
|
||||||
println!("Got:\n{:?}", r.logs);
|
println!("Got:\n{:?}", r.receipt.logs);
|
||||||
println!("Expect:\n{:?}", logs);
|
println!("Expect:\n{:?}", logs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +115,7 @@ declare_test!{StateTests_stSolidityTest, "StateTests/stSolidityTest"}
|
|||||||
declare_test!{StateTests_stSpecialTest, "StateTests/stSpecialTest"}
|
declare_test!{StateTests_stSpecialTest, "StateTests/stSpecialTest"}
|
||||||
declare_test!{StateTests_stSystemOperationsTest, "StateTests/stSystemOperationsTest"}
|
declare_test!{StateTests_stSystemOperationsTest, "StateTests/stSystemOperationsTest"}
|
||||||
declare_test!{StateTests_stTransactionTest, "StateTests/stTransactionTest"}
|
declare_test!{StateTests_stTransactionTest, "StateTests/stTransactionTest"}
|
||||||
//declare_test!{StateTests_stTransitionTest, "StateTests/stTransitionTest"}
|
declare_test!{StateTests_stTransitionTest, "StateTests/stTransitionTest"}
|
||||||
declare_test!{StateTests_stWalletTest, "StateTests/stWalletTest"}
|
declare_test!{StateTests_stWalletTest, "StateTests/stWalletTest"}
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,18 +15,18 @@
|
|||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
#![feature(cell_extras)]
|
#![cfg_attr(feature="dev", feature(plugin))]
|
||||||
#![feature(augmented_assignments)]
|
#![cfg_attr(feature="dev", plugin(clippy))]
|
||||||
#![feature(plugin)]
|
|
||||||
// Clippy
|
|
||||||
#![plugin(clippy)]
|
|
||||||
// TODO [todr] not really sure
|
|
||||||
#![allow(needless_range_loop)]
|
|
||||||
// Shorter than if-else
|
|
||||||
#![allow(match_bool)]
|
|
||||||
// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref.
|
|
||||||
#![allow(clone_on_copy)]
|
|
||||||
|
|
||||||
|
// Clippy config
|
||||||
|
// TODO [todr] not really sure
|
||||||
|
#![cfg_attr(feature="dev", allow(needless_range_loop))]
|
||||||
|
// Shorter than if-else
|
||||||
|
#![cfg_attr(feature="dev", allow(match_bool))]
|
||||||
|
// Keeps consistency (all lines with `.clone()`) and helpful when changing ref to non-ref.
|
||||||
|
#![cfg_attr(feature="dev", allow(clone_on_copy))]
|
||||||
|
// In most cases it expresses function flow better
|
||||||
|
#![cfg_attr(feature="dev", allow(if_not_else))]
|
||||||
|
|
||||||
//! Ethcore library
|
//! Ethcore library
|
||||||
//!
|
//!
|
||||||
@ -42,23 +42,17 @@
|
|||||||
//! - Ubuntu 14.04 and later:
|
//! - Ubuntu 14.04 and later:
|
||||||
//!
|
//!
|
||||||
//! ```bash
|
//! ```bash
|
||||||
//! # install rocksdb
|
|
||||||
//! add-apt-repository "deb http://ppa.launchpad.net/giskou/librocksdb/ubuntu trusty main"
|
|
||||||
//! apt-get update
|
|
||||||
//! apt-get install -y --force-yes librocksdb
|
|
||||||
//!
|
//!
|
||||||
//! # install multirust
|
//! # install multirust
|
||||||
//! curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
//! curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes
|
||||||
//!
|
//!
|
||||||
//! # install nightly and make it default
|
|
||||||
//! multirust update nightly && multirust default nightly
|
|
||||||
//!
|
|
||||||
//! # export rust LIBRARY_PATH
|
//! # export rust LIBRARY_PATH
|
||||||
//! export LIBRARY_PATH=/usr/local/lib
|
//! export LIBRARY_PATH=/usr/local/lib
|
||||||
//!
|
//!
|
||||||
//! # download and build parity
|
//! # download and build parity
|
||||||
//! git clone https://github.com/ethcore/parity
|
//! git clone https://github.com/ethcore/parity
|
||||||
//! cd parity
|
//! cd parity
|
||||||
|
//! multirust override beta
|
||||||
//! cargo build --release
|
//! cargo build --release
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
@ -67,18 +61,15 @@
|
|||||||
//! ```bash
|
//! ```bash
|
||||||
//! # install rocksdb && multirust
|
//! # install rocksdb && multirust
|
||||||
//! brew update
|
//! brew update
|
||||||
//! brew install rocksdb
|
|
||||||
//! brew install multirust
|
//! brew install multirust
|
||||||
//!
|
//!
|
||||||
//! # install nightly and make it default
|
|
||||||
//! multirust update nightly && multirust default nightly
|
|
||||||
//!
|
|
||||||
//! # export rust LIBRARY_PATH
|
//! # export rust LIBRARY_PATH
|
||||||
//! export LIBRARY_PATH=/usr/local/lib
|
//! export LIBRARY_PATH=/usr/local/lib
|
||||||
//!
|
//!
|
||||||
//! # download and build parity
|
//! # download and build parity
|
||||||
//! git clone https://github.com/ethcore/parity
|
//! git clone https://github.com/ethcore/parity
|
||||||
//! cd parity
|
//! cd parity
|
||||||
|
//! multirust override beta
|
||||||
//! cargo build --release
|
//! cargo build --release
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
@ -86,36 +77,38 @@
|
|||||||
#[macro_use] extern crate ethcore_util as util;
|
#[macro_use] extern crate ethcore_util as util;
|
||||||
#[macro_use] extern crate lazy_static;
|
#[macro_use] extern crate lazy_static;
|
||||||
extern crate rustc_serialize;
|
extern crate rustc_serialize;
|
||||||
extern crate rocksdb;
|
#[macro_use] extern crate heapsize;
|
||||||
extern crate heapsize;
|
|
||||||
extern crate crypto;
|
extern crate crypto;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
extern crate env_logger;
|
extern crate env_logger;
|
||||||
extern crate num_cpus;
|
extern crate num_cpus;
|
||||||
extern crate crossbeam;
|
extern crate crossbeam;
|
||||||
|
extern crate ethjson;
|
||||||
|
|
||||||
|
#[cfg(test)] extern crate ethcore_devtools as devtools;
|
||||||
#[cfg(feature = "jit" )] extern crate evmjit;
|
#[cfg(feature = "jit" )] extern crate evmjit;
|
||||||
|
|
||||||
pub mod block;
|
pub mod block;
|
||||||
pub mod blockchain;
|
|
||||||
pub mod block_queue;
|
pub mod block_queue;
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod error;
|
pub mod error;
|
||||||
pub mod ethereum;
|
pub mod ethereum;
|
||||||
|
pub mod filter;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
pub mod service;
|
pub mod service;
|
||||||
|
pub mod log_entry;
|
||||||
|
pub mod trace;
|
||||||
pub mod spec;
|
pub mod spec;
|
||||||
pub mod transaction;
|
pub mod transaction;
|
||||||
pub mod views;
|
pub mod views;
|
||||||
pub mod receipt;
|
pub mod receipt;
|
||||||
|
pub mod pod_state;
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
mod basic_types;
|
mod basic_types;
|
||||||
#[macro_use] mod evm;
|
#[macro_use] mod evm;
|
||||||
mod log_entry;
|
|
||||||
mod env_info;
|
mod env_info;
|
||||||
mod pod_account;
|
mod pod_account;
|
||||||
mod pod_state;
|
|
||||||
mod account_diff;
|
mod account_diff;
|
||||||
mod state_diff;
|
mod state_diff;
|
||||||
mod engine;
|
mod engine;
|
||||||
@ -125,11 +118,13 @@ mod account_db;
|
|||||||
mod action_params;
|
mod action_params;
|
||||||
mod null_engine;
|
mod null_engine;
|
||||||
mod builtin;
|
mod builtin;
|
||||||
|
mod chainfilter;
|
||||||
mod extras;
|
mod extras;
|
||||||
mod substate;
|
mod substate;
|
||||||
mod executive;
|
mod executive;
|
||||||
mod externalities;
|
mod externalities;
|
||||||
mod verification;
|
mod verification;
|
||||||
|
mod blockchain;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -14,8 +14,11 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Block log.
|
||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
|
use header::BlockNumber;
|
||||||
|
|
||||||
/// A record of execution for a `LOG` operation.
|
/// A record of execution for a `LOG` operation.
|
||||||
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
#[derive(Default, Debug, Clone, PartialEq, Eq)]
|
||||||
@ -37,16 +40,25 @@ impl Encodable for LogEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LogEntry {
|
impl Decodable for LogEntry {
|
||||||
/// Create a new log entry.
|
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||||
pub fn new(address: Address, topics: Vec<H256>, data: Bytes) -> LogEntry {
|
let d = decoder.as_rlp();
|
||||||
LogEntry {
|
let entry = LogEntry {
|
||||||
address: address,
|
address: try!(d.val_at(0)),
|
||||||
topics: topics,
|
topics: try!(d.val_at(1)),
|
||||||
data: data
|
data: try!(d.val_at(2)),
|
||||||
}
|
};
|
||||||
|
Ok(entry)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapSizeOf for LogEntry {
|
||||||
|
fn heap_size_of_children(&self) -> usize {
|
||||||
|
self.topics.heap_size_of_children() + self.data.heap_size_of_children()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LogEntry {
|
||||||
/// Calculates the bloom of this log entry.
|
/// Calculates the bloom of this log entry.
|
||||||
pub fn bloom(&self) -> LogBloom {
|
pub fn bloom(&self) -> LogBloom {
|
||||||
self.topics.iter().fold(LogBloom::from_bloomed(&self.address.sha3()), |b, t| b.with_bloomed(&t.sha3()))
|
self.topics.iter().fold(LogBloom::from_bloomed(&self.address.sha3()), |b, t| b.with_bloomed(&t.sha3()))
|
||||||
@ -65,6 +77,31 @@ impl FromJson for LogEntry {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Log localized in a blockchain.
|
||||||
|
#[derive(Default, Debug, PartialEq, Clone)]
|
||||||
|
pub struct LocalizedLogEntry {
|
||||||
|
/// Plain log entry.
|
||||||
|
pub entry: LogEntry,
|
||||||
|
/// Block in which this log was created.
|
||||||
|
pub block_hash: H256,
|
||||||
|
/// Block number.
|
||||||
|
pub block_number: BlockNumber,
|
||||||
|
/// Hash of transaction in which this log was created.
|
||||||
|
pub transaction_hash: H256,
|
||||||
|
/// Index of transaction within block.
|
||||||
|
pub transaction_index: usize,
|
||||||
|
/// Log position in the block.
|
||||||
|
pub log_index: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Deref for LocalizedLogEntry {
|
||||||
|
type Target = LogEntry;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.entry
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use util::*;
|
use util::*;
|
||||||
@ -74,7 +111,11 @@ mod tests {
|
|||||||
fn test_empty_log_bloom() {
|
fn test_empty_log_bloom() {
|
||||||
let bloom = H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
let bloom = H2048::from_str("00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000").unwrap();
|
||||||
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
let address = Address::from_str("0f572e5295c57f15886f9b263e2f6d2d6c7b5ec6").unwrap();
|
||||||
let log = LogEntry::new(address, vec![], vec![]);
|
let log = LogEntry {
|
||||||
|
address: address,
|
||||||
|
topics: vec![],
|
||||||
|
data: vec![]
|
||||||
|
};
|
||||||
assert_eq!(log.bloom(), bloom);
|
assert_eq!(log.bloom(), bloom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,16 @@ impl Engine for NullEngine {
|
|||||||
fn vm_factory(&self) -> &Factory {
|
fn vm_factory(&self) -> &Factory {
|
||||||
&self.factory
|
&self.factory
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &str { "NullEngine" }
|
fn name(&self) -> &str { "NullEngine" }
|
||||||
|
|
||||||
fn spec(&self) -> &Spec { &self.spec }
|
fn spec(&self) -> &Spec { &self.spec }
|
||||||
fn schedule(&self, _env_info: &EnvInfo) -> Schedule { Schedule::new_frontier() }
|
|
||||||
|
fn schedule(&self, env_info: &EnvInfo) -> Schedule {
|
||||||
|
if env_info.number < self.u64_param("frontierCompatibilityModeLimit") {
|
||||||
|
Schedule::new_frontier()
|
||||||
|
} else {
|
||||||
|
Schedule::new_homestead()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
use util::*;
|
use util::*;
|
||||||
use account::*;
|
use account::*;
|
||||||
use account_db::*;
|
use account_db::*;
|
||||||
|
use ethjson;
|
||||||
|
|
||||||
#[derive(Debug,Clone,PartialEq,Eq)]
|
#[derive(Debug,Clone,PartialEq,Eq)]
|
||||||
/// An account, expressed as Plain-Old-Data (hence the name).
|
/// An account, expressed as Plain-Old-Data (hence the name).
|
||||||
@ -73,6 +74,22 @@ impl PodAccount {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ethjson::blockchain::Account> for PodAccount {
|
||||||
|
fn from(a: ethjson::blockchain::Account) -> Self {
|
||||||
|
PodAccount {
|
||||||
|
balance: a.balance.into(),
|
||||||
|
nonce: a.nonce.into(),
|
||||||
|
code: a.code.into(),
|
||||||
|
storage: a.storage.into_iter().fold(BTreeMap::new(), |mut acc, (key, value)| {
|
||||||
|
let key: U256 = key.into();
|
||||||
|
let value: U256 = value.into();
|
||||||
|
acc.insert(H256::from(key), H256::from(value));
|
||||||
|
acc
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for PodAccount {
|
impl fmt::Display for PodAccount {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "(bal={}; nonce={}; code={} bytes, #{}; storage={} items)", self.balance, self.nonce, self.code.len(), self.code.sha3(), self.storage.len())
|
write!(f, "(bal={}; nonce={}; code={} bytes, #{}; storage={} items)", self.balance, self.nonce, self.code.len(), self.code.sha3(), self.storage.len())
|
||||||
|
@ -14,11 +14,14 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! State of all accounts in the system expressed in Plain Old Data.
|
||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
use pod_account::*;
|
use pod_account::*;
|
||||||
|
use ethjson;
|
||||||
|
|
||||||
#[derive(Debug,Clone,PartialEq,Eq,Default)]
|
|
||||||
/// State of all accounts in the system expressed in Plain Old Data.
|
/// State of all accounts in the system expressed in Plain Old Data.
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||||
pub struct PodState (BTreeMap<Address, PodAccount>);
|
pub struct PodState (BTreeMap<Address, PodAccount>);
|
||||||
|
|
||||||
impl PodState {
|
impl PodState {
|
||||||
@ -64,6 +67,15 @@ impl FromJson for PodState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<ethjson::blockchain::State> for PodState {
|
||||||
|
fn from(s: ethjson::blockchain::State) -> PodState {
|
||||||
|
PodState(s.0.into_iter().fold(BTreeMap::new(), |mut acc, (key, value)| {
|
||||||
|
acc.insert(key.into(), PodAccount::from(value));
|
||||||
|
acc
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Display for PodState {
|
impl fmt::Display for PodState {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
for (add, acc) in &self.0 {
|
for (add, acc) in &self.0 {
|
||||||
|
@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
use basic_types::LogBloom;
|
use basic_types::LogBloom;
|
||||||
use log_entry::LogEntry;
|
use header::BlockNumber;
|
||||||
|
use log_entry::{LogEntry, LocalizedLogEntry};
|
||||||
|
|
||||||
/// Information describing execution of a transaction.
|
/// Information describing execution of a transaction.
|
||||||
#[derive(Default, Debug, Clone)]
|
#[derive(Default, Debug, Clone)]
|
||||||
@ -39,7 +40,7 @@ impl Receipt {
|
|||||||
Receipt {
|
Receipt {
|
||||||
state_root: state_root,
|
state_root: state_root,
|
||||||
gas_used: gas_used,
|
gas_used: gas_used,
|
||||||
log_bloom: logs.iter().fold(LogBloom::new(), |mut b, l| { b |= &l.bloom(); b }),
|
log_bloom: logs.iter().fold(LogBloom::new(), |mut b, l| { b = &b | &l.bloom(); b }), //TODO: use |= operator
|
||||||
logs: logs,
|
logs: logs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -55,6 +56,45 @@ impl Encodable for Receipt {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Decodable for Receipt {
|
||||||
|
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||||
|
let d = decoder.as_rlp();
|
||||||
|
let receipt = Receipt {
|
||||||
|
state_root: try!(d.val_at(0)),
|
||||||
|
gas_used: try!(d.val_at(1)),
|
||||||
|
log_bloom: try!(d.val_at(2)),
|
||||||
|
logs: try!(d.val_at(3)),
|
||||||
|
};
|
||||||
|
Ok(receipt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HeapSizeOf for Receipt {
|
||||||
|
fn heap_size_of_children(&self) -> usize {
|
||||||
|
self.logs.heap_size_of_children()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Receipt with additional info.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct LocalizedReceipt {
|
||||||
|
/// Transaction hash.
|
||||||
|
pub transaction_hash: H256,
|
||||||
|
/// Transaction index.
|
||||||
|
pub transaction_index: usize,
|
||||||
|
/// Block hash.
|
||||||
|
pub block_hash: H256,
|
||||||
|
/// Block number.
|
||||||
|
pub block_number: BlockNumber,
|
||||||
|
/// Cumulative gas used.
|
||||||
|
pub cumulative_gas_used: U256,
|
||||||
|
/// Gas used.
|
||||||
|
pub gas_used: U256,
|
||||||
|
/// Contract address.
|
||||||
|
pub contract_address: Option<Address>,
|
||||||
|
/// Logs
|
||||||
|
pub logs: Vec<LocalizedLogEntry>,
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_basic() {
|
fn test_basic() {
|
||||||
@ -62,11 +102,11 @@ fn test_basic() {
|
|||||||
let r = Receipt::new(
|
let r = Receipt::new(
|
||||||
x!("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee"),
|
x!("2f697d671e9ae4ee24a43c4b0d7e15f1cb4ba6de1561120d43b9a4e8c4a8a6ee"),
|
||||||
x!(0x40cae),
|
x!(0x40cae),
|
||||||
vec![LogEntry::new(
|
vec![LogEntry {
|
||||||
x!("dcf421d093428b096ca501a7cd1a740855a7976f"),
|
address: x!("dcf421d093428b096ca501a7cd1a740855a7976f"),
|
||||||
vec![],
|
topics: vec![],
|
||||||
vec![0u8; 32]
|
data: vec![0u8; 32]
|
||||||
)]
|
}]
|
||||||
);
|
);
|
||||||
assert_eq!(&encode(&r)[..], &expected[..]);
|
assert_eq!(&encode(&r)[..], &expected[..]);
|
||||||
}
|
}
|
||||||
|
@ -20,13 +20,24 @@ use util::*;
|
|||||||
use util::panics::*;
|
use util::panics::*;
|
||||||
use spec::Spec;
|
use spec::Spec;
|
||||||
use error::*;
|
use error::*;
|
||||||
use client::Client;
|
use client::{Client, ClientConfig};
|
||||||
|
|
||||||
/// Message type for external and internal events
|
/// Message type for external and internal events
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub enum SyncMessage {
|
pub enum SyncMessage {
|
||||||
/// New block has been imported into the blockchain
|
/// New block has been imported into the blockchain
|
||||||
NewChainBlock(Bytes), //TODO: use Cow
|
NewChainBlocks {
|
||||||
|
/// Hashes of blocks imported to blockchain
|
||||||
|
imported: Vec<H256>,
|
||||||
|
/// Hashes of blocks not imported to blockchain (because were invalid)
|
||||||
|
invalid: Vec<H256>,
|
||||||
|
/// Hashes of blocks that were removed from canonical chain
|
||||||
|
retracted: Vec<H256>,
|
||||||
|
/// Hashes of blocks that are now included in cannonical chain
|
||||||
|
enacted: Vec<H256>,
|
||||||
|
},
|
||||||
|
/// Best Block Hash in chain has been changed
|
||||||
|
NewChainHead,
|
||||||
/// A block is ready
|
/// A block is ready
|
||||||
BlockVerified,
|
BlockVerified,
|
||||||
}
|
}
|
||||||
@ -43,14 +54,14 @@ pub struct ClientService {
|
|||||||
|
|
||||||
impl ClientService {
|
impl ClientService {
|
||||||
/// Start the service in a separate thread.
|
/// Start the service in a separate thread.
|
||||||
pub fn start(spec: Spec, net_config: NetworkConfiguration, db_path: &Path) -> Result<ClientService, Error> {
|
pub fn start(config: ClientConfig, spec: Spec, net_config: NetworkConfiguration, db_path: &Path) -> Result<ClientService, Error> {
|
||||||
let panic_handler = PanicHandler::new_in_arc();
|
let panic_handler = PanicHandler::new_in_arc();
|
||||||
let mut net_service = try!(NetworkService::start(net_config));
|
let mut net_service = try!(NetworkService::start(net_config));
|
||||||
panic_handler.forward_from(&net_service);
|
panic_handler.forward_from(&net_service);
|
||||||
|
|
||||||
info!("Starting {}", net_service.host_info());
|
info!("Starting {}", net_service.host_info());
|
||||||
info!("Configured for {} using {} engine", spec.name, spec.engine_name);
|
info!("Configured for {} using {} engine", spec.name, spec.engine_name);
|
||||||
let client = try!(Client::new(spec, db_path, net_service.io().channel()));
|
let client = try!(Client::new(config, spec, db_path, net_service.io().channel()));
|
||||||
panic_handler.forward_from(client.deref());
|
panic_handler.forward_from(client.deref());
|
||||||
let client_io = Arc::new(ClientIoHandler {
|
let client_io = Arc::new(ClientIoHandler {
|
||||||
client: client.clone()
|
client: client.clone()
|
||||||
@ -110,12 +121,11 @@ impl IoHandler<NetSyncMessage> for ClientIoHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(match_ref_pats)]
|
#[cfg_attr(feature="dev", allow(single_match))]
|
||||||
#[allow(single_match)]
|
|
||||||
fn message(&self, io: &IoContext<NetSyncMessage>, net_message: &NetSyncMessage) {
|
fn message(&self, io: &IoContext<NetSyncMessage>, net_message: &NetSyncMessage) {
|
||||||
if let &UserMessage(ref message) = net_message {
|
if let UserMessage(ref message) = *net_message {
|
||||||
match message {
|
match *message {
|
||||||
&SyncMessage::BlockVerified => {
|
SyncMessage::BlockVerified => {
|
||||||
self.client.import_verified_blocks(&io.channel());
|
self.client.import_verified_blocks(&io.channel());
|
||||||
},
|
},
|
||||||
_ => {}, // ignore other messages
|
_ => {}, // ignore other messages
|
||||||
@ -129,12 +139,14 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use util::network::*;
|
use util::network::*;
|
||||||
|
use devtools::*;
|
||||||
|
use client::ClientConfig;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn it_can_be_started() {
|
fn it_can_be_started() {
|
||||||
let spec = get_test_spec();
|
let spec = get_test_spec();
|
||||||
let temp_path = RandomTempPath::new();
|
let temp_path = RandomTempPath::new();
|
||||||
let service = ClientService::start(spec, NetworkConfiguration::new(), &temp_path.as_path());
|
let service = ClientService::start(ClientConfig::default(), spec, NetworkConfiguration::new_local(), &temp_path.as_path());
|
||||||
assert!(service.is_ok());
|
assert!(service.is_ok());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
91
ethcore/src/spec/genesis.rs
Normal file
91
ethcore/src/spec/genesis.rs
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use util::rlp::*;
|
||||||
|
use util::numbers::{Uint, U256};
|
||||||
|
use util::hash::{H64, Address, H256};
|
||||||
|
use ethjson;
|
||||||
|
|
||||||
|
/// Genesis seal type.
|
||||||
|
pub enum Seal {
|
||||||
|
/// Classic ethereum seal.
|
||||||
|
Ethereum {
|
||||||
|
/// Seal nonce.
|
||||||
|
nonce: H64,
|
||||||
|
/// Seal mix hash.
|
||||||
|
mix_hash: H256,
|
||||||
|
},
|
||||||
|
/// Generic seal.
|
||||||
|
Generic {
|
||||||
|
/// Number of seal fields.
|
||||||
|
fields: usize,
|
||||||
|
/// Seal rlp.
|
||||||
|
rlp: Vec<u8>,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Genesis components.
|
||||||
|
pub struct Genesis {
|
||||||
|
/// Seal.
|
||||||
|
pub seal: Seal,
|
||||||
|
/// Difficulty.
|
||||||
|
pub difficulty: U256,
|
||||||
|
/// Author.
|
||||||
|
pub author: Address,
|
||||||
|
/// Timestamp.
|
||||||
|
pub timestamp: u64,
|
||||||
|
/// Parent hash.
|
||||||
|
pub parent_hash: H256,
|
||||||
|
/// Gas limit.
|
||||||
|
pub gas_limit: U256,
|
||||||
|
/// Transactions root.
|
||||||
|
pub transactions_root: H256,
|
||||||
|
/// Receipts root.
|
||||||
|
pub receipts_root: H256,
|
||||||
|
/// State root.
|
||||||
|
pub state_root: Option<H256>,
|
||||||
|
/// Gas used.
|
||||||
|
pub gas_used: U256,
|
||||||
|
/// Extra data.
|
||||||
|
pub extra_data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<ethjson::spec::Genesis> for Genesis {
|
||||||
|
fn from(g: ethjson::spec::Genesis) -> Self {
|
||||||
|
Genesis {
|
||||||
|
seal: match (g.nonce, g.mix_hash) {
|
||||||
|
(Some(nonce), Some(mix_hash)) => Seal::Ethereum {
|
||||||
|
nonce: nonce.into(),
|
||||||
|
mix_hash: mix_hash.into(),
|
||||||
|
},
|
||||||
|
_ => Seal::Generic {
|
||||||
|
fields: g.seal_fields.unwrap(),
|
||||||
|
rlp: g.seal_rlp.unwrap().into(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
difficulty: g.difficulty.into(),
|
||||||
|
author: g.author.into(),
|
||||||
|
timestamp: g.timestamp.into(),
|
||||||
|
parent_hash: g.parent_hash.into(),
|
||||||
|
gas_limit: g.gas_limit.into(),
|
||||||
|
transactions_root: g.transactions_root.map_or_else(|| SHA3_NULL_RLP.clone(), Into::into),
|
||||||
|
receipts_root: g.receipts_root.map_or_else(|| SHA3_NULL_RLP.clone(), Into::into),
|
||||||
|
state_root: g.state_root.map(Into::into),
|
||||||
|
gas_used: g.gas_used.map_or_else(U256::zero, Into::into),
|
||||||
|
extra_data: g.extra_data.map_or_else(Vec::new, Into::into),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
ethcore/src/spec/mod.rs
Normal file
23
ethcore/src/spec/mod.rs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Blockchain params.
|
||||||
|
|
||||||
|
mod genesis;
|
||||||
|
pub mod spec;
|
||||||
|
|
||||||
|
pub use self::spec::*;
|
||||||
|
pub use self::genesis::Genesis;
|
@ -21,6 +21,8 @@ use engine::*;
|
|||||||
use pod_state::*;
|
use pod_state::*;
|
||||||
use null_engine::*;
|
use null_engine::*;
|
||||||
use account_db::*;
|
use account_db::*;
|
||||||
|
use ethereum;
|
||||||
|
use super::genesis::{Seal as GenesisSeal, Genesis};
|
||||||
|
|
||||||
/// Convert JSON value to equivalent RLP representation.
|
/// Convert JSON value to equivalent RLP representation.
|
||||||
// TODO: handle container types.
|
// TODO: handle container types.
|
||||||
@ -58,6 +60,8 @@ pub struct Spec {
|
|||||||
|
|
||||||
/// Known nodes on the network in enode format.
|
/// Known nodes on the network in enode format.
|
||||||
pub nodes: Vec<String>,
|
pub nodes: Vec<String>,
|
||||||
|
/// Network ID
|
||||||
|
pub network_id: U256,
|
||||||
|
|
||||||
/// Parameters concerning operation of the specific engine we're using.
|
/// Parameters concerning operation of the specific engine we're using.
|
||||||
/// Maps the parameter name to an RLP-encoded value.
|
/// Maps the parameter name to an RLP-encoded value.
|
||||||
@ -97,14 +101,14 @@ pub struct Spec {
|
|||||||
genesis_state: PodState,
|
genesis_state: PodState,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(wrong_self_convention)] // because to_engine(self) should be to_engine(&self)
|
#[cfg_attr(feature="dev", allow(wrong_self_convention))] // because to_engine(self) should be to_engine(&self)
|
||||||
impl Spec {
|
impl Spec {
|
||||||
/// Convert this object into a boxed Engine of the right underlying type.
|
/// Convert this object into a boxed Engine of the right underlying type.
|
||||||
// TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead.
|
// TODO avoid this hard-coded nastiness - use dynamic-linked plugin framework instead.
|
||||||
pub fn to_engine(self) -> Result<Box<Engine>, Error> {
|
pub fn to_engine(self) -> Result<Box<Engine>, Error> {
|
||||||
match self.engine_name.as_ref() {
|
match self.engine_name.as_ref() {
|
||||||
"NullEngine" => Ok(NullEngine::new_boxed(self)),
|
"NullEngine" => Ok(NullEngine::new_boxed(self)),
|
||||||
"Ethash" => Ok(super::ethereum::Ethash::new_boxed(self)),
|
"Ethash" => Ok(ethereum::Ethash::new_boxed(self)),
|
||||||
_ => Err(Error::UnknownEngineName(self.engine_name.clone()))
|
_ => Err(Error::UnknownEngineName(self.engine_name.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,6 +124,9 @@ impl Spec {
|
|||||||
/// Get the known knodes of the network in enode format.
|
/// Get the known knodes of the network in enode format.
|
||||||
pub fn nodes(&self) -> &Vec<String> { &self.nodes }
|
pub fn nodes(&self) -> &Vec<String> { &self.nodes }
|
||||||
|
|
||||||
|
/// Get the configured Network ID.
|
||||||
|
pub fn network_id(&self) -> U256 { self.network_id }
|
||||||
|
|
||||||
/// Get the header of the genesis block.
|
/// Get the header of the genesis block.
|
||||||
pub fn genesis_header(&self) -> Header {
|
pub fn genesis_header(&self) -> Header {
|
||||||
Header {
|
Header {
|
||||||
@ -131,7 +138,7 @@ impl Spec {
|
|||||||
uncles_hash: RlpStream::new_list(0).out().sha3(),
|
uncles_hash: RlpStream::new_list(0).out().sha3(),
|
||||||
extra_data: self.extra_data.clone(),
|
extra_data: self.extra_data.clone(),
|
||||||
state_root: self.state_root().clone(),
|
state_root: self.state_root().clone(),
|
||||||
receipts_root: self.receipts_root.clone(),
|
receipts_root: self.receipts_root.clone(),
|
||||||
log_bloom: H2048::new().clone(),
|
log_bloom: H2048::new().clone(),
|
||||||
gas_used: self.gas_used.clone(),
|
gas_used: self.gas_used.clone(),
|
||||||
gas_limit: self.gas_limit.clone(),
|
gas_limit: self.gas_limit.clone(),
|
||||||
@ -177,7 +184,7 @@ impl Spec {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.parent_hash = H256::from_json(&genesis["parentHash"]);
|
self.parent_hash = H256::from_json(&genesis["parentHash"]);
|
||||||
self.transactions_root = genesis.find("transactionsTrie").and_then(|_| Some(H256::from_json(&genesis["transactionsTrie"]))).unwrap_or(SHA3_NULL_RLP.clone());
|
self.transactions_root = genesis.find("transactionsTrie").and_then(|_| Some(H256::from_json(&genesis["transactionsTrie"]))).unwrap_or(SHA3_NULL_RLP.clone());
|
||||||
self.receipts_root = genesis.find("receiptTrie").and_then(|_| Some(H256::from_json(&genesis["receiptTrie"]))).unwrap_or(SHA3_NULL_RLP.clone());
|
self.receipts_root = genesis.find("receiptTrie").and_then(|_| Some(H256::from_json(&genesis["receiptTrie"]))).unwrap_or(SHA3_NULL_RLP.clone());
|
||||||
@ -192,6 +199,32 @@ impl Spec {
|
|||||||
self.state_root_memo = RwLock::new(genesis.find("stateRoot").and_then(|_| Some(H256::from_json(&genesis["stateRoot"]))));
|
self.state_root_memo = RwLock::new(genesis.find("stateRoot").and_then(|_| Some(H256::from_json(&genesis["stateRoot"]))));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Overwrite the genesis components.
|
||||||
|
pub fn overwrite_genesis_params(&mut self, g: Genesis) {
|
||||||
|
let (seal_fields, seal_rlp) = match g.seal {
|
||||||
|
GenesisSeal::Generic { fields, rlp } => (fields, rlp),
|
||||||
|
GenesisSeal::Ethereum { nonce, mix_hash } => {
|
||||||
|
let mut s = RlpStream::new();
|
||||||
|
s.append(&mix_hash);
|
||||||
|
s.append(&nonce);
|
||||||
|
(2, s.out())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
self.parent_hash = g.parent_hash;
|
||||||
|
self.transactions_root = g.transactions_root;
|
||||||
|
self.receipts_root = g.receipts_root;
|
||||||
|
self.author = g.author;
|
||||||
|
self.difficulty = g.difficulty;
|
||||||
|
self.gas_limit = g.gas_limit;
|
||||||
|
self.gas_used = g.gas_used;
|
||||||
|
self.timestamp = g.timestamp;
|
||||||
|
self.extra_data = g.extra_data;
|
||||||
|
self.seal_fields = seal_fields;
|
||||||
|
self.seal_rlp = seal_rlp;
|
||||||
|
self.state_root_memo = RwLock::new(g.state_root);
|
||||||
|
}
|
||||||
|
|
||||||
/// Alter the value of the genesis state.
|
/// Alter the value of the genesis state.
|
||||||
pub fn set_genesis_state(&mut self, s: PodState) {
|
pub fn set_genesis_state(&mut self, s: PodState) {
|
||||||
self.genesis_state = s;
|
self.genesis_state = s;
|
||||||
@ -244,12 +277,13 @@ impl FromJson for Spec {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Spec {
|
Spec {
|
||||||
name: json.find("name").map_or("unknown", |j| j.as_string().unwrap()).to_owned(),
|
name: json.find("name").map_or("unknown", |j| j.as_string().unwrap()).to_owned(),
|
||||||
engine_name: json["engineName"].as_string().unwrap().to_owned(),
|
engine_name: json["engineName"].as_string().unwrap().to_owned(),
|
||||||
engine_params: json_to_rlp_map(&json["params"]),
|
engine_params: json_to_rlp_map(&json["params"]),
|
||||||
nodes: nodes,
|
nodes: nodes,
|
||||||
|
network_id: U256::from_str(&json["params"]["networkID"].as_string().unwrap()[2..]).unwrap(),
|
||||||
builtins: builtins,
|
builtins: builtins,
|
||||||
parent_hash: H256::from_str(&genesis["parentHash"].as_string().unwrap()[2..]).unwrap(),
|
parent_hash: H256::from_str(&genesis["parentHash"].as_string().unwrap()[2..]).unwrap(),
|
||||||
author: Address::from_str(&genesis["author"].as_string().unwrap()[2..]).unwrap(),
|
author: Address::from_str(&genesis["author"].as_string().unwrap()[2..]).unwrap(),
|
||||||
@ -272,7 +306,7 @@ impl Spec {
|
|||||||
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
/// Ensure that the given state DB has the trie nodes in for the genesis state.
|
||||||
pub fn ensure_db_good(&self, db: &mut HashDB) -> bool {
|
pub fn ensure_db_good(&self, db: &mut HashDB) -> bool {
|
||||||
if !db.contains(&self.state_root()) {
|
if !db.contains(&self.state_root()) {
|
||||||
let mut root = H256::new();
|
let mut root = H256::new();
|
||||||
{
|
{
|
||||||
let mut t = SecTrieDBMut::new(db, &mut root);
|
let mut t = SecTrieDBMut::new(db, &mut root);
|
||||||
for (address, account) in self.genesis_state.get().iter() {
|
for (address, account) in self.genesis_state.get().iter() {
|
||||||
@ -298,7 +332,10 @@ impl Spec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new Spec which conforms to the Morden chain except that it's a NullEngine consensus.
|
/// Create a new Spec which conforms to the Morden chain except that it's a NullEngine consensus.
|
||||||
pub fn new_test() -> Spec { Self::from_json_utf8(include_bytes!("../res/null_morden.json")) }
|
pub fn new_test() -> Spec { Self::from_json_utf8(include_bytes!("../../res/null_morden.json")) }
|
||||||
|
|
||||||
|
/// Create a new Spec which conforms to the Morden chain except that it's a NullEngine consensus.
|
||||||
|
pub fn new_homestead_test() -> Spec { Self::from_json_utf8(include_bytes!("../../res/null_homestead_morden.json")) }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
@ -26,12 +26,20 @@ use pod_account::*;
|
|||||||
use pod_state::PodState;
|
use pod_state::PodState;
|
||||||
//use state_diff::*; // TODO: uncomment once to_pod() works correctly.
|
//use state_diff::*; // TODO: uncomment once to_pod() works correctly.
|
||||||
|
|
||||||
|
/// Used to return information about an `State::apply` operation.
|
||||||
|
pub struct ApplyOutcome {
|
||||||
|
/// The receipt for the applied transaction.
|
||||||
|
pub receipt: Receipt,
|
||||||
|
/// The trace for the applied transaction, if None if tracing is disabled.
|
||||||
|
pub trace: Option<Trace>,
|
||||||
|
}
|
||||||
|
|
||||||
/// Result type for the execution ("application") of a transaction.
|
/// Result type for the execution ("application") of a transaction.
|
||||||
pub type ApplyResult = Result<Receipt, Error>;
|
pub type ApplyResult = Result<ApplyOutcome, Error>;
|
||||||
|
|
||||||
/// Representation of the entire state of all accounts in the system.
|
/// Representation of the entire state of all accounts in the system.
|
||||||
pub struct State {
|
pub struct State {
|
||||||
db: JournalDB,
|
db: Box<JournalDB>,
|
||||||
root: H256,
|
root: H256,
|
||||||
cache: RefCell<HashMap<Address, Option<Account>>>,
|
cache: RefCell<HashMap<Address, Option<Account>>>,
|
||||||
snapshots: RefCell<Vec<HashMap<Address, Option<Option<Account>>>>>,
|
snapshots: RefCell<Vec<HashMap<Address, Option<Option<Account>>>>>,
|
||||||
@ -41,11 +49,11 @@ pub struct State {
|
|||||||
impl State {
|
impl State {
|
||||||
/// Creates new state with empty state root
|
/// Creates new state with empty state root
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn new(mut db: JournalDB, account_start_nonce: U256) -> State {
|
pub fn new(mut db: Box<JournalDB>, account_start_nonce: U256) -> State {
|
||||||
let mut root = H256::new();
|
let mut root = H256::new();
|
||||||
{
|
{
|
||||||
// init trie and reset root too null
|
// init trie and reset root too null
|
||||||
let _ = SecTrieDBMut::new(&mut db, &mut root);
|
let _ = SecTrieDBMut::new(db.as_hashdb_mut(), &mut root);
|
||||||
}
|
}
|
||||||
|
|
||||||
State {
|
State {
|
||||||
@ -58,10 +66,10 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates new state with existing state root
|
/// Creates new state with existing state root
|
||||||
pub fn from_existing(db: JournalDB, root: H256, account_start_nonce: U256) -> State {
|
pub fn from_existing(db: Box<JournalDB>, root: H256, account_start_nonce: U256) -> State {
|
||||||
{
|
{
|
||||||
// trie should panic! if root does not exist
|
// trie should panic! if root does not exist
|
||||||
let _ = SecTrieDB::new(&db, &root);
|
let _ = SecTrieDB::new(db.as_hashdb(), &root);
|
||||||
}
|
}
|
||||||
|
|
||||||
State {
|
State {
|
||||||
@ -126,7 +134,7 @@ impl State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Destroy the current object and return root and database.
|
/// Destroy the current object and return root and database.
|
||||||
pub fn drop(self) -> (H256, JournalDB) {
|
pub fn drop(self) -> (H256, Box<JournalDB>) {
|
||||||
(self.root, self.db)
|
(self.root, self.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,7 +146,7 @@ impl State {
|
|||||||
/// Create a new contract at address `contract`. If there is already an account at the address
|
/// Create a new contract at address `contract`. If there is already an account at the address
|
||||||
/// it will have its code reset, ready for `init_code()`.
|
/// it will have its code reset, ready for `init_code()`.
|
||||||
pub fn new_contract(&mut self, contract: &Address, balance: U256) {
|
pub fn new_contract(&mut self, contract: &Address, balance: U256) {
|
||||||
self.insert_cache(&contract, Some(Account::new_contract(balance)));
|
self.insert_cache(&contract, Some(Account::new_contract(balance, self.account_start_nonce)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Remove an existing account.
|
/// Remove an existing account.
|
||||||
@ -148,7 +156,7 @@ impl State {
|
|||||||
|
|
||||||
/// Determine whether an account exists.
|
/// Determine whether an account exists.
|
||||||
pub fn exists(&self, a: &Address) -> bool {
|
pub fn exists(&self, a: &Address) -> bool {
|
||||||
self.cache.borrow().get(&a).unwrap_or(&None).is_some() || SecTrieDB::new(&self.db, &self.root).contains(&a)
|
self.cache.borrow().get(&a).unwrap_or(&None).is_some() || SecTrieDB::new(self.db.as_hashdb(), &self.root).contains(&a)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the balance of account `a`.
|
/// Get the balance of account `a`.
|
||||||
@ -163,7 +171,7 @@ impl State {
|
|||||||
|
|
||||||
/// Mutate storage of account `address` so that it is `value` for `key`.
|
/// Mutate storage of account `address` so that it is `value` for `key`.
|
||||||
pub fn storage_at(&self, address: &Address, key: &H256) -> H256 {
|
pub fn storage_at(&self, address: &Address, key: &H256) -> H256 {
|
||||||
self.get(address, false).as_ref().map_or(H256::new(), |a|a.storage_at(&AccountDB::new(&self.db, address), key))
|
self.get(address, false).as_ref().map_or(H256::new(), |a|a.storage_at(&AccountDB::new(self.db.as_hashdb(), address), key))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Mutate storage of account `a` so that it is `value` for `key`.
|
/// Mutate storage of account `a` so that it is `value` for `key`.
|
||||||
@ -204,27 +212,27 @@ impl State {
|
|||||||
/// Initialise the code of account `a` so that it is `value` for `key`.
|
/// Initialise the code of account `a` so that it is `value` for `key`.
|
||||||
/// NOTE: Account should have been created with `new_contract`.
|
/// NOTE: Account should have been created with `new_contract`.
|
||||||
pub fn init_code(&mut self, a: &Address, code: Bytes) {
|
pub fn init_code(&mut self, a: &Address, code: Bytes) {
|
||||||
self.require_or_from(a, true, || Account::new_contract(U256::from(0u8)), |_|{}).init_code(code);
|
self.require_or_from(a, true, || Account::new_contract(x!(0), self.account_start_nonce), |_|{}).init_code(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a given transaction.
|
/// Execute a given transaction.
|
||||||
/// This will change the state accordingly.
|
/// This will change the state accordingly.
|
||||||
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &SignedTransaction) -> ApplyResult {
|
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, t: &SignedTransaction, tracing: bool) -> ApplyResult {
|
||||||
// let old = self.to_pod();
|
// let old = self.to_pod();
|
||||||
|
|
||||||
let e = try!(Executive::new(self, env_info, engine).transact(t));
|
let e = try!(Executive::new(self, env_info, engine).transact(t, tracing));
|
||||||
|
|
||||||
// TODO uncomment once to_pod() works correctly.
|
// TODO uncomment once to_pod() works correctly.
|
||||||
// trace!("Applied transaction. Diff:\n{}\n", StateDiff::diff_pod(&old, &self.to_pod()));
|
// trace!("Applied transaction. Diff:\n{}\n", StateDiff::diff_pod(&old, &self.to_pod()));
|
||||||
self.commit();
|
self.commit();
|
||||||
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
let receipt = Receipt::new(self.root().clone(), e.cumulative_gas_used, e.logs);
|
||||||
// trace!("Transaction receipt: {:?}", receipt);
|
// trace!("Transaction receipt: {:?}", receipt);
|
||||||
Ok(receipt)
|
Ok(ApplyOutcome{receipt: receipt, trace: e.trace})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit.
|
/// Commit accounts to SecTrieDBMut. This is similar to cpp-ethereum's dev::eth::commit.
|
||||||
/// `accounts` is mutable because we may need to commit the code or storage and record that.
|
/// `accounts` is mutable because we may need to commit the code or storage and record that.
|
||||||
#[allow(match_ref_pats)]
|
#[cfg_attr(feature="dev", allow(match_ref_pats))]
|
||||||
pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap<Address, Option<Account>>) {
|
pub fn commit_into(db: &mut HashDB, root: &mut H256, accounts: &mut HashMap<Address, Option<Account>>) {
|
||||||
// first, commit the sub trees.
|
// first, commit the sub trees.
|
||||||
// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?
|
// TODO: is this necessary or can we dispense with the `ref mut a` for just `a`?
|
||||||
@ -253,7 +261,7 @@ impl State {
|
|||||||
/// Commits our cached account changes into the trie.
|
/// Commits our cached account changes into the trie.
|
||||||
pub fn commit(&mut self) {
|
pub fn commit(&mut self) {
|
||||||
assert!(self.snapshots.borrow().is_empty());
|
assert!(self.snapshots.borrow().is_empty());
|
||||||
Self::commit_into(&mut self.db, &mut self.root, self.cache.borrow_mut().deref_mut());
|
Self::commit_into(self.db.as_hashdb_mut(), &mut self.root, self.cache.borrow_mut().deref_mut());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -282,30 +290,30 @@ impl State {
|
|||||||
|
|
||||||
/// Pull account `a` in our cache from the trie DB and return it.
|
/// Pull account `a` in our cache from the trie DB and return it.
|
||||||
/// `require_code` requires that the code be cached, too.
|
/// `require_code` requires that the code be cached, too.
|
||||||
fn get(&self, a: &Address, require_code: bool) -> Ref<Option<Account>> {
|
fn get<'a>(&'a self, a: &Address, require_code: bool) -> &'a Option<Account> {
|
||||||
let have_key = self.cache.borrow().contains_key(a);
|
let have_key = self.cache.borrow().contains_key(a);
|
||||||
if !have_key {
|
if !have_key {
|
||||||
self.insert_cache(a, SecTrieDB::new(&self.db, &self.root).get(&a).map(Account::from_rlp))
|
self.insert_cache(a, SecTrieDB::new(self.db.as_hashdb(), &self.root).get(&a).map(Account::from_rlp))
|
||||||
}
|
}
|
||||||
if require_code {
|
if require_code {
|
||||||
if let Some(ref mut account) = self.cache.borrow_mut().get_mut(a).unwrap().as_mut() {
|
if let Some(ref mut account) = self.cache.borrow_mut().get_mut(a).unwrap().as_mut() {
|
||||||
account.cache_code(&AccountDB::new(&self.db, a));
|
account.cache_code(&AccountDB::new(self.db.as_hashdb(), a));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ref::map(self.cache.borrow(), |m| m.get(a).unwrap())
|
unsafe { ::std::mem::transmute(self.cache.borrow().get(a).unwrap()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
|
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
|
||||||
fn require(&self, a: &Address, require_code: bool) -> RefMut<Account> {
|
fn require<'a>(&'a self, a: &Address, require_code: bool) -> &'a mut Account {
|
||||||
self.require_or_from(a, require_code, || Account::new_basic(U256::from(0u8), self.account_start_nonce), |_|{})
|
self.require_or_from(a, require_code, || Account::new_basic(U256::from(0u8), self.account_start_nonce), |_|{})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
|
/// Pull account `a` in our cache from the trie DB. `require_code` requires that the code be cached, too.
|
||||||
/// If it doesn't exist, make account equal the evaluation of `default`.
|
/// If it doesn't exist, make account equal the evaluation of `default`.
|
||||||
fn require_or_from<F: FnOnce() -> Account, G: FnOnce(&mut Account)>(&self, a: &Address, require_code: bool, default: F, not_default: G) -> RefMut<Account> {
|
fn require_or_from<'a, F: FnOnce() -> Account, G: FnOnce(&mut Account)>(&self, a: &Address, require_code: bool, default: F, not_default: G) -> &'a mut Account {
|
||||||
let have_key = self.cache.borrow().contains_key(a);
|
let have_key = self.cache.borrow().contains_key(a);
|
||||||
if !have_key {
|
if !have_key {
|
||||||
self.insert_cache(a, SecTrieDB::new(&self.db, &self.root).get(&a).map(Account::from_rlp))
|
self.insert_cache(a, SecTrieDB::new(self.db.as_hashdb(), &self.root).get(&a).map(Account::from_rlp))
|
||||||
} else {
|
} else {
|
||||||
self.note_cache(a);
|
self.note_cache(a);
|
||||||
}
|
}
|
||||||
@ -316,13 +324,12 @@ impl State {
|
|||||||
not_default(self.cache.borrow_mut().get_mut(a).unwrap().as_mut().unwrap());
|
not_default(self.cache.borrow_mut().get_mut(a).unwrap().as_mut().unwrap());
|
||||||
}
|
}
|
||||||
|
|
||||||
let b = self.cache.borrow_mut();
|
unsafe { ::std::mem::transmute(self.cache.borrow_mut().get_mut(a).unwrap().as_mut().map(|account| {
|
||||||
RefMut::map(b, |m| m.get_mut(a).unwrap().as_mut().map(|account| {
|
|
||||||
if require_code {
|
if require_code {
|
||||||
account.cache_code(&AccountDB::new(&self.db, a));
|
account.cache_code(&AccountDB::new(self.db.as_hashdb(), a));
|
||||||
}
|
}
|
||||||
account
|
account
|
||||||
}).unwrap())
|
}).unwrap()) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -336,12 +343,671 @@ impl fmt::Debug for State {
|
|||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use util::hash::*;
|
use util::common::*;
|
||||||
use util::trie::*;
|
use util::trie::*;
|
||||||
use util::rlp::*;
|
use util::rlp::*;
|
||||||
use util::uint::*;
|
|
||||||
use account::*;
|
use account::*;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
|
use devtools::*;
|
||||||
|
use evm::factory::*;
|
||||||
|
use env_info::*;
|
||||||
|
use spec::*;
|
||||||
|
use transaction::*;
|
||||||
|
use util::log::init_log;
|
||||||
|
use trace::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_apply_create_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Create,
|
||||||
|
value: x!(100),
|
||||||
|
data: FromHex::from_hex("601080600c6000396000f3006000355415600957005b60203560003555").unwrap(),
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Create(TraceCreate {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(77412),
|
||||||
|
init: vec![96, 16, 128, 96, 12, 96, 0, 57, 96, 0, 243, 0, 96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53, 85],
|
||||||
|
result: Some((x!(3224), x!("8988167e088c87cd314df6d3c2b83da5acb93ace"), vec![96, 0, 53, 84, 21, 96, 9, 87, 0, 91, 96, 32, 53, 96, 0, 53]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_failed_create_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Create,
|
||||||
|
value: x!(100),
|
||||||
|
data: FromHex::from_hex("5b600056").unwrap(),
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Create(TraceCreate {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(78792),
|
||||||
|
init: vec![91, 96, 0, 86],
|
||||||
|
result: None
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_call_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(100),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("6000").unwrap());
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(3), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_basic_call_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(100),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(0), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_not_trace_call_transaction_to_builtin() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = Spec::new_test().to_engine().unwrap();
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0x1)),
|
||||||
|
value: x!(0),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
let result = state.apply(&info, engine.deref(), &t, true).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(result.trace, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_not_trace_subcall_transaction_to_builtin() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = Spec::new_test().to_engine().unwrap();
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(0),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("600060006000600060006001610be0f1").unwrap());
|
||||||
|
let result = state.apply(&info, engine.deref(), &t, true).unwrap();
|
||||||
|
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(0),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(28061), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_not_trace_callcode() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = Spec::new_test().to_engine().unwrap();
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(0),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b611000f2").unwrap());
|
||||||
|
state.init_code(&x!(0xb), FromHex::from_hex("6000").unwrap());
|
||||||
|
let result = state.apply(&info, engine.deref(), &t, true).unwrap();
|
||||||
|
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(0),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(64), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_not_trace_delegatecall() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
info.number = 0x789b0;
|
||||||
|
let engine = Spec::new_test().to_engine().unwrap();
|
||||||
|
|
||||||
|
println!("schedule.have_delegate_call: {:?}", engine.schedule(&info).have_delegate_call);
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(0),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("6000600060006000600b618000f4").unwrap());
|
||||||
|
state.init_code(&x!(0xb), FromHex::from_hex("6000").unwrap());
|
||||||
|
let result = state.apply(&info, engine.deref(), &t, true).unwrap();
|
||||||
|
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(0),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(61), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_failed_call_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(100),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("5b600056").unwrap());
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: None
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
println!("trace: {:?}", result.trace);
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_call_with_subcall_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(100),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap());
|
||||||
|
state.init_code(&x!(0xb), FromHex::from_hex("6000").unwrap());
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(69), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![Trace {
|
||||||
|
depth: 1,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!(0xa),
|
||||||
|
to: x!(0xb),
|
||||||
|
value: x!(0),
|
||||||
|
gas: x!(78934),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(3), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_call_with_basic_subcall_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(100),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006045600b6000f1").unwrap());
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(31761), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![Trace {
|
||||||
|
depth: 1,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!(0xa),
|
||||||
|
to: x!(0xb),
|
||||||
|
value: x!(69),
|
||||||
|
gas: x!(2300),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(0), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_not_trace_call_with_invalid_basic_subcall_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(100),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("600060006000600060ff600b6000f1").unwrap()); // not enough funds.
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(31761), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_failed_subcall_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(100),
|
||||||
|
data: vec![],//600480600b6000396000f35b600056
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap());
|
||||||
|
state.init_code(&x!(0xb), FromHex::from_hex("5b600056").unwrap());
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(79000), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![Trace {
|
||||||
|
depth: 1,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!(0xa),
|
||||||
|
to: x!(0xb),
|
||||||
|
value: x!(0),
|
||||||
|
gas: x!(78934),
|
||||||
|
input: vec![],
|
||||||
|
result: None
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_call_with_subcall_with_subcall_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(100),
|
||||||
|
data: vec![],
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap());
|
||||||
|
state.init_code(&x!(0xb), FromHex::from_hex("60006000600060006000600c602b5a03f1").unwrap());
|
||||||
|
state.init_code(&x!(0xc), FromHex::from_hex("6000").unwrap());
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(135), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![Trace {
|
||||||
|
depth: 1,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!(0xa),
|
||||||
|
to: x!(0xb),
|
||||||
|
value: x!(0),
|
||||||
|
gas: x!(78934),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(69), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![Trace {
|
||||||
|
depth: 2,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!(0xb),
|
||||||
|
to: x!(0xc),
|
||||||
|
value: x!(0),
|
||||||
|
gas: x!(78868),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(3), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_trace_failed_subcall_with_subcall_transaction() {
|
||||||
|
init_log();
|
||||||
|
|
||||||
|
let temp = RandomTempPath::new();
|
||||||
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
|
|
||||||
|
let mut info = EnvInfo::default();
|
||||||
|
info.gas_limit = x!(1_000_000);
|
||||||
|
let engine = TestEngine::new(5, Factory::default());
|
||||||
|
|
||||||
|
let t = Transaction {
|
||||||
|
nonce: x!(0),
|
||||||
|
gas_price: x!(0),
|
||||||
|
gas: x!(100_000),
|
||||||
|
action: Action::Call(x!(0xa)),
|
||||||
|
value: x!(100),
|
||||||
|
data: vec![],//600480600b6000396000f35b600056
|
||||||
|
}.sign(&"".sha3());
|
||||||
|
|
||||||
|
state.init_code(&x!(0xa), FromHex::from_hex("60006000600060006000600b602b5a03f1").unwrap());
|
||||||
|
state.init_code(&x!(0xb), FromHex::from_hex("60006000600060006000600c602b5a03f1505b601256").unwrap());
|
||||||
|
state.init_code(&x!(0xc), FromHex::from_hex("6000").unwrap());
|
||||||
|
state.add_balance(t.sender().as_ref().unwrap(), &x!(100));
|
||||||
|
let result = state.apply(&info, &engine, &t, true).unwrap();
|
||||||
|
let expected_trace = Some(Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!("9cce34f7ab185c7aba1b7c8140d620b4bda941d6"),
|
||||||
|
to: x!(0xa),
|
||||||
|
value: x!(100),
|
||||||
|
gas: x!(79000),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(79000), vec![]))
|
||||||
|
}),
|
||||||
|
subs: vec![Trace {
|
||||||
|
depth: 1,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!(0xa),
|
||||||
|
to: x!(0xb),
|
||||||
|
value: x!(0),
|
||||||
|
gas: x!(78934),
|
||||||
|
input: vec![],
|
||||||
|
result: None
|
||||||
|
}),
|
||||||
|
subs: vec![Trace {
|
||||||
|
depth: 2,
|
||||||
|
action: TraceAction::Call(TraceCall {
|
||||||
|
from: x!(0xb),
|
||||||
|
to: x!(0xc),
|
||||||
|
value: x!(0),
|
||||||
|
gas: x!(78868),
|
||||||
|
input: vec![],
|
||||||
|
result: Some((x!(3), vec![])),
|
||||||
|
}),
|
||||||
|
subs: vec![]
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(result.trace, expected_trace);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn code_from_database() {
|
fn code_from_database() {
|
||||||
@ -349,7 +1015,7 @@ fn code_from_database() {
|
|||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let (root, db) = {
|
let (root, db) = {
|
||||||
let mut state = get_temp_state_in(temp.as_path());
|
let mut state = get_temp_state_in(temp.as_path());
|
||||||
state.require_or_from(&a, false, ||Account::new_contract(U256::from(42u32)), |_|{});
|
state.require_or_from(&a, false, ||Account::new_contract(x!(42), x!(0)), |_|{});
|
||||||
state.init_code(&a, vec![1, 2, 3]);
|
state.init_code(&a, vec![1, 2, 3]);
|
||||||
assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
|
assert_eq!(state.code(&a), Some([1u8, 2, 3].to_vec()));
|
||||||
state.commit();
|
state.commit();
|
||||||
|
@ -23,31 +23,53 @@ use common::*;
|
|||||||
pub struct Substate {
|
pub struct Substate {
|
||||||
/// Any accounts that have suicided.
|
/// Any accounts that have suicided.
|
||||||
pub suicides: HashSet<Address>,
|
pub suicides: HashSet<Address>,
|
||||||
|
|
||||||
/// Any logs.
|
/// Any logs.
|
||||||
pub logs: Vec<LogEntry>,
|
pub logs: Vec<LogEntry>,
|
||||||
|
|
||||||
/// Refund counter of SSTORE nonzero -> zero.
|
/// Refund counter of SSTORE nonzero -> zero.
|
||||||
pub sstore_clears_count: U256,
|
pub sstore_clears_count: U256,
|
||||||
|
|
||||||
/// Created contracts.
|
/// Created contracts.
|
||||||
pub contracts_created: Vec<Address>
|
pub contracts_created: Vec<Address>,
|
||||||
|
|
||||||
|
/// The trace during this execution or `None` if we're not tracing.
|
||||||
|
pub subtraces: Option<Vec<Trace>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Substate {
|
impl Substate {
|
||||||
/// Creates new substate.
|
/// Creates new substate.
|
||||||
pub fn new() -> Self {
|
pub fn new(tracing: bool) -> Self {
|
||||||
Substate {
|
Substate {
|
||||||
suicides: HashSet::new(),
|
suicides: Default::default(),
|
||||||
logs: vec![],
|
logs: Default::default(),
|
||||||
sstore_clears_count: U256::zero(),
|
sstore_clears_count: Default::default(),
|
||||||
contracts_created: vec![]
|
contracts_created: Default::default(),
|
||||||
|
subtraces: if tracing {Some(vec![])} else {None},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Merge secondary substate `s` into self, accruing each element correspondingly.
|
/// Merge tracing information from substate `s` if enabled.
|
||||||
pub fn accrue(&mut self, s: Substate) {
|
pub fn accrue_trace(&mut self, subs: Option<Vec<Trace>>, maybe_info: Option<(TraceAction, usize)>) {
|
||||||
|
// it failed, so we don't bother accrueing any protocol-level stuff, only the
|
||||||
|
// trace info.
|
||||||
|
if let Some(info) = maybe_info {
|
||||||
|
self.subtraces.as_mut().expect("maybe_action is Some: so we must be tracing: qed").push(Trace {
|
||||||
|
action: info.0,
|
||||||
|
depth: info.1,
|
||||||
|
subs: subs.expect("maybe_action is Some: so we must be tracing: qed"),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Merge secondary substate `s` into self, accruing each element correspondingly; will merge
|
||||||
|
/// tracing information too, if enabled.
|
||||||
|
pub fn accrue(&mut self, s: Substate, maybe_info: Option<(TraceAction, usize)>) {
|
||||||
self.suicides.extend(s.suicides.into_iter());
|
self.suicides.extend(s.suicides.into_iter());
|
||||||
self.logs.extend(s.logs.into_iter());
|
self.logs.extend(s.logs.into_iter());
|
||||||
self.sstore_clears_count = self.sstore_clears_count + s.sstore_clears_count;
|
self.sstore_clears_count = self.sstore_clears_count + s.sstore_clears_count;
|
||||||
self.contracts_created.extend(s.contracts_created.into_iter());
|
self.contracts_created.extend(s.contracts_created.into_iter());
|
||||||
|
self.accrue_trace(s.subtraces, maybe_info);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,24 +80,32 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn created() {
|
fn created() {
|
||||||
let sub_state = Substate::new();
|
let sub_state = Substate::new(false);
|
||||||
assert_eq!(sub_state.suicides.len(), 0);
|
assert_eq!(sub_state.suicides.len(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn accrue() {
|
fn accrue() {
|
||||||
let mut sub_state = Substate::new();
|
let mut sub_state = Substate::new(false);
|
||||||
sub_state.contracts_created.push(address_from_u64(1u64));
|
sub_state.contracts_created.push(address_from_u64(1u64));
|
||||||
sub_state.logs.push(LogEntry::new(address_from_u64(1u64), vec![], vec![]));
|
sub_state.logs.push(LogEntry {
|
||||||
|
address: address_from_u64(1u64),
|
||||||
|
topics: vec![],
|
||||||
|
data: vec![]
|
||||||
|
});
|
||||||
sub_state.sstore_clears_count = x!(5);
|
sub_state.sstore_clears_count = x!(5);
|
||||||
sub_state.suicides.insert(address_from_u64(10u64));
|
sub_state.suicides.insert(address_from_u64(10u64));
|
||||||
|
|
||||||
let mut sub_state_2 = Substate::new();
|
let mut sub_state_2 = Substate::new(false);
|
||||||
sub_state_2.contracts_created.push(address_from_u64(2u64));
|
sub_state_2.contracts_created.push(address_from_u64(2u64));
|
||||||
sub_state_2.logs.push(LogEntry::new(address_from_u64(1u64), vec![], vec![]));
|
sub_state_2.logs.push(LogEntry {
|
||||||
|
address: address_from_u64(1u64),
|
||||||
|
topics: vec![],
|
||||||
|
data: vec![]
|
||||||
|
});
|
||||||
sub_state_2.sstore_clears_count = x!(7);
|
sub_state_2.sstore_clears_count = x!(7);
|
||||||
|
|
||||||
sub_state.accrue(sub_state_2);
|
sub_state.accrue(sub_state_2, None);
|
||||||
assert_eq!(sub_state.contracts_created.len(), 2);
|
assert_eq!(sub_state.contracts_created.len(), 2);
|
||||||
assert_eq!(sub_state.sstore_clears_count, x!(12));
|
assert_eq!(sub_state.sstore_clears_count, x!(12));
|
||||||
assert_eq!(sub_state.suicides.len(), 1);
|
assert_eq!(sub_state.suicides.len(), 1);
|
||||||
|
@ -14,29 +14,42 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use client::{BlockChainClient, Client, BlockId};
|
use client::{BlockChainClient, Client, ClientConfig, BlockId};
|
||||||
|
use block::IsBlock;
|
||||||
use tests::helpers::*;
|
use tests::helpers::*;
|
||||||
use common::*;
|
use common::*;
|
||||||
|
use devtools::*;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn created() {
|
fn created() {
|
||||||
let dir = RandomTempPath::new();
|
let dir = RandomTempPath::new();
|
||||||
let client_result = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected());
|
let client_result = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected());
|
||||||
assert!(client_result.is_ok());
|
assert!(client_result.is_ok());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn imports_from_empty() {
|
fn imports_from_empty() {
|
||||||
let dir = RandomTempPath::new();
|
let dir = RandomTempPath::new();
|
||||||
let client = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||||
client.import_verified_blocks(&IoChannel::disconnected());
|
client.import_verified_blocks(&IoChannel::disconnected());
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn returns_state_root_basic() {
|
||||||
|
let client_result = generate_dummy_client(6);
|
||||||
|
let client = client_result.reference();
|
||||||
|
let test_spec = get_test_spec();
|
||||||
|
let test_engine = test_spec.to_engine().unwrap();
|
||||||
|
let state_root = test_engine.spec().genesis_header().state_root;
|
||||||
|
|
||||||
|
assert!(client.state_data(&state_root).is_some());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn imports_good_block() {
|
fn imports_good_block() {
|
||||||
let dir = RandomTempPath::new();
|
let dir = RandomTempPath::new();
|
||||||
let client = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||||
let good_block = get_good_dummy_block();
|
let good_block = get_good_dummy_block();
|
||||||
if let Err(_) = client.import_block(good_block) {
|
if let Err(_) = client.import_block(good_block) {
|
||||||
panic!("error importing block being good by definition");
|
panic!("error importing block being good by definition");
|
||||||
@ -51,7 +64,7 @@ fn imports_good_block() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn query_none_block() {
|
fn query_none_block() {
|
||||||
let dir = RandomTempPath::new();
|
let dir = RandomTempPath::new();
|
||||||
let client = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||||
|
|
||||||
let non_existant = client.block_header(BlockId::Number(188));
|
let non_existant = client.block_header(BlockId::Number(188));
|
||||||
assert!(non_existant.is_none());
|
assert!(non_existant.is_none());
|
||||||
@ -103,5 +116,36 @@ fn can_collect_garbage() {
|
|||||||
let client_result = generate_dummy_client(100);
|
let client_result = generate_dummy_client(100);
|
||||||
let client = client_result.reference();
|
let client = client_result.reference();
|
||||||
client.tick();
|
client.tick();
|
||||||
assert!(client.cache_info().blocks < 100 * 1024);
|
assert!(client.blockchain_cache_info().blocks < 100 * 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_handle_long_fork() {
|
||||||
|
let client_result = generate_dummy_client(1200);
|
||||||
|
let client = client_result.reference();
|
||||||
|
for _ in 0..10 {
|
||||||
|
client.import_verified_blocks(&IoChannel::disconnected());
|
||||||
|
}
|
||||||
|
assert_eq!(1200, client.chain_info().best_block_number);
|
||||||
|
|
||||||
|
push_blocks_to_client(client, 45, 1201, 800);
|
||||||
|
push_blocks_to_client(client, 49, 1201, 800);
|
||||||
|
push_blocks_to_client(client, 53, 1201, 600);
|
||||||
|
|
||||||
|
for _ in 0..20 {
|
||||||
|
client.import_verified_blocks(&IoChannel::disconnected());
|
||||||
|
}
|
||||||
|
assert_eq!(2000, client.chain_info().best_block_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn can_mine() {
|
||||||
|
let dummy_blocks = get_good_dummy_block_seq(2);
|
||||||
|
let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]);
|
||||||
|
let client = client_result.reference();
|
||||||
|
|
||||||
|
let b = client.prepare_sealing(Address::default(), x!(31415926), vec![], vec![]).unwrap().0;
|
||||||
|
|
||||||
|
assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().sha3());
|
||||||
|
assert!(client.try_seal(b, vec![]).is_ok());
|
||||||
}
|
}
|
||||||
|
@ -14,18 +14,15 @@
|
|||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use client::{BlockChainClient, Client};
|
use client::{BlockChainClient, Client, ClientConfig};
|
||||||
use std::env;
|
|
||||||
use common::*;
|
use common::*;
|
||||||
use std::path::PathBuf;
|
|
||||||
use spec::*;
|
use spec::*;
|
||||||
use std::fs::{remove_dir_all};
|
use blockchain::{BlockChain, BlockChainConfig};
|
||||||
use blockchain::{BlockChain};
|
|
||||||
use state::*;
|
use state::*;
|
||||||
use rocksdb::*;
|
|
||||||
use evm::{Schedule, Factory};
|
use evm::{Schedule, Factory};
|
||||||
use engine::*;
|
use engine::*;
|
||||||
use ethereum;
|
use ethereum;
|
||||||
|
use devtools::*;
|
||||||
|
|
||||||
#[cfg(feature = "json-tests")]
|
#[cfg(feature = "json-tests")]
|
||||||
pub enum ChainEra {
|
pub enum ChainEra {
|
||||||
@ -33,36 +30,6 @@ pub enum ChainEra {
|
|||||||
Homestead,
|
Homestead,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct RandomTempPath {
|
|
||||||
path: PathBuf
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RandomTempPath {
|
|
||||||
pub fn new() -> RandomTempPath {
|
|
||||||
let mut dir = env::temp_dir();
|
|
||||||
dir.push(H32::random().hex());
|
|
||||||
RandomTempPath {
|
|
||||||
path: dir.clone()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_path(&self) -> &PathBuf {
|
|
||||||
&self.path
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn as_str(&self) -> &str {
|
|
||||||
self.path.to_str().unwrap()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for RandomTempPath {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if let Err(e) = remove_dir_all(self.as_path()) {
|
|
||||||
panic!("failed to remove temp directory, probably something failed to destroyed ({})", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub struct GuardedTempResult<T> {
|
pub struct GuardedTempResult<T> {
|
||||||
result: Option<T>,
|
result: Option<T>,
|
||||||
@ -167,7 +134,7 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[&SignedTrans
|
|||||||
pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>> {
|
pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>> {
|
||||||
let dir = RandomTempPath::new();
|
let dir = RandomTempPath::new();
|
||||||
|
|
||||||
let client = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||||
let test_spec = get_test_spec();
|
let test_spec = get_test_spec();
|
||||||
let test_engine = test_spec.to_engine().unwrap();
|
let test_engine = test_spec.to_engine().unwrap();
|
||||||
let state_root = test_engine.spec().genesis_header().state_root;
|
let state_root = test_engine.spec().genesis_header().state_root;
|
||||||
@ -189,10 +156,9 @@ pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>
|
|||||||
rolling_block_number = rolling_block_number + 1;
|
rolling_block_number = rolling_block_number + 1;
|
||||||
rolling_timestamp = rolling_timestamp + 10;
|
rolling_timestamp = rolling_timestamp + 10;
|
||||||
|
|
||||||
if let Err(_) = client.import_block(create_test_block(&header)) {
|
if let Err(e) = client.import_block(create_test_block(&header)) {
|
||||||
panic!("error importing block which is valid by definition");
|
panic!("error importing block which is valid by definition: {:?}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
client.flush_queue();
|
client.flush_queue();
|
||||||
client.import_verified_blocks(&IoChannel::disconnected());
|
client.import_verified_blocks(&IoChannel::disconnected());
|
||||||
@ -203,9 +169,37 @@ pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult<Arc<Client>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn push_blocks_to_client(client: &Arc<Client>, timestamp_salt: u64, starting_number: usize, block_number: usize) {
|
||||||
|
let test_spec = get_test_spec();
|
||||||
|
let test_engine = test_spec.to_engine().unwrap();
|
||||||
|
let state_root = test_engine.spec().genesis_header().state_root;
|
||||||
|
let mut rolling_hash = client.chain_info().best_block_hash;
|
||||||
|
let mut rolling_block_number = starting_number as u64;
|
||||||
|
let mut rolling_timestamp = timestamp_salt + starting_number as u64 * 10;
|
||||||
|
|
||||||
|
for _ in 0..block_number {
|
||||||
|
let mut header = Header::new();
|
||||||
|
|
||||||
|
header.gas_limit = decode(test_engine.spec().engine_params.get("minGasLimit").unwrap());
|
||||||
|
header.difficulty = decode(test_engine.spec().engine_params.get("minimumDifficulty").unwrap());
|
||||||
|
header.timestamp = rolling_timestamp;
|
||||||
|
header.number = rolling_block_number;
|
||||||
|
header.parent_hash = rolling_hash;
|
||||||
|
header.state_root = state_root.clone();
|
||||||
|
|
||||||
|
rolling_hash = header.hash();
|
||||||
|
rolling_block_number = rolling_block_number + 1;
|
||||||
|
rolling_timestamp = rolling_timestamp + 10;
|
||||||
|
|
||||||
|
if let Err(e) = client.import_block(create_test_block(&header)) {
|
||||||
|
panic!("error importing block which is valid by definition: {:?}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<Client>> {
|
pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<Client>> {
|
||||||
let dir = RandomTempPath::new();
|
let dir = RandomTempPath::new();
|
||||||
let client = Client::new(get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), IoChannel::disconnected()).unwrap();
|
||||||
for block in &blocks {
|
for block in &blocks {
|
||||||
if let Err(_) = client.import_block(block.clone()) {
|
if let Err(_) = client.import_block(block.clone()) {
|
||||||
panic!("panic importing block which is well-formed");
|
panic!("panic importing block which is well-formed");
|
||||||
@ -222,9 +216,9 @@ pub fn get_test_client_with_blocks(blocks: Vec<Bytes>) -> GuardedTempResult<Arc<
|
|||||||
|
|
||||||
pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult<BlockChain> {
|
pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult<BlockChain> {
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let bc = BlockChain::new(&create_unverifiable_block(0, H256::zero()), temp.as_path());
|
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), temp.as_path());
|
||||||
for block_order in 1..block_number {
|
for block_order in 1..block_number {
|
||||||
bc.insert_block(&create_unverifiable_block(block_order, bc.best_block_hash()));
|
bc.insert_block(&create_unverifiable_block(block_order, bc.best_block_hash()), vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
GuardedTempResult::<BlockChain> {
|
GuardedTempResult::<BlockChain> {
|
||||||
@ -235,9 +229,9 @@ pub fn generate_dummy_blockchain(block_number: u32) -> GuardedTempResult<BlockCh
|
|||||||
|
|
||||||
pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempResult<BlockChain> {
|
pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempResult<BlockChain> {
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let bc = BlockChain::new(&create_unverifiable_block(0, H256::zero()), temp.as_path());
|
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), temp.as_path());
|
||||||
for block_order in 1..block_number {
|
for block_order in 1..block_number {
|
||||||
bc.insert_block(&create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None));
|
bc.insert_block(&create_unverifiable_block_with_extra(block_order, bc.best_block_hash(), None), vec![]);
|
||||||
}
|
}
|
||||||
|
|
||||||
GuardedTempResult::<BlockChain> {
|
GuardedTempResult::<BlockChain> {
|
||||||
@ -248,7 +242,7 @@ pub fn generate_dummy_blockchain_with_extra(block_number: u32) -> GuardedTempRes
|
|||||||
|
|
||||||
pub fn generate_dummy_empty_blockchain() -> GuardedTempResult<BlockChain> {
|
pub fn generate_dummy_empty_blockchain() -> GuardedTempResult<BlockChain> {
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let bc = BlockChain::new(&create_unverifiable_block(0, H256::zero()), temp.as_path());
|
let bc = BlockChain::new(BlockChainConfig::default(), &create_unverifiable_block(0, H256::zero()), temp.as_path());
|
||||||
|
|
||||||
GuardedTempResult::<BlockChain> {
|
GuardedTempResult::<BlockChain> {
|
||||||
_temp: temp,
|
_temp: temp,
|
||||||
@ -256,10 +250,9 @@ pub fn generate_dummy_empty_blockchain() -> GuardedTempResult<BlockChain> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_temp_journal_db() -> GuardedTempResult<JournalDB> {
|
pub fn get_temp_journal_db() -> GuardedTempResult<Box<JournalDB>> {
|
||||||
let temp = RandomTempPath::new();
|
let temp = RandomTempPath::new();
|
||||||
let db = DB::open_default(temp.as_str()).unwrap();
|
let journal_db = journaldb::new(temp.as_str(), journaldb::Algorithm::EarlyMerge);
|
||||||
let journal_db = JournalDB::new(db);
|
|
||||||
GuardedTempResult {
|
GuardedTempResult {
|
||||||
_temp: temp,
|
_temp: temp,
|
||||||
result: Some(journal_db)
|
result: Some(journal_db)
|
||||||
@ -275,9 +268,8 @@ pub fn get_temp_state() -> GuardedTempResult<State> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_temp_journal_db_in(path: &Path) -> JournalDB {
|
pub fn get_temp_journal_db_in(path: &Path) -> Box<JournalDB> {
|
||||||
let db = DB::open_default(path.to_str().unwrap()).unwrap();
|
journaldb::new(path.to_str().unwrap(), journaldb::Algorithm::EarlyMerge)
|
||||||
JournalDB::new(db)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_temp_state_in(path: &Path) -> State {
|
pub fn get_temp_state_in(path: &Path) -> State {
|
||||||
@ -285,6 +277,36 @@ pub fn get_temp_state_in(path: &Path) -> State {
|
|||||||
State::new(journal_db, U256::from(0u8))
|
State::new(journal_db, U256::from(0u8))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn get_good_dummy_block_seq(count: usize) -> Vec<Bytes> {
|
||||||
|
let test_spec = get_test_spec();
|
||||||
|
let test_engine = test_spec.to_engine().unwrap();
|
||||||
|
get_good_dummy_block_fork_seq(1, count, &test_engine.spec().genesis_header().hash())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_good_dummy_block_fork_seq(start_number: usize, count: usize, parent_hash: &H256) -> Vec<Bytes> {
|
||||||
|
let test_spec = get_test_spec();
|
||||||
|
let test_engine = test_spec.to_engine().unwrap();
|
||||||
|
let mut rolling_timestamp = start_number as u64 * 10;
|
||||||
|
let mut parent = *parent_hash;
|
||||||
|
let mut r = Vec::new();
|
||||||
|
for i in start_number .. start_number + count + 1 {
|
||||||
|
let mut block_header = Header::new();
|
||||||
|
block_header.gas_limit = decode(test_engine.spec().engine_params.get("minGasLimit").unwrap());
|
||||||
|
block_header.difficulty = U256::from(i).mul(U256([0, 1, 0, 0]));
|
||||||
|
block_header.timestamp = rolling_timestamp;
|
||||||
|
block_header.number = i as u64;
|
||||||
|
block_header.parent_hash = parent;
|
||||||
|
block_header.state_root = test_engine.spec().genesis_header().state_root;
|
||||||
|
|
||||||
|
parent = block_header.hash();
|
||||||
|
rolling_timestamp = rolling_timestamp + 10;
|
||||||
|
|
||||||
|
r.push(create_test_block(&block_header));
|
||||||
|
|
||||||
|
}
|
||||||
|
r
|
||||||
|
}
|
||||||
|
|
||||||
pub fn get_good_dummy_block() -> Bytes {
|
pub fn get_good_dummy_block() -> Bytes {
|
||||||
let mut block_header = Header::new();
|
let mut block_header = Header::new();
|
||||||
let test_spec = get_test_spec();
|
let test_spec = get_test_spec();
|
||||||
|
111
ethcore/src/trace.rs
Normal file
111
ethcore/src/trace.rs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
//! Tracing datatypes.
|
||||||
|
use common::*;
|
||||||
|
|
||||||
|
/// Description of a _call_ action, either a `CALL` operation or a message transction.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct TraceCall {
|
||||||
|
/// The sending account.
|
||||||
|
pub from: Address,
|
||||||
|
/// The destination account.
|
||||||
|
pub to: Address,
|
||||||
|
/// The value transferred to the destination account.
|
||||||
|
pub value: U256,
|
||||||
|
/// The gas available for executing the call.
|
||||||
|
pub gas: U256,
|
||||||
|
/// The input data provided to the call.
|
||||||
|
pub input: Bytes,
|
||||||
|
/// The result of the operation; the gas used and the output data of the call.
|
||||||
|
pub result: Option<(U256, Bytes)>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Description of a _create_ action, either a `CREATE` operation or a create transction.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct TraceCreate {
|
||||||
|
/// The address of the creator.
|
||||||
|
pub from: Address,
|
||||||
|
/// The value with which the new account is endowed.
|
||||||
|
pub value: U256,
|
||||||
|
/// The gas available for the creation init code.
|
||||||
|
pub gas: U256,
|
||||||
|
/// The init code.
|
||||||
|
pub init: Bytes,
|
||||||
|
/// The result of the operation; tuple of the gas used, the address of the newly created account and its code.
|
||||||
|
/// NOTE: Presently failed operations are not reported so this will always be `Some`.
|
||||||
|
pub result: Option<(U256, Address, Bytes)>,
|
||||||
|
// pub output: Bytes,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Description of an action that we trace; will be either a call or a create.
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub enum TraceAction {
|
||||||
|
/// Action isn't yet known.
|
||||||
|
Unknown,
|
||||||
|
/// It's a call action.
|
||||||
|
Call(TraceCall),
|
||||||
|
/// It's a create action.
|
||||||
|
Create(TraceCreate),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
/// A trace; includes a description of the action being traced and sub traces of each interior action.
|
||||||
|
pub struct Trace {
|
||||||
|
/// The number of EVM execution environments active when this action happened; 0 if it's
|
||||||
|
/// the outer action of the transaction.
|
||||||
|
pub depth: usize,
|
||||||
|
/// The action being performed.
|
||||||
|
pub action: TraceAction,
|
||||||
|
/// The sub traces for each interior action performed as part of this call.
|
||||||
|
pub subs: Vec<Trace>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Trace {
|
||||||
|
fn default() -> Trace {
|
||||||
|
Trace {
|
||||||
|
depth: 0,
|
||||||
|
action: TraceAction::Unknown,
|
||||||
|
subs: vec![],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TraceAction {
|
||||||
|
/// Compose a `TraceAction` from an `ActionParams`, knowing that the action is a call.
|
||||||
|
pub fn from_call(p: &ActionParams) -> TraceAction {
|
||||||
|
TraceAction::Call(TraceCall {
|
||||||
|
from: p.sender.clone(),
|
||||||
|
to: p.address.clone(),
|
||||||
|
value: match p.value { ActionValue::Transfer(ref x) | ActionValue::Apparent(ref x) => x.clone() },
|
||||||
|
gas: p.gas.clone(),
|
||||||
|
input: p.data.clone().unwrap_or(vec![]),
|
||||||
|
result: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compose a `TraceAction` from an `ActionParams`, knowing that the action is a create.
|
||||||
|
pub fn from_create(p: &ActionParams) -> TraceAction {
|
||||||
|
TraceAction::Create(TraceCreate {
|
||||||
|
from: p.sender.clone(),
|
||||||
|
value: match p.value { ActionValue::Transfer(ref x) | ActionValue::Apparent(ref x) => x.clone() },
|
||||||
|
gas: p.gas.clone(),
|
||||||
|
init: p.code.clone().unwrap_or(vec![]),
|
||||||
|
result: None,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -37,10 +37,11 @@ impl Default for Action {
|
|||||||
impl Decodable for Action {
|
impl Decodable for Action {
|
||||||
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
fn decode<D>(decoder: &D) -> Result<Self, DecoderError> where D: Decoder {
|
||||||
let rlp = decoder.as_rlp();
|
let rlp = decoder.as_rlp();
|
||||||
match rlp.is_empty() {
|
if rlp.is_empty() {
|
||||||
true => Ok(Action::Create),
|
Ok(Action::Create)
|
||||||
false => Ok(Action::Call(try!(rlp.as_val())))
|
} else {
|
||||||
}
|
Ok(Action::Call(try!(rlp.as_val())))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,6 +80,7 @@ impl Transaction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FromJson for SignedTransaction {
|
impl FromJson for SignedTransaction {
|
||||||
|
#[cfg_attr(feature="dev", allow(single_char_pattern))]
|
||||||
fn from_json(json: &Json) -> SignedTransaction {
|
fn from_json(json: &Json) -> SignedTransaction {
|
||||||
let t = Transaction {
|
let t = Transaction {
|
||||||
nonce: xjson!(&json["nonce"]),
|
nonce: xjson!(&json["nonce"]),
|
||||||
@ -98,10 +100,10 @@ impl FromJson for SignedTransaction {
|
|||||||
v: match json.find("v") { Some(ref j) => u16::from_json(j) as u8, None => 0 },
|
v: match json.find("v") { Some(ref j) => u16::from_json(j) as u8, None => 0 },
|
||||||
r: match json.find("r") { Some(j) => xjson!(j), None => x!(0) },
|
r: match json.find("r") { Some(j) => xjson!(j), None => x!(0) },
|
||||||
s: match json.find("s") { Some(j) => xjson!(j), None => x!(0) },
|
s: match json.find("s") { Some(j) => xjson!(j), None => x!(0) },
|
||||||
hash: RefCell::new(None),
|
hash: Cell::new(None),
|
||||||
sender: match json.find("sender") {
|
sender: match json.find("sender") {
|
||||||
Some(&Json::String(ref sender)) => RefCell::new(Some(address_from_hex(clean(sender)))),
|
Some(&Json::String(ref sender)) => Cell::new(Some(address_from_hex(clean(sender)))),
|
||||||
_ => RefCell::new(None),
|
_ => Cell::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +112,7 @@ impl FromJson for SignedTransaction {
|
|||||||
|
|
||||||
impl Transaction {
|
impl Transaction {
|
||||||
/// The message hash of the transaction.
|
/// The message hash of the transaction.
|
||||||
pub fn hash(&self) -> H256 {
|
pub fn hash(&self) -> H256 {
|
||||||
let mut stream = RlpStream::new();
|
let mut stream = RlpStream::new();
|
||||||
self.rlp_append_unsigned_transaction(&mut stream);
|
self.rlp_append_unsigned_transaction(&mut stream);
|
||||||
stream.out().sha3()
|
stream.out().sha3()
|
||||||
@ -125,8 +127,8 @@ impl Transaction {
|
|||||||
r: r,
|
r: r,
|
||||||
s: s,
|
s: s,
|
||||||
v: v + 27,
|
v: v + 27,
|
||||||
hash: RefCell::new(None),
|
hash: Cell::new(None),
|
||||||
sender: RefCell::new(None)
|
sender: Cell::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,8 +140,8 @@ impl Transaction {
|
|||||||
r: U256::zero(),
|
r: U256::zero(),
|
||||||
s: U256::zero(),
|
s: U256::zero(),
|
||||||
v: 0,
|
v: 0,
|
||||||
hash: RefCell::new(None),
|
hash: Cell::new(None),
|
||||||
sender: RefCell::new(None)
|
sender: Cell::new(None),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,9 +171,9 @@ pub struct SignedTransaction {
|
|||||||
/// The S field of the signature; helps describe the point on the curve.
|
/// The S field of the signature; helps describe the point on the curve.
|
||||||
s: U256,
|
s: U256,
|
||||||
/// Cached hash.
|
/// Cached hash.
|
||||||
hash: RefCell<Option<H256>>,
|
hash: Cell<Option<H256>>,
|
||||||
/// Cached sender.
|
/// Cached sender.
|
||||||
sender: RefCell<Option<Address>>
|
sender: Cell<Option<Address>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for SignedTransaction {
|
impl PartialEq for SignedTransaction {
|
||||||
@ -206,8 +208,8 @@ impl Decodable for SignedTransaction {
|
|||||||
v: try!(d.val_at(6)),
|
v: try!(d.val_at(6)),
|
||||||
r: try!(d.val_at(7)),
|
r: try!(d.val_at(7)),
|
||||||
s: try!(d.val_at(8)),
|
s: try!(d.val_at(8)),
|
||||||
hash: RefCell::new(None),
|
hash: Cell::new(None),
|
||||||
sender: RefCell::new(None),
|
sender: Cell::new(None),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -236,13 +238,14 @@ impl SignedTransaction {
|
|||||||
|
|
||||||
/// Get the hash of this header (sha3 of the RLP).
|
/// Get the hash of this header (sha3 of the RLP).
|
||||||
pub fn hash(&self) -> H256 {
|
pub fn hash(&self) -> H256 {
|
||||||
let mut hash = self.hash.borrow_mut();
|
let hash = self.hash.get();
|
||||||
match &mut *hash {
|
match hash {
|
||||||
&mut Some(ref h) => h.clone(),
|
Some(h) => h,
|
||||||
hash @ &mut None => {
|
None => {
|
||||||
*hash = Some(self.rlp_sha3());
|
let h = self.rlp_sha3();
|
||||||
hash.as_ref().unwrap().clone()
|
self.hash.set(Some(h));
|
||||||
}
|
h
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,13 +266,14 @@ impl SignedTransaction {
|
|||||||
|
|
||||||
/// Returns transaction sender.
|
/// Returns transaction sender.
|
||||||
pub fn sender(&self) -> Result<Address, Error> {
|
pub fn sender(&self) -> Result<Address, Error> {
|
||||||
let mut sender = self.sender.borrow_mut();
|
let sender = self.sender.get();
|
||||||
match &mut *sender {
|
match sender {
|
||||||
&mut Some(ref h) => Ok(h.clone()),
|
Some(s) => Ok(s),
|
||||||
sender @ &mut None => {
|
None => {
|
||||||
*sender = Some(From::from(try!(ec::recover(&self.signature(), &self.unsigned.hash())).sha3()));
|
let s = Address::from(try!(ec::recover(&self.signature(), &self.unsigned.hash())).sha3());
|
||||||
Ok(sender.as_ref().unwrap().clone())
|
self.sender.set(Some(s));
|
||||||
}
|
Ok(s)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
34
ethcore/src/verification/canon_verifier.rs
Normal file
34
ethcore/src/verification/canon_verifier.rs
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
// Copyright 2015, 2016 Ethcore (UK) Ltd.
|
||||||
|
// This file is part of Parity.
|
||||||
|
|
||||||
|
// Parity is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
|
||||||
|
// Parity is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use blockchain::BlockProvider;
|
||||||
|
use engine::Engine;
|
||||||
|
use error::Error;
|
||||||
|
use header::Header;
|
||||||
|
use super::Verifier;
|
||||||
|
use super::verification;
|
||||||
|
|
||||||
|
pub struct CanonVerifier;
|
||||||
|
|
||||||
|
impl Verifier for CanonVerifier {
|
||||||
|
fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: &BlockProvider) -> Result<(), Error> {
|
||||||
|
verification::verify_block_family(header, bytes, engine, bc)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error> {
|
||||||
|
verification::verify_block_final(expected, got)
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user