From 49024a4f2849f6bf8575c5c44b3d2c458ea17438 Mon Sep 17 00:00:00 2001 From: Robert Habermeier Date: Wed, 29 Jun 2016 14:46:29 +0200 Subject: [PATCH] Merge with master --- .travis.yml | 6 +- Cargo.lock | 350 +- Cargo.toml | 11 +- README.md | 43 +- appveyor.yml | 46 + cov.sh | 6 +- dapps/Cargo.toml | 6 +- dapps/src/endpoint.rs | 6 +- dapps/src/lib.rs | 13 +- dapps/src/page/handler.rs | 2 +- dapps/src/router/auth.rs | 14 +- dapps/src/router/mod.rs | 6 +- dapps/src/router/redirect.rs | 2 +- db/Cargo.toml | 4 +- devtools/Cargo.toml | 2 +- doc.sh | 2 + docker/centos/Dockerfile | 27 + docker/ubuntu-aarch64/Dockerfile | 47 + docker/ubuntu-arm/Dockerfile | 63 +- docker/ubuntu-dev/Dockerfile | 8 +- docker/ubuntu-jit/Dockerfile | 63 +- docker/ubuntu/Dockerfile | 34 +- ethash/Cargo.toml | 2 +- ethcore/Cargo.toml | 7 +- ethcore/res/ethereum/frontier.json | 3 +- ethcore/res/ethereum/frontier_dao_rescue.json | 26729 ++++++++++++++++ ethcore/res/ethereum/frontier_like_test.json | 3 +- .../frontier_like_test_dao_rescue.json | 43 + ethcore/res/ethereum/frontier_test.json | 3 +- ethcore/res/ethereum/homestead_test.json | 3 +- .../ethereum/homestead_test_dao_rescue.json | 43 + ethcore/res/ethereum/morden.json | 3 +- ethcore/res/ethereum/olympic.json | 3 +- ethcore/res/null.json | 33 + ethcore/src/account.rs | 6 +- ethcore/src/account_db.rs | 22 +- ethcore/src/account_provider.rs | 272 + ethcore/src/basic_authority.rs | 55 +- ethcore/src/block.rs | 84 +- ethcore/src/block_queue.rs | 4 +- ethcore/src/blockchain/blockchain.rs | 14 +- ethcore/src/blockchain/config.rs | 3 + ethcore/src/client/client.rs | 114 +- ethcore/src/client/config.rs | 20 + ethcore/src/client/mod.rs | 66 +- ethcore/src/client/test_client.rs | 26 +- ethcore/src/engine.rs | 4 +- ethcore/src/env_info.rs | 5 + ethcore/src/error.rs | 3 + ethcore/src/ethereum/ethash.rs | 57 +- ethcore/src/ethereum/mod.rs | 9 +- ethcore/src/evm/jit.rs | 7 +- ethcore/src/evm/schedule.rs | 3 + ethcore/src/externalities.rs | 3 +- ethcore/src/json_tests/chain.rs | 29 +- ethcore/src/lib.rs | 4 +- ethcore/src/miner/miner.rs | 279 +- ethcore/src/miner/mod.rs | 21 +- ethcore/src/miner/transaction_queue.rs | 220 +- ethcore/src/service.rs | 38 +- ethcore/src/snapshot/account.rs | 2 +- ethcore/src/spec/spec.rs | 5 + ethcore/src/state.rs | 24 + ethcore/src/tests/client.rs | 22 +- ethcore/src/tests/helpers.rs | 82 +- ethcore/src/trace/config.rs | 5 +- ethcore/src/trace/db.rs | 9 +- ethcore/src/types/transaction.rs | 9 +- ethcore/src/verification/canon_verifier.rs | 4 +- ethcore/src/verification/mod.rs | 25 +- ethcore/src/verification/noop_verifier.rs | 4 +- ethcore/src/verification/verification.rs | 2 +- ethcore/src/verification/verifier.rs | 4 +- ethcore/src/views.rs | 339 - ethcore/src/views/block.rs | 167 + ethcore/src/views/header.rs | 134 + {util/src/keys => ethcore/src/views}/mod.rs | 15 +- ethcore/src/views/transaction.rs | 97 + ethkey/.gitignore | 2 + ethkey/.travis.yml | 23 + ethkey/Cargo.toml | 21 + ethkey/README.md | 168 + ethkey/src/bin/ethkey.rs | 312 + ethkey/src/bin/main.rs | 21 + ethkey/src/brain.rs | 62 + ethkey/src/error.rs | 69 + ethkey/src/keccak.rs | 31 + ethkey/src/keypair.rs | 111 + ethkey/src/lib.rs | 49 + ethkey/src/prefix.rs | 57 + ethkey/src/primitive.rs | 138 + ethkey/src/random.rs | 32 + ethkey/src/signature.rs | 207 + ethstore/.editorconfig | 11 + ethstore/.gitignore | 2 + ethstore/.travis.yml | 23 + ethstore/Cargo.toml | 30 + ethstore/README.md | 185 + ethstore/build.rs | 45 + ethstore/src/account/cipher.rs | 59 + ethstore/src/account/kdf.rs | 125 + ethstore/src/account/mod.rs | 25 + ethstore/src/account/safe_account.rs | 216 + ethstore/src/account/version.rs | 38 + ethstore/src/bin/ethstore.rs | 169 + ethstore/src/bin/main.rs | 21 + ethstore/src/crypto.rs | 93 + ethstore/src/dir/disk.rs | 125 + ethstore/src/dir/geth.rs | 95 + ethstore/src/dir/mod.rs | 37 + ethstore/src/dir/parity.rs | 74 + ethstore/src/error.rs | 58 + ethstore/src/ethkey.rs | 41 + ethstore/src/ethstore.rs | 108 + ethstore/src/import.rs | 28 + ethstore/src/json/cipher.rs | 91 + ethstore/src/json/crypto.rs | 200 + ethstore/src/json/error.rs | 50 + ethstore/src/json/hash.rs | 112 + ethstore/src/json/id.rs | 145 + ethstore/src/json/kdf.rs | 149 + ethstore/src/json/key_file.rs | 271 + ethstore/src/json/mod.rs | 24 + ethstore/src/json/mod.rs.in | 20 + ethstore/src/json/presale.rs | 42 + ethstore/src/json/version.rs | 54 + ethstore/src/lib.rs | 50 + ethstore/src/presale.rs | 79 + ethstore/src/random.rs | 39 + ethstore/src/secret_store.rs | 31 + ethstore/tests/api.rs | 127 + ethstore/tests/cli.rs | 16 + ...--3f49624084b67849c7b4e805c5988c21a430f9d9 | 0 ...--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf | 0 ...--63121b431a52f8043c16fcf0d1df9cb7b5f66649 | 2 +- {util => ethstore/tests}/res/pat/p1.json | 0 {util => ethstore/tests}/res/pat/p2.json | 0 ethstore/tests/util/mod.rs | 19 + ethstore/tests/util/transient_dir.rs | 74 + evmjit/Cargo.toml | 2 +- hook.sh | 2 +- install-parity.sh | 2 +- ipc/codegen/Cargo.toml | 2 +- ipc/nano/Cargo.toml | 2 +- ipc/rpc/Cargo.toml | 2 +- json/Cargo.toml | 2 +- json/src/spec/engine.rs | 3 +- json/src/spec/ethash.rs | 8 +- json/src/spec/spec.rs | 3 +- nsis/installer.nsi | 135 + nsis/logo.ico | Bin 0 -> 99678 bytes parity/cli.rs | 110 +- parity/configuration.rs | 220 +- parity/dapps.rs | 7 +- parity/io_handler.rs | 40 +- parity/main.rs | 159 +- parity/migration.rs | 17 +- parity/rpc.rs | 33 +- parity/rpc_apis.rs | 20 +- parity/signer.rs | 7 +- parity/url.rs | 59 + rpc/Cargo.toml | 4 +- rpc/rpctest/Cargo.toml | 2 +- rpc/rpctest/src/main.rs | 2 +- rpc/src/v1/helpers/signing_queue.rs | 46 +- rpc/src/v1/impls/eth.rs | 85 +- rpc/src/v1/impls/eth_signing.rs | 84 +- rpc/src/v1/impls/ethcore.rs | 56 +- rpc/src/v1/impls/ethcore_set.rs | 53 +- rpc/src/v1/impls/mod.rs | 124 +- rpc/src/v1/impls/net.rs | 10 + rpc/src/v1/impls/personal.rs | 32 +- rpc/src/v1/impls/personal_signer.rs | 29 +- rpc/src/v1/tests/eth.rs | 45 +- rpc/src/v1/tests/helpers/miner_service.rs | 27 +- rpc/src/v1/tests/helpers/sync_provider.rs | 6 + rpc/src/v1/tests/mocked/eth.rs | 48 +- rpc/src/v1/tests/mocked/eth_signing.rs | 60 +- rpc/src/v1/tests/mocked/ethcore.rs | 165 +- rpc/src/v1/tests/mocked/ethcore_set.rs | 107 + rpc/src/v1/tests/mocked/mod.rs | 1 + rpc/src/v1/tests/mocked/personal.rs | 51 +- rpc/src/v1/tests/mocked/personal_signer.rs | 27 +- rpc/src/v1/traits/ethcore.rs | 13 + rpc/src/v1/traits/ethcore_set.rs | 24 + rpc/src/v1/traits/net.rs | 6 + rpc/src/v1/types/optionals.rs | 26 +- rpc/src/v1/types/receipt.rs | 41 +- signer/Cargo.toml | 8 +- signer/src/ws_server/mod.rs | 28 +- signer/src/ws_server/session.rs | 38 +- sync/Cargo.toml | 4 +- sync/src/blocks.rs | 48 +- sync/src/chain.rs | 359 +- sync/src/io.rs | 6 + sync/src/lib.rs | 55 +- sync/src/tests/chain.rs | 16 +- sync/src/tests/helpers.rs | 20 +- test.sh | 2 + util/Cargo.toml | 8 +- util/bigint/Cargo.toml | 2 - util/bigint/src/uint.rs | 73 +- util/src/hash.rs | 11 +- util/src/hashdb.rs | 24 +- util/src/io/mod.rs | 2 +- util/src/io/service.rs | 119 +- util/src/journaldb/archivedb.rs | 101 +- util/src/journaldb/earlymergedb.rs | 177 +- util/src/journaldb/mod.rs | 16 +- util/src/journaldb/overlayrecentdb.rs | 169 +- util/src/journaldb/refcounteddb.rs | 73 +- util/src/keys/directory.rs | 1252 - util/src/keys/geth_import.rs | 261 - util/src/keys/store.rs | 750 - util/src/keys/test_account_provider.rs | 118 - util/src/kvdb.rs | 109 +- util/src/lib.rs | 3 +- util/src/memorydb.rs | 6 +- util/src/network/connection.rs | 137 +- util/src/network/discovery.rs | 15 +- util/src/network/handshake.rs | 57 +- util/src/network/host.rs | 381 +- util/src/network/mod.rs | 26 +- util/src/network/service.rs | 87 +- util/src/network/session.rs | 66 +- util/src/network/stats.rs | 2 +- util/src/network/tests.rs | 33 +- util/src/overlaydb.rs | 22 +- util/src/path.rs | 19 + util/src/rlp/bytes.rs | 9 +- util/src/rlp/tests.rs | 7 + util/src/rlp/untrusted_rlp.rs | 6 +- util/src/timer.rs | 51 + util/src/trie/triedb.rs | 8 +- util/src/trie/triedbmut.rs | 18 +- 235 files changed, 36456 insertions(+), 4814 deletions(-) create mode 100644 appveyor.yml create mode 100644 docker/centos/Dockerfile create mode 100644 docker/ubuntu-aarch64/Dockerfile create mode 100644 ethcore/res/ethereum/frontier_dao_rescue.json create mode 100644 ethcore/res/ethereum/frontier_like_test_dao_rescue.json create mode 100644 ethcore/res/ethereum/homestead_test_dao_rescue.json create mode 100644 ethcore/res/null.json create mode 100644 ethcore/src/account_provider.rs delete mode 100644 ethcore/src/views.rs create mode 100644 ethcore/src/views/block.rs create mode 100644 ethcore/src/views/header.rs rename {util/src/keys => ethcore/src/views}/mod.rs (72%) create mode 100644 ethcore/src/views/transaction.rs create mode 100644 ethkey/.gitignore create mode 100644 ethkey/.travis.yml create mode 100644 ethkey/Cargo.toml create mode 100644 ethkey/README.md create mode 100644 ethkey/src/bin/ethkey.rs create mode 100644 ethkey/src/bin/main.rs create mode 100644 ethkey/src/brain.rs create mode 100644 ethkey/src/error.rs create mode 100644 ethkey/src/keccak.rs create mode 100644 ethkey/src/keypair.rs create mode 100644 ethkey/src/lib.rs create mode 100644 ethkey/src/prefix.rs create mode 100644 ethkey/src/primitive.rs create mode 100644 ethkey/src/random.rs create mode 100644 ethkey/src/signature.rs create mode 100644 ethstore/.editorconfig create mode 100644 ethstore/.gitignore create mode 100644 ethstore/.travis.yml create mode 100644 ethstore/Cargo.toml create mode 100644 ethstore/README.md create mode 100644 ethstore/build.rs create mode 100644 ethstore/src/account/cipher.rs create mode 100644 ethstore/src/account/kdf.rs create mode 100644 ethstore/src/account/mod.rs create mode 100644 ethstore/src/account/safe_account.rs create mode 100644 ethstore/src/account/version.rs create mode 100644 ethstore/src/bin/ethstore.rs create mode 100644 ethstore/src/bin/main.rs create mode 100644 ethstore/src/crypto.rs create mode 100644 ethstore/src/dir/disk.rs create mode 100644 ethstore/src/dir/geth.rs create mode 100644 ethstore/src/dir/mod.rs create mode 100644 ethstore/src/dir/parity.rs create mode 100644 ethstore/src/error.rs create mode 100644 ethstore/src/ethkey.rs create mode 100644 ethstore/src/ethstore.rs create mode 100644 ethstore/src/import.rs create mode 100644 ethstore/src/json/cipher.rs create mode 100644 ethstore/src/json/crypto.rs create mode 100644 ethstore/src/json/error.rs create mode 100644 ethstore/src/json/hash.rs create mode 100644 ethstore/src/json/id.rs create mode 100644 ethstore/src/json/kdf.rs create mode 100644 ethstore/src/json/key_file.rs create mode 100644 ethstore/src/json/mod.rs create mode 100644 ethstore/src/json/mod.rs.in create mode 100644 ethstore/src/json/presale.rs create mode 100644 ethstore/src/json/version.rs create mode 100644 ethstore/src/lib.rs create mode 100644 ethstore/src/presale.rs create mode 100644 ethstore/src/random.rs create mode 100644 ethstore/src/secret_store.rs create mode 100644 ethstore/tests/api.rs create mode 100644 ethstore/tests/cli.rs rename {util => ethstore/tests}/res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9 (100%) rename {util => ethstore/tests}/res/geth_keystore/UTC--2016-02-20T09-33-03.984382741Z--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf (100%) rename {util => ethstore/tests}/res/geth_keystore/UTC--2016-04-03T08-58-49.834202900Z--63121b431a52f8043c16fcf0d1df9cb7b5f66649 (91%) rename {util => ethstore/tests}/res/pat/p1.json (100%) rename {util => ethstore/tests}/res/pat/p2.json (100%) create mode 100644 ethstore/tests/util/mod.rs create mode 100644 ethstore/tests/util/transient_dir.rs create mode 100644 nsis/installer.nsi create mode 100644 nsis/logo.ico create mode 100644 parity/url.rs create mode 100644 rpc/src/v1/tests/mocked/ethcore_set.rs delete mode 100644 util/src/keys/directory.rs delete mode 100644 util/src/keys/geth_import.rs delete mode 100644 util/src/keys/store.rs delete mode 100644 util/src/keys/test_account_provider.rs create mode 100644 util/src/timer.rs diff --git a/.travis.yml b/.travis.yml index 230e7862f..b7124b2df 100644 --- a/.travis.yml +++ b/.travis.yml @@ -33,10 +33,10 @@ 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 ethjson -p ethcore-dapps -p ethcore-signer" + - TARGETS="-p ethkey -p ethstore -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethjson -p ethcore-dapps -p ethcore-signer" - 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" + - 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,ethstore/tests target/kcov" - RUN_TESTS="false" - RUN_COVERAGE="false" - RUN_BUILD="false" @@ -65,6 +65,8 @@ after_success: | 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 ../.. && cargo test --no-run ${KCOV_FEATURES} ${TARGETS} && + $KCOV_CMD target/debug/deps/ethkey-* && + $KCOV_CMD target/debug/deps/ethstore-* && $KCOV_CMD target/debug/deps/ethcore_util-* && $KCOV_CMD target/debug/deps/ethash-* && $KCOV_CMD target/debug/deps/ethcore-* && diff --git a/Cargo.lock b/Cargo.lock index ec229ac27..8448b0a97 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,26 +1,26 @@ [root] name = "parity" -version = "1.2.0" +version = "1.3.0" dependencies = [ "ansi_term 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.76 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", "ctrlc 1.1.1 (git+https://github.com/ethcore/rust-ctrlc.git)", "daemonize 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "docopt 0.6.80 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore 1.2.0", - "ethcore-dapps 1.2.0", - "ethcore-devtools 1.2.0", - "ethcore-ipc 1.2.0", - "ethcore-ipc-codegen 1.2.0", - "ethcore-ipc-nano 1.2.0", - "ethcore-rpc 1.2.0", - "ethcore-signer 1.2.0", - "ethcore-util 1.2.0", - "ethsync 1.2.0", + "ethcore 1.3.0", + "ethcore-dapps 1.3.0", + "ethcore-devtools 1.3.0", + "ethcore-ipc 1.3.0", + "ethcore-ipc-codegen 1.3.0", + "ethcore-ipc-nano 1.3.0", + "ethcore-rpc 1.3.0", + "ethcore-signer 1.3.0", + "ethcore-util 1.3.0", + "ethsync 1.3.0", "fdlimit 0.1.0", "hyper 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", - "json-ipc-server 0.1.0 (git+https://github.com/ethcore/json-ipc-server.git)", + "json-ipc-server 0.2.4 (git+https://github.com/ethcore/json-ipc-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "number_prefix 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", @@ -30,6 +30,7 @@ dependencies = [ "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -66,12 +67,10 @@ dependencies = [ name = "bigint" version = "0.1.0" dependencies = [ - "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -130,15 +129,15 @@ dependencies = [ [[package]] name = "clippy" -version = "0.0.76" +version = "0.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "clippy_lints 0.0.76 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy_lints 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "clippy_lints" -version = "0.0.76" +version = "0.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", @@ -165,7 +164,7 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -179,7 +178,7 @@ version = "1.1.1" source = "git+https://github.com/ethcore/rust-ctrlc.git#f4927770f89eca80ec250911eea3adcbf579ac48" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -188,7 +187,7 @@ name = "daemonize" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -230,16 +229,16 @@ source = "git+https://github.com/ethcore/rust-secp256k1#b6fdd43bbcf6d46adb72a92d dependencies = [ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ethash" -version = "1.2.0" +version = "1.3.0" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "primal 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", @@ -248,24 +247,25 @@ dependencies = [ [[package]] name = "ethcore" -version = "1.2.0" +version = "1.3.0" dependencies = [ "bloomchain 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.76 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethash 1.2.0", - "ethcore-devtools 1.2.0", - "ethcore-ipc 1.2.0", - "ethcore-ipc-codegen 1.2.0", - "ethcore-util 1.2.0", + "ethash 1.3.0", + "ethcore-devtools 1.3.0", + "ethcore-ipc 1.3.0", + "ethcore-ipc-codegen 1.3.0", + "ethcore-util 1.3.0", "ethjson 0.1.0", + "ethstore 0.1.0", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", - "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "num_cpus 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", "rayon 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rust-crypto 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -273,50 +273,48 @@ dependencies = [ [[package]] name = "ethcore-dapps" -version = "1.2.0" +version = "1.3.0" dependencies = [ - "clippy 0.0.76 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-rpc 1.2.0", - "ethcore-util 1.2.0", - "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", - "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-rpc 1.3.0", + "ethcore-util 1.3.0", + "hyper 0.9.4 (git+https://github.com/ethcore/hyper)", + "jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)", "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", "parity-dapps-builtins 0.5.1 (git+https://github.com/ethcore/parity-dapps-builtins-rs.git)", - "parity-dapps-dao 0.4.0 (git+https://github.com/ethcore/parity-dapps-dao-rs.git)", - "parity-dapps-makerotc 0.3.0 (git+https://github.com/ethcore/parity-dapps-makerotc-rs.git)", "parity-dapps-status 0.5.0 (git+https://github.com/ethcore/parity-dapps-status-rs.git)", "parity-dapps-wallet 0.6.1 (git+https://github.com/ethcore/parity-dapps-wallet-rs.git)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ethcore-devtools" -version = "1.2.0" +version = "1.3.0" dependencies = [ "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ethcore-ipc" -version = "1.2.0" +version = "1.3.0" dependencies = [ - "ethcore-devtools 1.2.0", - "ethcore-util 1.2.0", + "ethcore-devtools 1.3.0", + "ethcore-util 1.3.0", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", "semver 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "ethcore-ipc-codegen" -version = "1.2.0" +version = "1.3.0" dependencies = [ "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "quasi 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -327,32 +325,32 @@ dependencies = [ [[package]] name = "ethcore-ipc-nano" -version = "1.2.0" +version = "1.3.0" dependencies = [ - "ethcore-ipc 1.2.0", - "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-ipc 1.3.0", + "jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg 0.5.1 (git+https://github.com/ethcore/nanomsg.rs.git)", ] [[package]] name = "ethcore-rpc" -version = "1.2.0" +version = "1.3.0" dependencies = [ - "clippy 0.0.76 (registry+https://github.com/rust-lang/crates.io-index)", - "ethash 1.2.0", - "ethcore 1.2.0", - "ethcore-devtools 1.2.0", - "ethcore-util 1.2.0", + "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", + "ethash 1.3.0", + "ethcore 1.3.0", + "ethcore-devtools 1.3.0", + "ethcore-util 1.3.0", "ethjson 0.1.0", - "ethsync 1.2.0", - "json-ipc-server 0.1.0 (git+https://github.com/ethcore/json-ipc-server.git)", - "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ethsync 1.3.0", + "json-ipc-server 0.2.4 (git+https://github.com/ethcore/json-ipc-server.git)", + "jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "jsonrpc-http-server 5.1.0 (git+https://github.com/ethcore/jsonrpc-http-server.git)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", "transient-hashmap 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -360,48 +358,48 @@ dependencies = [ [[package]] name = "ethcore-signer" -version = "1.2.0" +version = "1.3.0" dependencies = [ - "clippy 0.0.76 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore-rpc 1.2.0", - "ethcore-util 1.2.0", - "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "ethcore-rpc 1.3.0", + "ethcore-util 1.3.0", + "jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "parity-minimal-sysui 0.1.0 (git+https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git)", + "parity-minimal-sysui 0.2.0 (git+https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "ws 0.4.6 (git+https://github.com/ethcore/ws-rs.git)", + "ws 0.5.0 (git+https://github.com/ethcore/ws-rs.git?branch=stable)", ] [[package]] name = "ethcore-util" -version = "1.2.0" +version = "1.3.0" dependencies = [ "arrayvec 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)", "bigint 0.1.0", "chrono 0.2.22 (registry+https://github.com/rust-lang/crates.io-index)", - "clippy 0.0.76 (registry+https://github.com/rust-lang/crates.io-index)", + "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", "crossbeam 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)", "elastic-array 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", "eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)", - "ethcore-devtools 1.2.0", + "ethcore-devtools 1.3.0", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "igd 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", "itertools 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)", "json-tests 0.1.0", - "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)", "nix 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb 0.4.5 (git+https://github.com/ethcore/rust-rocksdb)", - "rust-crypto 0.2.35 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", "sha3 0.1.0", "slab 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "target_info 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -414,22 +412,49 @@ dependencies = [ name = "ethjson" version = "0.1.0" dependencies = [ - "ethcore-util 1.2.0", + "ethcore-util 1.3.0", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] -name = "ethsync" -version = "1.2.0" +name = "ethkey" +version = "0.2.0" dependencies = [ - "clippy 0.0.76 (registry+https://github.com/rust-lang/crates.io-index)", + "eth-secp256k1 0.5.4 (git+https://github.com/ethcore/rust-secp256k1)", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethstore" +version = "0.1.0" +dependencies = [ + "ethkey 0.2.0", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", + "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", + "rust-crypto 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)", + "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", + "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", + "tiny-keccak 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "ethsync" +version = "1.3.0" +dependencies = [ + "clippy 0.0.77 (registry+https://github.com/rust-lang/crates.io-index)", "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "ethcore 1.2.0", - "ethcore-util 1.2.0", + "ethcore 1.3.0", + "ethcore-util 1.3.0", "heapsize 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -440,7 +465,7 @@ dependencies = [ name = "fdlimit" version = "0.1.0" dependencies = [ - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -521,23 +546,22 @@ dependencies = [ [[package]] name = "hyper" -version = "0.9.3" -source = "git+https://github.com/ethcore/hyper#dbb4cf160ebf242f7f0459d547c40e9e6877ccf4" +version = "0.9.4" +source = "git+https://github.com/ethcore/hyper#7ccfcb2aa7e6aa6300efa8cebd6a0e6ce55582ea" dependencies = [ "cookie 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "language-tags 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mime 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "rotor 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)", + "rotor 0.6.3 (git+https://github.com/ethcore/rotor)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "spmc 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)", "typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "vecio 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -570,12 +594,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "json-ipc-server" -version = "0.1.0" -source = "git+https://github.com/ethcore/json-ipc-server.git#4f9226c4f84dcce2385a188374e3b5fc66b63e68" +version = "0.2.4" +source = "git+https://github.com/ethcore/json-ipc-server.git#902b031b8f50a59ecb4f389cbec1d264a98556bc" dependencies = [ "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "env_logger 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", + "jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "miow 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -589,11 +617,11 @@ dependencies = [ [[package]] name = "jsonrpc-core" -version = "2.0.5" +version = "2.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", - "serde_codegen 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_codegen 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", "serde_json 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)", "syntex 0.33.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -601,10 +629,10 @@ dependencies = [ [[package]] name = "jsonrpc-http-server" version = "5.1.0" -source = "git+https://github.com/ethcore/jsonrpc-http-server.git#6117b1d77b5a60d6fa2dc884f12aa7f5fd4585ca" +source = "git+https://github.com/ethcore/jsonrpc-http-server.git#e59c2fbaca499620874023755cb91f05b858ffe7" dependencies = [ - "hyper 0.9.3 (git+https://github.com/ethcore/hyper)", - "jsonrpc-core 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)", + "hyper 0.9.4 (git+https://github.com/ethcore/hyper)", + "jsonrpc-core 2.0.7 (registry+https://github.com/rust-lang/crates.io-index)", "unicase 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -629,17 +657,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "lazy_static" -version = "0.1.16" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "libc" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" - -[[package]] -name = "libc" -version = "0.2.10" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -657,7 +680,7 @@ name = "memchr" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -690,15 +713,15 @@ dependencies = [ [[package]] name = "mio" -version = "0.5.0" -source = "git+https://github.com/carllerche/mio.git#f4aa49a9d2c4507fb33a4533d5238e0365f67c99" +version = "0.5.1" +source = "git+https://github.com/ethcore/mio?branch=v0.5.x#3842d3b250ffd7bd9b16f9586b875ddcbac2b0dd" dependencies = [ "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", - "nix 0.5.0-pre (git+https://github.com/carllerche/nix-rust?rev=c4257f8a76)", + "nix 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -710,7 +733,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "miow 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "net2 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)", @@ -736,7 +759,7 @@ name = "nanomsg" version = "0.5.1" source = "git+https://github.com/ethcore/nanomsg.rs.git#c40fe442c9afaea5b38009a3d992ca044dcceb00" dependencies = [ - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "nanomsg-sys 0.5.0 (git+https://github.com/ethcore/nanomsg.rs.git)", ] @@ -746,7 +769,7 @@ version = "0.5.0" source = "git+https://github.com/ethcore/nanomsg.rs.git#c40fe442c9afaea5b38009a3d992ca044dcceb00" dependencies = [ "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -756,27 +779,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "cfg-if 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", "ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", ] -[[package]] -name = "nix" -version = "0.5.0-pre" -source = "git+https://github.com/carllerche/nix-rust?rev=c4257f8a76#c4257f8a76b69b0d2e9a001d83e4bef67c03b23f" -dependencies = [ - "bitflags 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", -] - [[package]] name = "nix" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -863,7 +877,7 @@ name = "num_cpus" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -882,7 +896,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "parity-dapps" version = "0.3.0" -source = "git+https://github.com/ethcore/parity-dapps-rs.git#1f065d93aa49338e4a453c77c839957f2db78895" +source = "git+https://github.com/ethcore/parity-dapps-rs.git#8cc812c26c903cf5764ce0f4cc3f2a7c3ddb0dc2" dependencies = [ "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", @@ -896,23 +910,7 @@ dependencies = [ [[package]] name = "parity-dapps-builtins" version = "0.5.1" -source = "git+https://github.com/ethcore/parity-dapps-builtins-rs.git#b3970ff4686a12321365cfafba6552bfaa2e7874" -dependencies = [ - "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", -] - -[[package]] -name = "parity-dapps-dao" -version = "0.4.0" -source = "git+https://github.com/ethcore/parity-dapps-dao-rs.git#dd6b9ca7c18fbfa714183a4f570bd75b8391c13d" -dependencies = [ - "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", -] - -[[package]] -name = "parity-dapps-makerotc" -version = "0.3.0" -source = "git+https://github.com/ethcore/parity-dapps-makerotc-rs.git#33568ac7209aa765c498bb2322e848f552656303" +source = "git+https://github.com/ethcore/parity-dapps-builtins-rs.git#7408838e8ca3b57c6b0cf5da2e31e0e275959955" dependencies = [ "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", ] @@ -920,7 +918,7 @@ dependencies = [ [[package]] name = "parity-dapps-status" version = "0.5.0" -source = "git+https://github.com/ethcore/parity-dapps-status-rs.git#53e159f52013be5d2e8ba7eca35f605ad6e3bfa9" +source = "git+https://github.com/ethcore/parity-dapps-status-rs.git#0cdd3512004e403aff7da3b8c16ba0bf5d6c911c" dependencies = [ "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", ] @@ -928,15 +926,15 @@ dependencies = [ [[package]] name = "parity-dapps-wallet" version = "0.6.1" -source = "git+https://github.com/ethcore/parity-dapps-wallet-rs.git#8923d4c73359c75ce04f0639bbcde46adb846b81" +source = "git+https://github.com/ethcore/parity-dapps-wallet-rs.git#867994fe25038f000f1cc09cd024a83700a03930" dependencies = [ "parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)", ] [[package]] name = "parity-minimal-sysui" -version = "0.1.0" -source = "git+https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git#4c704913f671060bb0e43b5ce4a68d02281115d5" +version = "0.2.0" +source = "git+https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git#996c9f3f0ebedc727aecb4ece191154e956ae292" [[package]] name = "phf" @@ -1033,7 +1031,7 @@ dependencies = [ [[package]] name = "quick-error" -version = "0.2.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] @@ -1046,7 +1044,7 @@ name = "rand" version = "0.3.14" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1079,30 +1077,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "rocksdb" version = "0.4.5" -source = "git+https://github.com/ethcore/rust-rocksdb#8f6e43b2d8799578a378648bcb17c01fb431dbec" +source = "git+https://github.com/ethcore/rust-rocksdb#9be41e05923616dfa28741c58b22776d479751e6" dependencies = [ - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "rocksdb-sys 0.3.0 (git+https://github.com/ethcore/rust-rocksdb)", ] [[package]] name = "rocksdb-sys" version = "0.3.0" -source = "git+https://github.com/ethcore/rust-rocksdb#8f6e43b2d8799578a378648bcb17c01fb431dbec" +source = "git+https://github.com/ethcore/rust-rocksdb#9be41e05923616dfa28741c58b22776d479751e6" dependencies = [ "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rotor" version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" +source = "git+https://github.com/ethcore/rotor#e63d45137b2eb66d1e085a7c6321a5db8b187576" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", - "quick-error 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", + "mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)", + "quick-error 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1112,18 +1109,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "termios 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "rust-crypto" -version = "0.2.35" +version = "0.2.36" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "gcc 0.3.28 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "time 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1165,12 +1162,12 @@ dependencies = [ [[package]] name = "serde" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "serde_codegen" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "aster 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1186,7 +1183,7 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)", - "serde 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 0.7.9 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1247,7 +1244,7 @@ version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "bitflags 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)", "term 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1273,7 +1270,7 @@ name = "termios" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1282,7 +1279,7 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1299,7 +1296,7 @@ version = "0.1.35" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", - "libc 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", + "libc 0.2.12 (registry+https://github.com/rust-lang/crates.io-index)", "winapi 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1384,7 +1381,7 @@ dependencies = [ [[package]] name = "url" -version = "1.0.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1448,16 +1445,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "ws" -version = "0.4.6" -source = "git+https://github.com/ethcore/ws-rs.git#5b28de58421b017b01f4565b2c35a46679707789" +version = "0.5.0" +source = "git+https://github.com/ethcore/ws-rs.git?branch=stable#a876fc115c3ef50a17c8822c9bd2f6e94473e005" dependencies = [ "httparse 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", - "mio 0.5.0 (git+https://github.com/carllerche/mio.git)", + "mio 0.5.1 (git+https://github.com/ethcore/mio?branch=v0.5.x)", "rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "sha1 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", - "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", - "url 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "url 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index f7f805d30..9493af006 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Ethcore client." name = "parity" -version = "1.2.0" +version = "1.3.0" license = "GPL-3.0" authors = ["Ethcore "] build = "build.rs" @@ -19,11 +19,10 @@ docopt = "0.6" time = "0.1" ctrlc = { git = "https://github.com/ethcore/rust-ctrlc.git" } fdlimit = { path = "util/fdlimit" } -daemonize = "0.2" num_cpus = "0.2" number_prefix = "0.2" rpassword = "0.2.1" -clippy = { version = "0.0.76", optional = true} +clippy = { version = "0.0.77", optional = true} ethcore = { path = "ethcore" } ethcore-util = { path = "util" } ethsync = { path = "sync" } @@ -37,6 +36,12 @@ ethcore-ipc = { path = "ipc/rpc" } json-ipc-server = { git = "https://github.com/ethcore/json-ipc-server.git" } ansi_term = "0.7" +[target.'cfg(windows)'.dependencies] +winapi = "0.2" + +[target.'cfg(not(windows))'.dependencies] +daemonize = "0.2" + [dependencies.hyper] version = "0.8" default-features = false diff --git a/README.md b/README.md index 193cbeb8f..53212b229 100644 --- a/README.md +++ b/README.md @@ -31,29 +31,43 @@ In a near-future release, it will be easy to install Dapps and use them through If you run into an issue while using parity, feel free to file one in this repository or hop on our [gitter chat room]([gitter-url]) to ask a question. We are glad to help! -Parity's current release is 1.1. You can download it at https://ethcore.io/parity.html or follow the instructions +Parity's current release is 1.2. You can download it at https://ethcore.io/parity.html or follow the instructions below to build from source. ---- -## Building from source +## Build dependencies Parity is fully compatible with Stable Rust. -We recommend installing Rust through [multirust](https://github.com/brson/multirust). If you don't already have multirust, you can install it like this: +We recommend installing Rust through [rustup](https://www.rustup.rs/). If you don't already have rustup, you can install it like this: + +- Linux and OSX: + ```bash + $ curl https://sh.rustup.rs -sSf | sh + ``` + +- Windows + + Make sure you have Visual Studio 2015 with C++ support installed. Next, download and run the rustup installer from + https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe, start "VS2015 x64 Native Tools Command Prompt", and use the following command to install and set up the msvc toolchain: + ``` + $ rustup default stable-x86_64-pc-windows-msvc + ``` + +Once you have rustup, install parity or download and build from source + +---- + +## Quick install -- Linux: ```bash -$ curl -sf https://raw.githubusercontent.com/brson/multirust/master/quick-install.sh | sh +cargo install --git https://github.com/ethcore/parity.git parity ``` -- OSX with Homebrew: -```bash -$ brew update && brew install multirust -$ multirust default stable -``` +---- -Then, download and build Parity: +## Build from source ```bash # download Parity code @@ -64,12 +78,11 @@ $ cd parity $ cargo build --release ``` -This will produce an executable in the `target/release` subdirectory. -Either run `cd target/release`, or copy `target/release/parity` to another location. +This will produce an executable in the `./target/release` subdirectory. To get started, just run ```bash -$ parity +$ ./target/release/parity ``` -and parity will begin syncing the Ethereum blockchain. \ No newline at end of file +and parity will begin syncing the Ethereum blockchain. diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..212b26ea9 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,46 @@ +environment: + matrix: + - TARGET: x86_64-pc-windows-msvc + cert: + secure: ESPpYVVAMG1fbJx6kq4ct/g9SQTXac4Hs6xXr6Oh4Zrk2dwYglNjxmzErdPnvu7gs/gekzrJ6KEQHYRc+5+4dKg6rRADQ681NLVx9vOggBs= + certpass: + secure: 0BgXJqxq9Ei34/hZ7121FQ== + keyfile: C:\users\appveyor\Certificates.p12 + +branches: + only: + - master + - /^beta-.*$/ + - /^stable-.*$/ + - /^beta$/ + - /^stable$/ + +install: + - git submodule update --init --recursive + - ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.9.0-x86_64-pc-windows-msvc.exe" + - ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -FileName nsis\SimpleFC.dll + - ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -FileName nsis\vc_redist.x64.exe + - rust-1.9.0-x86_64-pc-windows-msvc.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust" + - SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin;C:\Program Files (x86)\NSIS;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin + - rustc -V + - cargo -V + +build: off + +test_script: + - cargo test --verbose --release + +after_test: + - cargo build --verbose --release + - ps: if($env:cert) { Start-FileDownload $env:cert -FileName $env:keyfile } + - ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass target\release\parity.exe } + - makensis.exe nsis\installer.nsi + - ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass nsis\installer.exe } + +artifacts: + - path: nsis\installer.exe + name: Windows Installer (x86_64) + +cache: + - target + - C:\users\appveyor\.cargo -> appveyor.yml diff --git a/cov.sh b/cov.sh index a13db50b9..8de2264c0 100755 --- a/cov.sh +++ b/cov.sh @@ -16,6 +16,8 @@ if ! type kcov > /dev/null; then fi cargo test \ + -p ethkey \ + -p ethstore \ -p ethash \ -p ethcore-util \ -p ethcore \ @@ -28,7 +30,9 @@ cargo test \ rm -rf target/coverage mkdir -p target/coverage -EXCLUDE="~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests" +EXCLUDE="~/.multirust,rocksdb,secp256k1,src/tests,util/json-tests,util/src/network/tests,sync/src/tests,ethcore/src/tests,ethcore/src/evm/tests,ethstore/tests" +kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethkey-* +kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethstore-* kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore-* kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethash-* kcov --exclude-pattern $EXCLUDE --include-pattern src --verify target/coverage target/debug/deps/ethcore_util-* diff --git a/dapps/Cargo.toml b/dapps/Cargo.toml index 396ee4f2c..0476e9919 100644 --- a/dapps/Cargo.toml +++ b/dapps/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Parity Dapps crate" name = "ethcore-dapps" -version = "1.2.0" +version = "1.3.0" license = "GPL-3.0" authors = ["Ethcore Option<&EndpointInfo> { None } - fn to_handler(&self, path: EndpointPath) -> Box>; + fn to_handler(&self, path: EndpointPath) -> Box + Send>; } pub type Endpoints = BTreeMap>; -pub type Handler = server::Handler; +pub type Handler = server::Handler + Send; pub struct ContentHandler { content: String, @@ -65,7 +65,7 @@ impl ContentHandler { } impl server::Handler for ContentHandler { - fn on_request(&mut self, _request: server::Request) -> Next { + fn on_request(&mut self, _request: server::Request) -> Next { Next::write() } diff --git a/dapps/src/lib.rs b/dapps/src/lib.rs index a7fbd5963..22b075afd 100644 --- a/dapps/src/lib.rs +++ b/dapps/src/lib.rs @@ -132,9 +132,16 @@ impl Server { special.clone(), authorization.clone(), )) - .map(|l| Server { - server: Some(l), - panic_handler: panic_handler, + .map(|(l, srv)| { + + ::std::thread::spawn(move || { + srv.run(); + }); + + Server { + server: Some(l), + panic_handler: panic_handler, + } }) .map_err(ServerError::from) } diff --git a/dapps/src/page/handler.rs b/dapps/src/page/handler.rs index 5167c85c8..c3ec354e0 100644 --- a/dapps/src/page/handler.rs +++ b/dapps/src/page/handler.rs @@ -86,7 +86,7 @@ impl PageHandler { } impl server::Handler for PageHandler { - fn on_request(&mut self, req: server::Request) -> Next { + fn on_request(&mut self, req: server::Request) -> Next { self.file = match *req.uri() { RequestUri::AbsolutePath(ref path) => { self.app.file(&self.extract_path(path)) diff --git a/dapps/src/router/auth.rs b/dapps/src/router/auth.rs index d9933b51c..9459d0719 100644 --- a/dapps/src/router/auth.rs +++ b/dapps/src/router/auth.rs @@ -27,13 +27,13 @@ pub enum Authorized { /// Authorization was successful. Yes, /// Unsuccessful authorization. Handler for further work is returned. - No(Box>), + No(Box + Send>), } /// Authorization interface pub trait Authorization : Send + Sync { /// Checks if authorization is valid. - fn is_authorized(&self, req: &server::Request)-> Authorized; + fn is_authorized(&self, req: &server::Request)-> Authorized; } /// HTTP Basic Authorization handler @@ -45,13 +45,13 @@ pub struct HttpBasicAuth { pub struct NoAuth; impl Authorization for NoAuth { - fn is_authorized(&self, _req: &server::Request)-> Authorized { + fn is_authorized(&self, _req: &server::Request)-> Authorized { Authorized::Yes } } impl Authorization for HttpBasicAuth { - fn is_authorized(&self, req: &server::Request) -> Authorized { + fn is_authorized(&self, req: &server::Request) -> Authorized { let auth = self.check_auth(&req); match auth { @@ -89,7 +89,7 @@ impl HttpBasicAuth { self.users.get(&username.to_owned()).map_or(false, |pass| pass == password) } - fn check_auth(&self, req: &server::Request) -> Access { + fn check_auth(&self, req: &server::Request) -> Access { match req.headers().get::>() { Some(&header::Authorization( header::Basic { ref username, password: Some(ref password) } @@ -105,7 +105,7 @@ pub struct UnauthorizedHandler { } impl server::Handler for UnauthorizedHandler { - fn on_request(&mut self, _request: server::Request) -> Next { + fn on_request(&mut self, _request: server::Request) -> Next { Next::write() } @@ -141,7 +141,7 @@ impl server::Handler for UnauthorizedHandler { pub struct AuthRequiredHandler; impl server::Handler for AuthRequiredHandler { - fn on_request(&mut self, _request: server::Request) -> Next { + fn on_request(&mut self, _request: server::Request) -> Next { Next::write() } diff --git a/dapps/src/router/mod.rs b/dapps/src/router/mod.rs index 12738d79d..0cb0d38d0 100644 --- a/dapps/src/router/mod.rs +++ b/dapps/src/router/mod.rs @@ -49,12 +49,12 @@ pub struct Router { endpoints: Arc, special: Arc>>, authorization: Arc, - handler: Box>, + handler: Box + Send>, } impl server::Handler for Router { - fn on_request(&mut self, req: server::Request) -> Next { + fn on_request(&mut self, req: server::Request) -> Next { // Check authorization let auth = self.authorization.is_authorized(&req); @@ -124,7 +124,7 @@ impl Router { } } -fn extract_url(req: &server::Request) -> Option { +fn extract_url(req: &server::Request) -> Option { match *req.uri() { uri::RequestUri::AbsoluteUri(ref url) => { match Url::from_generic_url(url.clone()) { diff --git a/dapps/src/router/redirect.rs b/dapps/src/router/redirect.rs index 6faf9d0c8..6d738115d 100644 --- a/dapps/src/router/redirect.rs +++ b/dapps/src/router/redirect.rs @@ -33,7 +33,7 @@ impl Redirection { } impl server::Handler for Redirection { - fn on_request(&mut self, _request: server::Request) -> Next { + fn on_request(&mut self, _request: server::Request) -> Next { Next::write() } diff --git a/db/Cargo.toml b/db/Cargo.toml index b77840d02..2f5f0254e 100644 --- a/db/Cargo.toml +++ b/db/Cargo.toml @@ -3,7 +3,7 @@ description = "Ethcore Database" homepage = "http://ethcore.io" license = "GPL-3.0" name = "ethcore-db" -version = "1.2.0" +version = "1.3.0" authors = ["Ethcore "] build = "build.rs" @@ -12,7 +12,7 @@ syntex = "*" ethcore-ipc-codegen = { path = "../ipc/codegen" } [dependencies] -clippy = { version = "0.0.67", optional = true} +clippy = { version = "0.0.77", optional = true} ethcore-devtools = { path = "../devtools" } ethcore-ipc = { path = "../ipc/rpc" } rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" } diff --git a/devtools/Cargo.toml b/devtools/Cargo.toml index 1bccfc9d0..c82a4bb6a 100644 --- a/devtools/Cargo.toml +++ b/devtools/Cargo.toml @@ -3,7 +3,7 @@ description = "Ethcore development/test/build tools" homepage = "http://ethcore.io" license = "GPL-3.0" name = "ethcore-devtools" -version = "1.2.0" +version = "1.3.0" authors = ["Ethcore "] [dependencies] diff --git a/doc.sh b/doc.sh index fb39ef272..41251f7a8 100755 --- a/doc.sh +++ b/doc.sh @@ -2,6 +2,8 @@ # generate documentation only for partiy and ethcore libraries cargo doc --no-deps --verbose \ + -p ethkey \ + -p ethstore \ -p ethash \ -p ethcore-util \ -p ethcore \ diff --git a/docker/centos/Dockerfile b/docker/centos/Dockerfile new file mode 100644 index 000000000..56015422c --- /dev/null +++ b/docker/centos/Dockerfile @@ -0,0 +1,27 @@ +FROM centos:latest +WORKDIR /build +# install tools and dependencies +RUN yum -y update&& \ + yum install -y git make gcc-c++ gcc file binutils +# install rustup +RUN curl -sSf https://static.rust-lang.org/rustup.sh -o rustup.sh &&\ +ls&&\ + sh rustup.sh -s -- --disable-sudo +# show backtraces +ENV RUST_BACKTRACE 1 +# set compiler +ENV CXX g++ +ENV CC gcc +# show tools +RUN rustc -vV && \ +cargo -V && \ +gcc -v &&\ +g++ -v +# build parity +RUN git clone https://github.com/ethcore/parity && \ + cd parity&&\ + ls -a&&\ + cargo build --release --verbose && \ + ls /build/parity/target/release/parity && \ + strip /build/parity/target/release/parity +RUN file /build/parity/target/release/parity diff --git a/docker/ubuntu-aarch64/Dockerfile b/docker/ubuntu-aarch64/Dockerfile new file mode 100644 index 000000000..3212f84d0 --- /dev/null +++ b/docker/ubuntu-aarch64/Dockerfile @@ -0,0 +1,47 @@ +FROM ubuntu:14.04 +WORKDIR /build +# install tools and dependencies +RUN apt-get -y update && \ + apt-get install -y --force-yes --no-install-recommends \ + curl git make g++ gcc-aarch64-linux-gnu g++-aarch64-linux-gnu \ + libc6-arm64-cross libc6-dev-arm64-cross wget file ca-certificates \ + binutils-aarch64-linux-gnu \ + && \ + apt-get clean + +# install rustup +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y + +# rustup directory +ENV PATH /root/.cargo/bin:$PATH + +ENV RUST_TARGETS="aarch64-unknown-linux-gnu" + +# multirust add arm--linux-gnuabhf toolchain +RUN rustup target add aarch64-unknown-linux-gnu + +# show backtraces +ENV RUST_BACKTRACE 1 + +# set compilers +ENV CXX aarch64-linux-gnu-g++ +ENV CC aarch64-linux-gnu-gcc + +# show tools + RUN rustc -vV && \ + cargo -V && \ + gcc -v &&\ + g++ -v + +# build parity +RUN git clone https://github.com/ethcore/parity && \ + cd parity && \ + mkdir -p .cargo && \ + echo '[target.aarch64-unknown-linux-gnu]\n\ + linker = "aarch64-linux-gnu-gcc"\n'\ + >>.cargo/config && \ + cat .cargo/config && \ + cargo build --target aarch64-unknown-linux-gnu --release --verbose && \ + ls /build/parity/target/aarch64-unknown-linux-gnu/release/parity && \ + /usr/bin/aarch64-linux-gnu-strip /build/parity/target/aarch64-unknown-linux-gnu/release/parity +RUN file /build/parity/target/aarch64-unknown-linux-gnu/release/parity diff --git a/docker/ubuntu-arm/Dockerfile b/docker/ubuntu-arm/Dockerfile index 9678912cb..fab325e5e 100644 --- a/docker/ubuntu-arm/Dockerfile +++ b/docker/ubuntu-arm/Dockerfile @@ -2,45 +2,46 @@ FROM ubuntu:14.04 WORKDIR /build # install tools and dependencies RUN apt-get -y update && \ - apt-get install -y --force-yes --no-install-recommends \ - curl git make g++ gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf \ - libc6-dev-armhf-cross wget file ca-certificates \ - binutils-arm-linux-gnueabihf \ - && \ + apt-get install -y --force-yes --no-install-recommends \ + curl git make g++ gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf \ + libc6-dev-armhf-cross wget file ca-certificates \ + binutils-arm-linux-gnueabihf \ + && \ apt-get clean -# install multirust -RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes +# install rustup +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y + +# rustup directory +ENV PATH /root/.cargo/bin:$PATH + ENV RUST_TARGETS="arm-unknown-linux-gnueabihf" # multirust add arm--linux-gnuabhf toolchain -RUN multirust add-target stable arm-unknown-linux-gnueabihf +RUN rustup target add armv7-unknown-linux-gnueabihf # show backtraces ENV RUST_BACKTRACE 1 + # set compilers -ENV CXX arm-linux-gnueabihf-g++ -ENV CC arm-linux-gnueabihf-gcc +ENV CXX arm-linux-gnueabihf-g++ +ENV CC arm-linux-gnueabihf-gcc + +# show tools + RUN rustc -vV && \ + cargo -V && \ + gcc -v &&\ + g++ -v + # build parity RUN git clone https://github.com/ethcore/parity && \ - cd parity && \ - git checkout master && \ - wget https://github.com/nix-rust/nix/archive/v0.5.0.tar.gz && \ - tar -xf v0.5.0.tar.gz && \ - rm -rf v0.5.0.tar.gz && \ - wget https://github.com/thkaw/mio/archive/v0.5.x.tar.gz && \ - tar -xf v0.5.x.tar.gz && \ - rm -rf v0.5.x.tar.gz && \ - mkdir -p .cargo && \ - echo 'paths = ["nix-0.5.0","mio-0.5.x"]\n\ - [target.arm-unknown-linux-gnueabihf]\n\ - linker = "arm-linux-gnueabihf-gcc"\n'\ - >>.cargo/config && \ - cat .cargo/config && \ - rustc -vV && \ - cargo -V && \ - cargo build --target arm-unknown-linux-gnueabihf --release --verbose && \ - ls /build/parity/target/arm-unknown-linux-gnueabihf/release/parity && \ - file /build/parity/target/arm-unknown-linux-gnueabihf/release/parity && \ - /usr/bin/arm-linux-gnueabihf-strip /build/parity/target/arm-unknown-linux-gnueabihf/release/parity -RUN file /build/parity/target/arm-unknown-linux-gnueabihf/release/parity + cd parity && \ + mkdir -p .cargo && \ + echo '[target.armv7-unknown-linux-gnueabihf]\n\ + linker = "arm-linux-gnueabihf-gcc"\n'\ + >>.cargo/config && \ + cat .cargo/config && \ + cargo build --target armv7-unknown-linux-gnueabihf --release --verbose && \ + ls /build/parity/target/armv7-unknown-linux-gnueabihf/release/parity && \ + /usr/bin/arm-linux-gnueabihf-strip /build/parity/target/armv7-unknown-linux-gnueabihf/release/parity +RUN file /build/parity/target/armv7-unknown-linux-gnueabihf/release/parity diff --git a/docker/ubuntu-dev/Dockerfile b/docker/ubuntu-dev/Dockerfile index 05e8dfe8f..72b4bb08e 100644 --- a/docker/ubuntu-dev/Dockerfile +++ b/docker/ubuntu-dev/Dockerfile @@ -27,11 +27,11 @@ RUN git clone https://github.com/debris/evmjit && \ mkdir build && cd build && \ cmake .. && make && make install && cd -# install multirust -RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes +# install rustup +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y -# export rust LIBRARY_PATH -ENV LIBRARY_PATH /usr/local/lib +# rustup directory +ENV PATH /root/.cargo/bin:$PATH # show backtraces ENV RUST_BACKTRACE 1 diff --git a/docker/ubuntu-jit/Dockerfile b/docker/ubuntu-jit/Dockerfile index 138882d2b..89c38cee7 100644 --- a/docker/ubuntu-jit/Dockerfile +++ b/docker/ubuntu-jit/Dockerfile @@ -1,42 +1,53 @@ FROM ubuntu:14.04 - +WORKDIR /build # install tools and dependencies RUN apt-get update && \ - apt-get install -y \ - # make - build-essential \ - # add-apt-repository - software-properties-common \ - curl \ - wget \ - git \ - g++ \ - # evmjit dependencies - zlib1g-dev \ - libedit-dev + apt-get install -y \ + # make + build-essential \ + # add-apt-repository + software-properties-common \ + curl \ + wget \ + git \ + g++ \ + binutils \ + file \ + # evmjit dependencies + zlib1g-dev \ + libedit-dev -# cmake, llvm and rocksdb ppas. then update ppas +# cmake and llvm ppas. then update ppas 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" && \ - apt-get update && \ - apt-get install -y --force-yes cmake llvm-3.7-dev + add-apt-repository "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.7 main" && \ + apt-get update && \ + apt-get install -y --force-yes cmake llvm-3.7-dev # install evmjit RUN git clone https://github.com/debris/evmjit && \ - cd evmjit && \ - mkdir build && cd build && \ - cmake .. && make && make install && cd + cd evmjit && \ + mkdir build && cd build && \ + cmake .. && make && make install && cd -# install multirust -RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes +# install rustup +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y -# export rust LIBRARY_PATH -ENV LIBRARY_PATH /usr/local/lib +# rustup directory +ENV PATH /root/.cargo/bin:$PATH # show backtraces ENV RUST_BACKTRACE 1 +# show tools +RUN rustc -vV && \ +cargo -V && \ +gcc -v &&\ +g++ -v + # build parity RUN git clone https://github.com/ethcore/parity && \ - cd parity && \ - cargo build --release --features ethcore/jit + cd parity && \ + cargo build --release --features ethcore/jit --verbose && \ + ls /build/parity/target/release/parity && \ + strip /build/parity/target/release/parity +RUN file /build/parity/target/release/parity diff --git a/docker/ubuntu/Dockerfile b/docker/ubuntu/Dockerfile index 38c628d0e..9999909c3 100644 --- a/docker/ubuntu/Dockerfile +++ b/docker/ubuntu/Dockerfile @@ -1,23 +1,33 @@ FROM ubuntu:14.04 - +WORKDIR /build # install tools and dependencies RUN apt-get update && \ - apt-get install -y \ - g++ \ - curl \ - git \ - make + apt-get install -y \ + g++ \ + curl \ + git \ + file \ + binutils -# install multirust -RUN curl -sf https://raw.githubusercontent.com/brson/multirust/master/blastoff.sh | sh -s -- --yes +# install rustup +RUN curl https://sh.rustup.rs -sSf | sh -s -- -y -# export rust LIBRARY_PATH -ENV LIBRARY_PATH /usr/local/lib +# rustup directory +ENV PATH /root/.cargo/bin:$PATH # show backtraces ENV RUST_BACKTRACE 1 +# show tools +RUN rustc -vV && \ +cargo -V && \ +gcc -v &&\ +g++ -v + # build parity RUN git clone https://github.com/ethcore/parity && \ - cd parity && \ - cargo build --release + cd parity && \ + cargo build --release --verbose && \ + ls /build/parity/target/release/parity && \ + strip /build/parity/target/release/parity +RUN file /build/parity/target/release/parity diff --git a/ethash/Cargo.toml b/ethash/Cargo.toml index cfa1fa9b7..94a714d55 100644 --- a/ethash/Cargo.toml +++ b/ethash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethash" -version = "1.2.0" +version = "1.3.0" authors = ["arkpar "] build = "build.rs" @@ -22,14 +22,15 @@ ethcore-util = { path = "../util" } evmjit = { path = "../evmjit", optional = true } ethash = { path = "../ethash" } num_cpus = "0.2" -clippy = { version = "0.0.76", optional = true} +clippy = { version = "0.0.77", optional = true} crossbeam = "0.2.9" -lazy_static = "0.1" +lazy_static = "0.2" ethcore-devtools = { path = "../devtools" } ethjson = { path = "../json" } bloomchain = "0.1" "ethcore-ipc" = { path = "../ipc/rpc" } rayon = "0.3.1" +ethstore = { path = "../ethstore" } [features] jit = ["evmjit"] diff --git a/ethcore/res/ethereum/frontier.json b/ethcore/res/ethereum/frontier.json index a57ad8ed8..159fe6d44 100644 --- a/ethcore/res/ethereum/frontier.json +++ b/ethcore/res/ethereum/frontier.json @@ -9,7 +9,8 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", - "frontierCompatibilityModeLimit": "0x118c30" + "frontierCompatibilityModeLimit": "0x118c30", + "daoRescueSoftFork": false } } }, diff --git a/ethcore/res/ethereum/frontier_dao_rescue.json b/ethcore/res/ethereum/frontier_dao_rescue.json new file mode 100644 index 000000000..4ceff14b7 --- /dev/null +++ b/ethcore/res/ethereum/frontier_dao_rescue.json @@ -0,0 +1,26729 @@ +{ + "name": "Frontier/Homestead", + "engine": { + "Ethash": { + "params": { + "gasLimitBoundDivisor": "0x0400", + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "frontierCompatibilityModeLimit": "0x118c30", + "daoRescueSoftFork": true + } + } + }, + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x1" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x1388", + "stateRoot": "0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544" + }, + "nodes": [ + "enode://a979fb575495b8d6db44f750317d0f4622bf4c2aa3365d6af7c284339968eef29b69ad0dce72a4d8db5ebb4968de0e3bec910127f134779fbcb0cb6d3331163c@52.16.188.185:30303", + "enode://de471bccee3d042261d52e9bff31458daecc406142b401d4cd848f677479f73104b9fdeb090af9583d3391b7f10cb2ba9e26865dd5fca4fcdc0fb1e3b723c786@54.94.239.50:30303", + "enode://1118980bf48b0a3640bdba04e0fe78b1add18e1cd99bf22d53daac1fd9972ad650df52176e7c7d89d1114cfef2bc23a2959aa54998a46afcf7d91809f0855082@52.74.57.123:30303", + "enode://248f12bc8b18d5289358085520ac78cd8076485211e6d96ab0bc93d6cd25442db0ce3a937dc404f64f207b0b9aed50e25e98ce32af5ac7cb321ff285b97de485@zero.parity.io:30303" + ], + "accounts": { + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "3282791d6fd713f1e94f4bfd565eaa78b3a0599d": { + "balance": "1337000000000000000000" + }, + "17961d633bcf20a7b029a7d94b7df4da2ec5427f": { + "balance": "229427000000000000000" + }, + "493a67fe23decc63b10dda75f3287695a81bd5ab": { + "balance": "880000000000000000000" + }, + "01fb8ec12425a04f813e46c54c05748ca6b29aa9": { + "balance": "259800000000000000000" + }, + "d2a030ac8952325f9e1db378a71485a24e1b07b2": { + "balance": "2000000000000000000000" + }, + "77a34907f305a54c85db09c363fde3c47e6ae21f": { + "balance": "985000000000000000000" + }, + "391a77405c09a72b5e8436237aaaf95d68da1709": { + "balance": "49082000000000000000" + }, + "00aada25ea2286709abb422d41923fd380cd04c7": { + "balance": "650100000000000000000" + }, + "acc46a2a555c74ded4a2bd094e821b97843b40c0": { + "balance": "1940000000000000000000" + }, + "de07fb5b7a464e3ba7fbe09e9acb271af5338c58": { + "balance": "50000000000000000000" + }, + "4c696be99f3a690440c3436a59a7d7e937d6ba0d": { + "balance": "3460000000000000000000" + }, + "fa33553285a973719a0d5f956ff861b2d89ed304": { + "balance": "20000000000000000000" + }, + "67cfda6e70bf7657d39059b59790e5145afdbe61": { + "balance": "646000000000000000000" + }, + "a321091d3018064279db399d2b2a88a6f440ae24": { + "balance": "3200000000000000000000" + }, + "fb3fa1ac08aba9cc3bf0fe9d483820688f65b410": { + "balance": "30000000000000000000000" + }, + "6715c14035fb57bb3d667f7b707498c41074b855": { + "balance": "700000000000000000000" + }, + "d4344f7d5cad65d17e5c2d0e7323943d6f62fe92": { + "balance": "267400000000000000000" + }, + "a3294626ec2984c43b43da4d5d8e4669b11d4b59": { + "balance": "1008000000000000000000" + }, + "656018584130db83ab0591a8128d9381666a8d0e": { + "balance": "63960000000000000000" + }, + "0fa010ce0c731d3b628e36b91f571300e49dbeab": { + "balance": "999800000000000000000" + }, + "3098b65db93ecacaf7353c48808390a223d57684": { + "balance": "449965000000000000000" + }, + "ae635bf73831119d2d29c0d04ff8f8d8d0a57a46": { + "balance": "1337000000000000000000" + }, + "0f7515ff0e808f695e0c20485ff96ed2f7b79310": { + "balance": "1000169000000000000000" + }, + "8b30c04098d7a7e6420c357ea7bfa49bac9a8a18": { + "balance": "8000200000000000000000" + }, + "64dba2d6615b8bd7571836dc75bc79d314f5ecee": { + "balance": "10000000000000000000000" + }, + "e7912d4cf4562c573ddc5b71e37310e378ef86c9": { + "balance": "394000000000000000000" + }, + "a4da34450d22ec0ffcede0004b02f7872ee0b73a": { + "balance": "93342000000000000000" + }, + "34437d1465640b136cb5841c3f934f9ba0b7097d": { + "balance": "173000000000000000000" + }, + "c652871d192422c6bc235fa063b44a7e1d43e385": { + "balance": "155000000000000000000" + }, + "a8a708e84f82db86a35502193b4c6ee9a76ebe8f": { + "balance": "1015200000000000000000" + }, + "5c3f567faff7bad1b5120022e8cbcaa82b4917b3": { + "balance": "2000000000000000000000" + }, + "dbc1d0ee2bab531140de137722cd36bdb4e47194": { + "balance": "200000000000000000000" + }, + "f59dab1bf8df11327e61f9b7a14b563a96ec3554": { + "balance": "6000000000000000000000" + }, + "456f8d746682b224679349064d1b368c7c05b176": { + "balance": "3700000000000000000000" + }, + "5f13154631466dcb1353c890932a7c97e0878e90": { + "balance": "6000000000000000000000" + }, + "f4b1626e24f30bcad9273c527fcc714b5d007b8f": { + "balance": "200000000000000000000" + }, + "a8db0b9b201453333c757f6ad9bcb555c02da93b": { + "balance": "2199970000000000000000" + }, + "a0fc7e53c5ebd27a2abdac45261f84ab3b51aefb": { + "balance": "3008250000000000000000" + }, + "1b636b7a496f044d7359596e353a104616436f6b": { + "balance": "360354000000000000000" + }, + "74bce9ec38362d6c94ccac26d5c0e13a8b3b1d40": { + "balance": "999954000000000000000" + }, + "9834682180b982d166badb9d9d1d9bbf016d87ee": { + "balance": "2000000000000000000000" + }, + "1e6e0153fc161bc05e656bbb144c7187bf4fe84d": { + "balance": "2000000000000000000000" + }, + "989c0ccff654da03aeb11af701054561d6297e1d": { + "balance": "4000000000000000000000" + }, + "78a1e254409fb1b55a7cb4dd8eba3b30c8bad9ef": { + "balance": "100000000000000000000" + }, + "9ef1896b007c32a15114fb89d73dbd47f9122b69": { + "balance": "4000000000000000000000" + }, + "33320dd90f2baa110dd334872a998f148426453c": { + "balance": "999972000000000000000" + }, + "e72e1d335cc29a96b9b1c02f003a16d971e90b9d": { + "balance": "1580000000000000000000" + }, + "0921605f99164e3bcc28f31caece78973182561d": { + "balance": "793744000000000000000" + }, + "fc00a420a36107dfd5f495128a5fe5abb2db0f34": { + "balance": "5960000000000000000000" + }, + "dfcbdf09454e1a5e4a40d3eef7c5cf1cd3de9486": { + "balance": "4000000000000000000000" + }, + "646e043d0597a664948fbb0dc15475a3a4f3a6ed": { + "balance": "20000000000000000000" + }, + "79aeb34566b974c35a5881dec020927da7df5d25": { + "balance": "2000000000000000000000" + }, + "dbadc61ed5f0460a7f18e51b2fb2614d9264a0e0": { + "balance": "40000000000000000000" + }, + "97b91efe7350c2d57e7e406bab18f3617bcde14a": { + "balance": "9999980000000000000000" + }, + "8398e07ebcb4f75ff2116de77c1c2a99f303a4cf": { + "balance": "500000000000000000000" + }, + "f02796295101674288c1d93467053d042219b794": { + "balance": "740000000000000000000" + }, + "f4ed848ec961739c2c7e352f435ba70a7cd5db38": { + "balance": "1970000000000000000000" + }, + "82485728d0e281563758c75ab27ed9e882a0002d": { + "balance": "147000000000000000000" + }, + "427ec668ac9404e895cc861511d1620a4912be98": { + "balance": "40000000000000000000000" + }, + "1bbc199e586790be87afedc849c04726745c5d7b": { + "balance": "4000000000000000000000" + }, + "10d945334ecde47beb9ca3816c173dfbbd0b5333": { + "balance": "1400000000000000000000" + }, + "1dcebcb7656df5dcaa3368a055d22f9ed6cdd940": { + "balance": "499800000000000000000" + }, + "2ac1f8d7bf721f3cfe74d20fea9b87a28aaa982c": { + "balance": "161000000000000000000" + }, + "0a47ad9059a249fc936b2662353da6905f75c2b9": { + "balance": "2000000000000000000000" + }, + "768498934e37e905f1d0e77b44b574bcf3ec4ae8": { + "balance": "20000000000000000000000" + }, + "f46b6b9c7cb552829c1d3dfd8ffb11aabae782f6": { + "balance": "21000000000000000000" + }, + "7aea25d42b2612286e99c53697c6bc4100e2dbbf": { + "balance": "2000000000000000000000" + }, + "af3615c789d0b1152ad4db25fe5dcf222804cf62": { + "balance": "1000000000000000000000" + }, + "92e6581e1da1f9b846e09347333dc818e2d2ac66": { + "balance": "3640000000000000000000" + }, + "240305727313d01e73542c775ff59d11cd35f819": { + "balance": "5931229000000000000000" + }, + "b95cfda8465ba9c2661b249fc3ab661bdfa35ff0": { + "balance": "318949000000000000000" + }, + "1b0d076817e8d68ee2df4e1da1c1142d198c4435": { + "balance": "1550000000000000000000" + }, + "93c2e64e5de5589ed25006e843196ee9b1cf0b3e": { + "balance": "1670000000000000000000" + }, + "0e2e504a2d1122b5a9feee5cb1451bf4c2ace87b": { + "balance": "3940000000000000000000" + }, + "22b96ab2cad55db100b53001f9e4db378104c807": { + "balance": "10000000000000000000000" + }, + "a927d48bb6cb814bc609cbcaa9151f5d459a27e1": { + "balance": "271600000000000000000" + }, + "5cbd8daf27ddf704cdd0d909a789ba36ed4f37b2": { + "balance": "13400000000000000000" + }, + "9adbd3bc7b0afc05d1d2eda49ff863939c48db46": { + "balance": "199955000000000000000" + }, + "ac7e03702723cb16ee27e22dd0b815dc2d5cae9f": { + "balance": "16000000000000000000000" + }, + "1e210e7047886daa52aaf70f4b991dac68e3025e": { + "balance": "200000000000000000000" + }, + "c98048687f2bfcc9bd90ed18736c57edd352b65d": { + "balance": "1000000000000000000000" + }, + "81c18c2a238ddc4cba230a072dd7dc101e620273": { + "balance": "1337000000000000000000" + }, + "cb3d766c983f192bcecac70f4ee03dd9ff714d51": { + "balance": "100000000000000000000" + }, + "44a63d18424587b9b307bfc3c364ae10cd04c713": { + "balance": "20000000000000000000" + }, + "4ab2d34f04834fbf7479649cab923d2c4725c553": { + "balance": "3520000000000000000000" + }, + "b834acf3015322c58382eeb2b79638906e88b6de": { + "balance": "24000000000000000000000" + }, + "7d551397f79a2988b064afd0efebee802c7721bc": { + "balance": "39400000000000000000000" + }, + "b537d36a70eeb8d3e5c80de815225c1158cb92c4": { + "balance": "1500000000000000000000" + }, + "805ce51297a0793b812067f017b3e7b2df9bb1f9": { + "balance": "100000000000000000000" + }, + "085ba65febe23eefc2c802666ab1262382cfc494": { + "balance": "400000000000000000000" + }, + "b1c0d08b36e184f9952a4037e3e53a667d070a4e": { + "balance": "1000000000000000000000" + }, + "83fe5a1b328bae440711beaf6aad6026eda6d220": { + "balance": "20000000000000000000000" + }, + "7fd679e5fb0da2a5d116194dcb508318edc580f3": { + "balance": "6560000000000000000000" + }, + "41ad369f758fef38a19aa3149379832c818ef2a0": { + "balance": "1000060000000000000000" + }, + "6d846dc12657e91af25008519c3e857f51707dd6": { + "balance": "4590000000000000000000" + }, + "c02d6eadeacf1b78b3ca85035c637bb1ce01f490": { + "balance": "4000000000000000000000" + }, + "826eb7cd7319b82dd07a1f3b409071d96e39677f": { + "balance": "1000000000000000000000" + }, + "4ac9905a4cb6ab1cfd62546ee5917300b87c4fde": { + "balance": "1015200000000000000000" + }, + "cf6e52e6b77480b1867efec6446d9fc3cc3577e8": { + "balance": "222010000000000000000" + }, + "2476b2bb751ce748e1a4c4ff7b230be0c15d2245": { + "balance": "4000000000000000000000" + }, + "1a505e62a74e87e577473e4f3afa16bedd3cfa52": { + "balance": "500000000000000000000" + }, + "21d02705f3f64905d80ed9147913ea8c7307d695": { + "balance": "1363740000000000000000" + }, + "7b1daf14891b8a1e1bd429d8b36b9a4aa1d9afbf": { + "balance": "500000000000000000000" + }, + "5338ef70eac9dd9af5a0503b5efad1039e67e725": { + "balance": "2674000000000000000000" + }, + "50ca86b5eb1d01874df8e5f34945d49c6c1ab848": { + "balance": "1000000000000000000000" + }, + "f3cc8bcb559465f81bfe583bd7ab0a2306453b9e": { + "balance": "20000000000000000000000" + }, + "5c323457e187761a8276e359b7b7af3f3b6e3df6": { + "balance": "10000000000000000000000" + }, + "4d82d7700c123bb919419bbaf046799c6b0e2c66": { + "balance": "20000000000000000000000" + }, + "8a66abbc2d30ce21a833b0db8e561d5105e0a72c": { + "balance": "699958000000000000000" + }, + "2ae53866fc2d14d572ab73b4a065a1188267f527": { + "balance": "8000000000000000000000" + }, + "9af5c9894c33e42c2c518e3ac670ea9505d1b53e": { + "balance": "18200000000000000000" + }, + "cba25c7a503cc8e0d04971ca05c762f9b762b48b": { + "balance": "500000000000000000000" + }, + "fda3042819af3e662900e1b92b4358eda6e92590": { + "balance": "118200000000000000000000" + }, + "9bd7c38a4210304a4d653edeff1b3ce45fce7843": { + "balance": "282000000000000000000" + }, + "edc22fb92c638e1e21ff5cf039daa6e734dafb29": { + "balance": "298000000000000000000" + }, + "a1f193a0592f1feb9fdfc90aa813784eb80471c9": { + "balance": "1400000000000000000000" + }, + "e97fde0b67716325cf0ecce8a191a3761b2c791d": { + "balance": "1004700000000000000000" + }, + "110237cf9117e767922fc4a1b78d7964da82df20": { + "balance": "3940000000000000000000" + }, + "e32f95766d57b5cd4b173289d6876f9e64558194": { + "balance": "100000000000000000000" + }, + "f2d59c8923759073d6f415aaf8eb065ff2f3b685": { + "balance": "7880000000000000000000" + }, + "c53d79f7cb9b70952fd30fce58d54b9f0b59f647": { + "balance": "5089200000000000000000" + }, + "9eb281c32719c40fdb3e216db0f37fbc73a026b7": { + "balance": "20000000000000000000" + }, + "2d6511fd7a3800b26854c7ec39c0dcb5f4c4e8e8": { + "balance": "399910000000000000000" + }, + "61ba87c77e9b596de7ba0e326fddfeec2163ef66": { + "balance": "200000000000000000000" + }, + "de1121829c9a08284087a43fbd2fc1142a3233b4": { + "balance": "1000000000000000000000" + }, + "22a25812ab56dcc423175ed1d8adacce33cd1810": { + "balance": "1850000000000000000000" + }, + "518cef27b10582b6d14f69483ddaa0dd3c87bb5c": { + "balance": "600000000000000000000" + }, + "59161749fedcf1c721f2202d13ade2abcf460b3d": { + "balance": "2000000000000000000000" + }, + "3e36c17253c11cf38974ed0db1b759160da63783": { + "balance": "7000000000000000000000" + }, + "cbfa76db04ce38fb205d37b8d377cf1380da0317": { + "balance": "1430000000000000000000" + }, + "a7e83772bc200f9006aa2a260dbaa8483dc52b30": { + "balance": "207730000000000000000" + }, + "e87eac6d602b4109c9671bf57b950c2cfdb99d55": { + "balance": "49932000000000000000" + }, + "9b06ad841dffbe4ccf46f1039fc386f3c321446e": { + "balance": "2000000000000000000000" + }, + "e0f903c1e48ac421ab48528f3d4a2648080fe043": { + "balance": "1015200000000000000000" + }, + "5d872b122e994ef27c71d7deb457bf65429eca6c": { + "balance": "7999973000000000000000" + }, + "f34083ecea385017aa40bdd35ef7effb4ce7762d": { + "balance": "400000000000000000000" + }, + "7f3709391f3fbeba3592d175c740e87a09541d02": { + "balance": "480000000000000000000" + }, + "888e94917083d152202b53163939869d271175b4": { + "balance": "4000000000000000000000" + }, + "bed4c8f006a27c1e5f7ce205de75f516bfb9f764": { + "balance": "16000000000000000000000" + }, + "b3a6bd41f9d9c3201e050b87198fbda399342210": { + "balance": "3622615000000000000000" + }, + "550aadae1221b07afea39fba2ed62e05e5b7b5f9": { + "balance": "20000000000000000000" + }, + "bcedc4267ccb89b31bb764d7211171008d94d44d": { + "balance": "200000000000000000000" + }, + "6229dcc203b1edccfdf06e87910c452a1f4d7a72": { + "balance": "32500000000000000000000" + }, + "94be3ae54f62d663b0d4cc9e1ea8fe9556ea9ebf": { + "balance": "23280000000000000000" + }, + "0e0c9d005ea016c295cd795cc9213e87febc33eb": { + "balance": "198000000000000000000" + }, + "55d057bcc04bd0f4af9642513aa5090bb3ff93fe": { + "balance": "1106680000000000000000" + }, + "ed9e030ca75cb1d29ea01d0d4cdfdccd3844b6e4": { + "balance": "30895000000000000000" + }, + "86c4ce06d9ac185bb148d96f7b7abe73f441006d": { + "balance": "10000000000000000000000" + }, + "2c04115c3e52961b0dc0b0bf31fba4546f5966fd": { + "balance": "200000000000000000000" + }, + "b959dce02e91d9db02b1bd8b7d17a9c41a97af09": { + "balance": "8000000000000000000000" + }, + "e01547ba42fcafaf93938becf7699f74290af74f": { + "balance": "2000000000000000000000" + }, + "c593d6e37d14b566643ac4135f243caa0787c182": { + "balance": "12000000000000000000000" + }, + "2c0ee134d8b36145b47beee7af8d2738dbda08e8": { + "balance": "201000000000000000000" + }, + "0ef54ac7264d2254abbb5f8b41adde875157db7c": { + "balance": "40000000000000000000" + }, + "0349634dc2a9e80c3f7721ee2b5046aeaaedfbb5": { + "balance": "4000000000000000000000" + }, + "873e49135c3391991060290aa7f6ccb8f85a78db": { + "balance": "20000000000000000000" + }, + "05236d4c90d065f9e3938358aaffd777b86aec49": { + "balance": "500000000000000000000" + }, + "d2abd84a181093e5e229136f42d835e8235de109": { + "balance": "100007000000000000000" + }, + "b56a780028039c81caf37b6775c620e786954764": { + "balance": "2000000000000000000000" + }, + "86df73bd377f2c09de63c45d67f283eaefa0f4ab": { + "balance": "1000000000000000000000" + }, + "7670b02f2c3cf8fd4f4730f3381a71ea431c33c7": { + "balance": "267400000000000000000" + }, + "24aa1151bb765fa3a89ca50eb6e1b1c706417fd4": { + "balance": "3100000000000000000000" + }, + "43227d65334e691cf231b4a4e1d339b95d598afb": { + "balance": "10000000000000000000000" + }, + "695550656cbf90b75d92ad9122d90d23ca68ca4d": { + "balance": "1000000000000000000000" + }, + "5281733473e00d87f11e9955e589b59f4ac28e7a": { + "balance": "660360000000000000000000" + }, + "99a96bf2242ea1b39ece6fcc0d18aed00c0179f3": { + "balance": "300000000000000000000" + }, + "b1cf94f8091505055f010ab4bac696e0ca0f67a1": { + "balance": "1580000000000000000000" + }, + "54391b4d176d476cea164e5fb535c69700cb2535": { + "balance": "100076000000000000000" + }, + "152f2bd229ddf3cb0fdaf455c183209c0e1e39a2": { + "balance": "2000000000000000000000" + }, + "affc99d5ebb4a84fe7788d97dce274b038240438": { + "balance": "5000000000000000000000" + }, + "23df8f48ee009256ea797e1fa369beebcf6bc663": { + "balance": "2302671000000000000000" + }, + "3a72d635aadeee4382349db98a1813a4cfeb3df1": { + "balance": "200000000000000000000000" + }, + "ce26f9a5305f8381094354dbfc92664e84f902b5": { + "balance": "230200000000000000000" + }, + "d283b8edb10a25528a4404de1c65e7410dbcaa67": { + "balance": "12000000000000000000000" + }, + "a7859fc07f756ea7dcebbccd42f05817582d973f": { + "balance": "10000000000000000000000" + }, + "b28181a458a440f1c6bb1de8400281a3148f4c35": { + "balance": "376000000000000000000" + }, + "27b1694eafa165ebd7cc7bc99e74814a951419dc": { + "balance": "800000000000000000000" + }, + "66cc8ab23c00d1b82acd7d73f38c99e0d05a4fa6": { + "balance": "100000000000000000000" + }, + "926082cb7eed4b1993ad245a477267e1c33cd568": { + "balance": "374300000000000000000" + }, + "4a47fc3e177f567a1e3893e000e36bba23520ab8": { + "balance": "2000000000000000000000" + }, + "594a76f06935388dde5e234696a0668bc20d2ddc": { + "balance": "2800000000000000000000" + }, + "e91fa0badaddb9a97e88d3f4db7c55d6bb7430fe": { + "balance": "376000000000000000000" + }, + "574de1b3f38d915846ae3718564a5ada20c2f3ed": { + "balance": "4000000000000000000000" + }, + "5816c2687777b6d7d2a2432d59a41fa059e3a406": { + "balance": "133700000000000000000000" + }, + "b50955aa6e341571986608bdc891c2139f540cdf": { + "balance": "1970000000000000000000" + }, + "6d44974a31d187eda16ddd47b9c7ec5002d61fbe": { + "balance": "940000000000000000000" + }, + "80abec5aa36e5c9d098f1b942881bd5acac6963d": { + "balance": "2000000000000000000000" + }, + "294f494b3f2e143c2ffc9738cbfd9501850b874e": { + "balance": "2240000000000000000000" + }, + "bca3ffd4683fba0ad3bbc90734b611da9cfb457e": { + "balance": "200000000000000000000" + }, + "5992624c54cdec60a5ae938033af8be0c50cbb0a": { + "balance": "3621678000000000000000" + }, + "6560941328ff587cbc56c38c78238a7bb5f442f6": { + "balance": "744900000000000000000" + }, + "74b7e0228baed65957aebb4d916d333aae164f0e": { + "balance": "2000000000000000000000" + }, + "8516fcaf77c893970fcd1a958ba9a00e49044019": { + "balance": "196279000000000000000" + }, + "b992a967308c02b98af91ee760fd3b6b4824ab0e": { + "balance": "2000000000000000000000" + }, + "30bb4357cd6910c86d2238bf727cbe8156680e62": { + "balance": "100014000000000000000" + }, + "b8cc0f060aad92d4eb8b36b3b95ce9e90eb383d7": { + "balance": "150000000000000000000000" + }, + "28d4ebf41e3d3c451e943bdd7e1f175fae932a3d": { + "balance": "6000000000000000000000" + }, + "8c83d424a3cf24d51f01923dd54a18d6b6fede7b": { + "balance": "4000000000000000000000" + }, + "7efc90766a00bc52372cac97fabd8a3c831f8ecd": { + "balance": "158000000000000000000" + }, + "7c2b9603884a4f2e464eceb97d17938d828bc02c": { + "balance": "3000000000000000000000" + }, + "9d250ae4f110d71cafc7b0adb52e8d9acb6679b8": { + "balance": "9840000000000000000000" + }, + "61b3df2e9e9fd968131f1e88f0a0eb5bd765464d": { + "balance": "4000000000000000000000" + }, + "9ae13bd882f2576575921a94974cbea861ba0d35": { + "balance": "3160000000000000000000" + }, + "3d09688d93ad07f3abe68c722723cd680990435e": { + "balance": "29999948000000000000000" + }, + "5e58e255fc19870a04305ff2a04631f2ff294bb1": { + "balance": "17600000000000000000" + }, + "bcaed0acb6a76f113f7c613555a2c3b0f5bf34a5": { + "balance": "193600000000000000000" + }, + "159adce27aa10b47236429a34a5ac42cad5b6416": { + "balance": "31867951000000000000000" + }, + "e834c64318205ca7dd4a21abcb08266cb21ff02c": { + "balance": "999999000000000000000" + }, + "7b6a84718dd86e63338429ac811d7c8a860f21f1": { + "balance": "1790000000000000000000" + }, + "2118c116ab0cdf6fd11d54a4309307b477c3fc0f": { + "balance": "10000000000000000000000" + }, + "34a901a69f036bcf9f7843c0ba01b426e8c3dc2b": { + "balance": "4000000000000000000000" + }, + "c7d44fe32c7f8cd5f1a97427b6cd3afc9e45023e": { + "balance": "1580000000000000000000" + }, + "c6045b3c350b4ce9ca0c6b754fb41a69b97e9900": { + "balance": "925000000000000000000" + }, + "cf5a6f9df75579c644f794711215b30d77a0ce40": { + "balance": "2000000000000000000000" + }, + "e2904b1aefa056398b6234cb35811288d736db67": { + "balance": "40000000000000000000" + }, + "7101bd799e411cde14bdfac25b067ac890eab8e8": { + "balance": "1450054000000000000000" + }, + "cc45fb3a555bad807b388a0357c855205f7c75e8": { + "balance": "865000000000000000000" + }, + "ff0c3c7798e8733dd2668152891bab80a8be955c": { + "balance": "80220000000000000000" + }, + "3536453322c1466cb905af5c335ca8db74bff1e6": { + "balance": "447000000000000000000" + }, + "08cac8952641d8fc526ec1ab4f2df826a5e7710f": { + "balance": "300000000000000000000" + }, + "0d8aab8f74ea862cdf766805009d3f3e42d8d00b": { + "balance": "5820000000000000000000" + }, + "8908760cd39b9c1e8184e6a752ee888e3f0b7045": { + "balance": "6000000000000000000000" + }, + "8156360bbd370961ceca6b6691d75006ad204cf2": { + "balance": "40000000000000000000000" + }, + "a304588f0d850cd8d38f76e9e83c1bf63e333ede": { + "balance": "39800000000000000000" + }, + "14c63ba2dcb1dd4df33ddab11c4f0007fa96a62d": { + "balance": "15500000000000000000000" + }, + "a009bf076f1ba3fa57d2a7217218bed5565a7a7a": { + "balance": "1000000000000000000000" + }, + "1c89060f987c518fa079ec2c0a5ebfa30f5d20f7": { + "balance": "38000000000000000000000" + }, + "8895eb726226edc3f78cc6a515077b3296fdb95e": { + "balance": "3940000000000000000000" + }, + "7919e7627f9b7d54ea3b14bb4dd4649f4f39dee0": { + "balance": "1670000000000000000000" + }, + "b3c65b845aba6cd816fbaae983e0e46c82aa8622": { + "balance": "1000000000000000000000" + }, + "eff51d72adfae143edf3a42b1aec55a2ccdd0b90": { + "balance": "300000000000000000000" + }, + "05bb64a916be66f460f5e3b64332110d209e19ae": { + "balance": "4200000000000000000000" + }, + "d5b117ec116eb846418961eb7edb629cd0dd697f": { + "balance": "3000000000000000000000" + }, + "05e97b09492cd68f63b12b892ed1d11d152c0eca": { + "balance": "1015200000000000000000" + }, + "84cc7878da605fdb019fab9b4ccfc157709cdda5": { + "balance": "1336922000000000000000" + }, + "79cac6494f11ef2798748cb53285bd8e22f97cda": { + "balance": "2000000000000000000000" + }, + "bd5a8c94bd8be6470644f70c8f8a33a8a55c6341": { + "balance": "200000000000000000000" + }, + "b119e79aa9b916526581cbf521ef474ae84dcff4": { + "balance": "1470700000000000000000" + }, + "aff1045adf27a1aa329461b24de1bae9948a698b": { + "balance": "33400000000000000000" + }, + "4398628ea6632d393e929cbd928464c568aa4a0c": { + "balance": "1400000000000000000000" + }, + "99997668f7c1a4ff9e31f9977ae3224bcb887a85": { + "balance": "291200000000000000000" + }, + "bc0e8745c3a549445c2be900f52300804ab56289": { + "balance": "33104697000000000000000" + }, + "e5bab4f0afd8a9d1a381b45761aa18f3d3cce105": { + "balance": "1508010000000000000000" + }, + "be60037e90714a4b917e61f193d834906703b13a": { + "balance": "1700000000000000000000" + }, + "8ed4284c0f47449c15b8d9b3245de8beb6ce80bf": { + "balance": "800000000000000000000" + }, + "333ad1596401e05aea2d36ca47318ef4cd2cb3df": { + "balance": "2910000000000000000000" + }, + "22db559f2c3c1475a2e6ffe83a5979599196a7fa": { + "balance": "1000000000000000000000" + }, + "fdf449f108c6fb4f5a2b081eed7e45e6919e4d25": { + "balance": "2000000000000000000000" + }, + "0be1bcb90343fae5303173f461bd914a4839056c": { + "balance": "6000000000000000000000" + }, + "b981ad5e6b7793a23fc6c1e8692eb2965d18d0da": { + "balance": "9999924000000000000000" + }, + "c75d2259306aec7df022768c69899a652185dbc4": { + "balance": "4000000000000000000000" + }, + "6c2e9be6d4ab450fd12531f33f028c614674f197": { + "balance": "3580000000000000000000" + }, + "6dcc7e64fcafcbc2dc6c0e5e662cb347bffcd702": { + "balance": "20000000000000000000000" + }, + "aabdb35c1514984a039213793f3345a168e81ff1": { + "balance": "309760000000000000000" + }, + "d315deea1d8c1271f9d1311263ab47c007afb6f5": { + "balance": "69760000000000000000" + }, + "4faf90b76ecfb9631bf9022176032d8b2c207009": { + "balance": "1000032000000000000000" + }, + "3e7a966b5dc357ffb07e9fe067c45791fd8e3049": { + "balance": "59100000000000000000" + }, + "2e64a8d71111a22f4c5de1e039b336f68d398a7c": { + "balance": "2000000000000000000000" + }, + "181fbba852a7f50178b1c7f03ed9e58d54162929": { + "balance": "666000000000000000000" + }, + "4f7330096f79ed264ee0127f5d30d2f73c52b3d8": { + "balance": "499970000000000000000" + }, + "a8a8dbdd1a85d1beee2569e91ccc4d09ae7f6ea1": { + "balance": "5800000000000000000000" + }, + "1f9c3268458da301a2be5ab08257f77bb5a98aa4": { + "balance": "200000000000000000000" + }, + "fc372ff6927cb396d9cf29803500110da632bc52": { + "balance": "2000000000000000000000" + }, + "4fa554ab955c249217386a4d3263bbf72895434e": { + "balance": "19982000000000000000" + }, + "2a59e47ea5d8f0e7c028a3e8e093a49c1b50b9a3": { + "balance": "2000000000000000000000" + }, + "5e32c72191b8392c55f510d8e3326e3a60501d62": { + "balance": "44000000000000000000000" + }, + "1dfaee077212f1beaf0e6f2f1840537ae154ad86": { + "balance": "1000000000000000000000" + }, + "7eaba035e2af3793fd74674b102540cf190addb9": { + "balance": "1273000000000000000000" + }, + "d62edb96fce2969aaf6c545e967cf1c0bc805205": { + "balance": "85705000000000000000" + }, + "220dc68df019b6b0ccbffb784b5a5ab4b15d4060": { + "balance": "3940000000000000000000" + }, + "45bb829652d8bfb58b8527f0ecb621c29e212ec3": { + "balance": "2000000000000000000000" + }, + "79b120eb8806732321288f675a27a9225f1cd2eb": { + "balance": "2465000000000000000000" + }, + "740af1eefd3365d78ba7b12cb1a673e06a077246": { + "balance": "19700000000000000000000" + }, + "0f042c9c2fb18766f836bb59f735f27dc329fe3c": { + "balance": "10000000000000000000000" + }, + "6dda5f788a6c688ddf921fa3852eb6d6c6c62966": { + "balance": "40000000000000000000" + }, + "96ad579bbfa8db8ebec9d286a72e4661eed8e356": { + "balance": "1070750000000000000000" + }, + "0c2073ba44d3ddbdb639c04e191039a71716237f": { + "balance": "1430000000000000000000" + }, + "1a3520453582c718a21c42375bc50773255253e1": { + "balance": "790000000000000000000" + }, + "efcaae9ff64d2cd95b5249dcffe7faa0a0c0e44d": { + "balance": "401100000000000000000" + }, + "0a3de155d5ecd8e81c1ff9bbf0378301f8d4c623": { + "balance": "4000000000000000000000" + }, + "80f07ac09e7b2c3c0a3d1e9413a544c73a41becb": { + "balance": "20000000000000000000" + }, + "c3631c7698b6c5111989bf452727b3f9395a6dea": { + "balance": "10683500000000000000000" + }, + "4cc22c9bc9ad05d875a397dbe847ed221c920c67": { + "balance": "2000000000000000000000" + }, + "1a987e3f83de75a42f1bde7c997c19217b4a5f24": { + "balance": "2000000000000000000000" + }, + "5b2b64e9c058e382a8b299224eecaa16e09c8d92": { + "balance": "161000000000000000000" + }, + "86caafacf32aa0317c032ac36babed974791dc03": { + "balance": "40000000000000000000000" + }, + "1cd1f0a314cbb200de0a0cb1ef97e920709d97c2": { + "balance": "2000000000000000000000" + }, + "7d980f4b566bb045517e4c14c87750de9346744b": { + "balance": "1337000000000000000000" + }, + "8b5f29cc2faa262cdef30ef554f50eb488146eac": { + "balance": "5818250000000000000000" + }, + "5153a0c3c8912881bf1c3501bf64b45649e48222": { + "balance": "4000000000000000000000" + }, + "d21a7341eb84fd151054e5e387bb25d36e499c09": { + "balance": "14000000000000000000000" + }, + "9560e8ac6718a6a1cdcff189d603c9063e413da6": { + "balance": "4000000000000000000000" + }, + "e49ba0cd96816c4607773cf8a5970bb5bc16a1e6": { + "balance": "1670000000000000000000" + }, + "b8ac117d9f0dba80901445823c4c9d4fa3fedc6e": { + "balance": "15759015000000000000000" + }, + "af67fd3e127fd9dc36eb3fcd6a80c7be4f7532b2": { + "balance": "1670000000000000000000" + }, + "b43c27f7a0a122084b98f483922541c8836cee2c": { + "balance": "715000000000000000000" + }, + "4d9279962029a8bd45639737e98b511eff074c21": { + "balance": "1337000000000000000000" + }, + "c667441e7f29799aba616451d53b3f489f9e0f48": { + "balance": "13920000000000000000000" + }, + "275875ff4fbb0cf3a430213127487f7608d04cba": { + "balance": "500080000000000000000" + }, + "9a953b5bcc709379fcb559d7b916afdaa50cadcc": { + "balance": "100000000000000000000" + }, + "7ea791ebab0445a00efdfc4e4a8e9a7e7565136d": { + "balance": "18200000000000000000" + }, + "6ffe5cf82cc9ea5e36cad7c2974ce7249f3749e6": { + "balance": "1940000000000000000000" + }, + "f1b4ecc63525f7432c3d834ffe2b970fbeb87212": { + "balance": "3000064000000000000000" + }, + "6b72a8f061cfe6996ad447d3c72c28c0c08ab3a7": { + "balance": "4271316000000000000000" + }, + "bba3c68004248e489573abb2743677066b24c8a7": { + "balance": "2000000000000000000000" + }, + "b7c0d0cc0b4d342d4062bac624ccc3c70cc6da3f": { + "balance": "4000000000000000000000" + }, + "fe98c664c3e447a95e69bd582171b7176ea2a685": { + "balance": "4000000000000000000000" + }, + "ce71086d4c602554b82dcbfce88d20634d53cc4d": { + "balance": "43250000000000000000000" + }, + "1c601993789207f965bb865cbb4cd657cce76fc0": { + "balance": "98294000000000000000" + }, + "476b5599089a3fb6f29c6c72e49b2e4740ea808d": { + "balance": "2800000000000000000000" + }, + "3439998b247cb4bf8bc80a6d2b3527f1dfe9a6d2": { + "balance": "140000000000000000000" + }, + "c4f7d2e2e22084c44f70feaab6c32105f3da376f": { + "balance": "1970000000000000000000" + }, + "c1eba5684aa1b24cba63150263b7a9131aeec28d": { + "balance": "20000000000000000000" + }, + "94ad4bad824bd0eb9ea49c58cebcc0ff5e08346b": { + "balance": "1940000000000000000000" + }, + "ded877378407b94e781c4ef4af7cfc5bc220b516": { + "balance": "372500000000000000000" + }, + "699c9ee47195511f35f862ca4c22fd35ae8ffbf4": { + "balance": "80000000000000000000" + }, + "e3a89a1927cc4e2d43fbcda1e414d324a7d9e057": { + "balance": "205500000000000000000" + }, + "4d93696fa24859f5d2939aebfa54b4b51ae1dccc": { + "balance": "19100000000000000000" + }, + "0af65f14784e55a6f95667fd73252a1c94072d2a": { + "balance": "192987000000000000000" + }, + "5b70c49cc98b3df3fbe2b1597f5c1b6347a388b7": { + "balance": "970000000000000000000" + }, + "426f78f70db259ac8534145b2934f4ef1098b5d8": { + "balance": "360000000000000000000" + }, + "58b8ae8f63ef35ed0762f0b6233d4ac14e64b64d": { + "balance": "2000000000000000000000" + }, + "8eae29435598ba8f1c93428cdb3e2b4d31078e00": { + "balance": "2000000000000000000000" + }, + "17fd9b551a98cb61c2e07fbf41d3e8c9a530cba5": { + "balance": "26989000000000000000" + }, + "ab3e78294ba886a0cfd5d3487fb3a3078d338d6e": { + "balance": "1970000000000000000000" + }, + "bdf6e68c0cd7584080e847d72cbb23aad46aeb1d": { + "balance": "1970000000000000000000" + }, + "f989346772995ec1906faffeba2a7fe7de9c6bab": { + "balance": "6685000000000000000000" + }, + "dc5f5ad663a6f263327d64cac9cb133d2c960597": { + "balance": "2000000000000000000000" + }, + "68fe1357218d095849cd579842c4aa02ff888d93": { + "balance": "2000000000000000000000" + }, + "e09c68e61998d9c81b14e4ee802ba7adf6d74cdb": { + "balance": "4000000000000000000000" + }, + "890fe11f3c24db8732d6c2e772e2297c7e65f139": { + "balance": "62980000000000000000000" + }, + "a76929890a7b47fb859196016c6fdd8289ceb755": { + "balance": "5000000000000000000000" + }, + "2dc79d6e7f55bce2e2d0c02ad07ceca8bb529354": { + "balance": "1580000000000000000000" + }, + "19687daa39c368139b6e7be60dc1753a9f0cbea3": { + "balance": "8000000000000000000000" + }, + "c69be440134d6280980144a9f64d84748a37f349": { + "balance": "715000000000000000000" + }, + "3d8d0723721e73a6c0d860aa0557abd14c1ee362": { + "balance": "5000000000000000000000" + }, + "2b241f037337eb4acc61849bd272ac133f7cdf4b": { + "balance": "378000000000000000000000" + }, + "24b95ebef79500baa0eda72e77f877415df75c33": { + "balance": "910000000000000000000" + }, + "106ed5c719b5261477890425ae7551dc59bd255c": { + "balance": "11979600000000000000000" + }, + "5b2e2f1618552eab0db98add55637c2951f1fb19": { + "balance": "12000000000000000000000" + }, + "403145cb4ae7489fcc90cd985c6dc782b3cc4e44": { + "balance": "5999800000000000000000" + }, + "e8be24f289443ee473bc76822f55098d89b91cc5": { + "balance": "2000000000000000000000" + }, + "f6bc37b1d2a3788d589b6de212dc1713b2f6e78e": { + "balance": "5000000000000000000000" + }, + "67fc527dce1785f0fb8bc7e518b1c669f7ecdfb5": { + "balance": "240000000000000000000" + }, + "6580b1bc94390f04b397bd73e95d96ef11eaf3a8": { + "balance": "20000000000000000000" + }, + "98bf4af3810b842387db70c14d46099626003d10": { + "balance": "4000000000000000000000" + }, + "17993d312aa1106957868f6a55a5e8f12f77c843": { + "balance": "450065000000000000000" + }, + "0729b4b47c09eb16158464c8aa7fd9690b438839": { + "balance": "1999800000000000000000" + }, + "ae70e69d2c4a0af818807b1a2705f79fd0b5dbc4": { + "balance": "985000000000000000000" + }, + "38b50146e71916a5448de12a4d742135dcf39833": { + "balance": "32200000000000000000000" + }, + "38439aaa24e3636f3a18e020ea1da7e145160d86": { + "balance": "2600000000000000000000" + }, + "54b4429b182f0377be7e626939c5db6440f75d7a": { + "balance": "1970000000000000000000" + }, + "7179726f5c71ae1b6d16a68428174e6b34b23646": { + "balance": "7353500000000000000000" + }, + "c2ee91d3ef58c9d1a589844ea1ae3125d6c5ba69": { + "balance": "970000000000000000000" + }, + "912304118b80473d9e9fe3ee458fbe610ffda2bb": { + "balance": "200000000000000000000" + }, + "3308b03466c27a17dfe1aafceb81e16d2934566f": { + "balance": "17000000000000000000000" + }, + "10346414bec6d3dcc44e50e54d54c2b8c3734e3e": { + "balance": "4000000000000000000000" + }, + "4fee50c5f988206b09a573469fb1d0b42ebb6dce": { + "balance": "2009400000000000000000" + }, + "9ece1400800936c7c6485fcdd3626017d09afbf6": { + "balance": "310000000000000000000" + }, + "ddf3ad76353810be6a89d731b787f6f17188612b": { + "balance": "20000000000000000000000" + }, + "72402300e81d146c2e644e2bbda1da163ca3fb56": { + "balance": "7000000000000000000000" + }, + "bb4b4a4b548070ff41432c9e08a0ca6fa7bc9f76": { + "balance": "850000000000000000000" + }, + "c3dd58903886303b928625257ae1a013d71ae216": { + "balance": "2000000000000000000000" + }, + "ca6c818befd251361e02744068be99d8aa60b84a": { + "balance": "6000000000000000000000" + }, + "b8d2ddc66f308c0158ae3ccb7b869f7d199d7b32": { + "balance": "844800000000000000000" + }, + "8e486a0442d171c8605be348fee57eb5085eff0d": { + "balance": "4000000000000000000000" + }, + "a807104f2703d679f8deafc442befe849e42950b": { + "balance": "2000000000000000000000" + }, + "bb61a04bffd57c10470d45c39103f64650347616": { + "balance": "1000000000000000000000" + }, + "d1c45954a62b911ad701ff2e90131e8ceb89c95c": { + "balance": "1394000000000000000000" + }, + "5e65458be964ae449f71773704979766f8898761": { + "balance": "528600000000000000000" + }, + "f9b37825f03073d31e249378c30c795c33f83af2": { + "balance": "200152000000000000000" + }, + "e309974ce39d60aadf2e69673251bf0e04760a10": { + "balance": "254030000000000000000" + }, + "d541ac187ad7e090522de6da3213e9a7f4439673": { + "balance": "2000000000000000000000" + }, + "f33efc6397aa65fb53a8f07a0f893aae30e8bcee": { + "balance": "2304850000000000000000" + }, + "d2f1998e1cb1580cec4f6c047dcd3dcec54cf73c": { + "balance": "200000000000000000000" + }, + "0ed76c2c3b5d50ff8fb50b3eeacd681590be1c2d": { + "balance": "100000000000000000000" + }, + "637d67d87f586f0a5a479e20ee13ea310a10b647": { + "balance": "48300000000000000000000" + }, + "1a5ee533acbfb3a2d76d5b685277b796c56a052b": { + "balance": "2000000000000000000000" + }, + "323fca5ed77f699f9d9930f5ceeff8e56f59f03c": { + "balance": "1337000000000000000000" + }, + "a5fe2ce97f0e8c3856be0de5f4dcb2ce5d389a16": { + "balance": "22892000000000000000" + }, + "93258255b37c7f58f4b10673a932dd3afd90f4f2": { + "balance": "1000000000000000000000" + }, + "950fe9c6cad50c18f11a9ed9c45740a6180612d0": { + "balance": "8000000000000000000000" + }, + "ee31167f9cc93b3c6465609d79db0cde90e8484c": { + "balance": "2000000000000000000000" + }, + "6ebb5e6957aa821ef659b6018a393a504cae4450": { + "balance": "2000000000000000000000" + }, + "be305a796e33bbf7f9aeae6512959066efda1010": { + "balance": "10880000000000000000000" + }, + "537f9d4d31ef70839d84b0d9cdb72b9afedbdf35": { + "balance": "70000000000000000000000" + }, + "fe9e1197d7974a7648dcc7a03112a88edbc9045d": { + "balance": "4925000000000000000000" + }, + "99f77f998b20e0bcdcd9fc838641526cf25918ef": { + "balance": "1790000000000000000000" + }, + "76ffc157ad6bf8d56d9a1a7fddbc0fea010aabf4": { + "balance": "1000000000000000000000" + }, + "defe9141f4704599159d7b223de42bffd80496b3": { + "balance": "100000000000000000000" + }, + "7b1bf53a9cbe83a7dea434579fe72aac8d2a0cd0": { + "balance": "199800000000000000000" + }, + "23ccc3c6acd85c2e460c4ffdd82bc75dc849ea14": { + "balance": "4000000000000000000000" + }, + "9f86a066edb61fcb5856de93b75c8c791864b97b": { + "balance": "2000000000000000000000" + }, + "871b8a8b51dea1989a5921f13ec1a955a515ad47": { + "balance": "8000000000000000000000" + }, + "4efcd9c79fb4334ca6247b0a33bd9cc33208e272": { + "balance": "1337000000000000000000" + }, + "35ac1d3ed7464fa3db14e7729213ceaa378c095e": { + "balance": "1520000000000000000000" + }, + "c69d663c8d60908391c8d236191533fdf7775613": { + "balance": "485000000000000000000" + }, + "c2ed5ffdd1add855a2692fe062b5d618742360d4": { + "balance": "1200000000000000000000" + }, + "454f0141d721d33cbdc41018bd01119aa4784818": { + "balance": "6000000000000000000000" + }, + "6c8687e3417710bb8a93559021a1469e6a86bc77": { + "balance": "11126675000000000000000" + }, + "ec5b198a00cfb55a97b5d53644cffa8a04d2ab45": { + "balance": "2000000000000000000000" + }, + "cd59f3dde77e09940befb6ee58031965cae7a336": { + "balance": "10000000000000000000000" + }, + "8eebec1a62c08b05a7d1d59180af9ff0d18e3f36": { + "balance": "500000000000000000000" + }, + "92a971a739799f8cb48ea8475d72b2d2474172e6": { + "balance": "3940000000000000000000" + }, + "bed4649df646e2819229032d8868556fe1e053d3": { + "balance": "18200000000000000000" + }, + "c50fe415a641b0856c4e75bf960515441afa358d": { + "balance": "2000000000000000000000" + }, + "91f516146cda20281719978060c6be4149067c88": { + "balance": "2000000000000000000000" + }, + "54a1370116fe22099e015d07cd2669dd291cc9d1": { + "balance": "20000000000000000000" + }, + "80c04efd310f440483c73f744b5b9e64599ce3ec": { + "balance": "1200000000000000000000" + }, + "a8914c95b560ec13f140577338c32bcbb77d3a7a": { + "balance": "180000000000000000000" + }, + "e3c812737ac606baf7522ad817428a36050e7a34": { + "balance": "1940000000000000000000" + }, + "6d1456fff0104ee844a3314737843338d24cd66c": { + "balance": "141840000000000000000" + }, + "0e6ece99111cad1961c748ed3df51edd69d2a3b1": { + "balance": "100000000000000000000000" + }, + "019d709579ff4bc09fdcdde431dc1447d2c260bc": { + "balance": "20000000000000000000" + }, + "ebff84bbef423071e604c361bba677f5593def4e": { + "balance": "10000000000000000000000" + }, + "e10c540088113fa6ec00b4b2c8824f8796e96ec4": { + "balance": "236400000000000000000000" + }, + "e03220c697bcd28f26ef0b74404a8beb06b2ba7b": { + "balance": "8000000000000000000000" + }, + "e69a6cdb3a8a7db8e1f30c8b84cd73bae02bc0f8": { + "balance": "16915503000000000000000" + }, + "e5fb31a5caee6a96de393bdbf89fbe65fe125bb3": { + "balance": "1000000000000000000000" + }, + "030fb3401f72bd3418b7d1da75bf8c519dd707dc": { + "balance": "3000000000000000000000" + }, + "1c751e7f24df9d94a637a5dedeffc58277b5db19": { + "balance": "3220000000000000000000" + }, + "bded7e07d0711e684de65ac8b2ab57c55c1a8645": { + "balance": "591000000000000000000" + }, + "dd7ff441ba6ffe3671f3c0dabbff1823a5043370": { + "balance": "2000000000000000000000" + }, + "b55474ba58f0f2f40e6cbabed4ea176e011fcad6": { + "balance": "1970000000000000000000" + }, + "b92427ad7578b4bfe20a9f63a7c5506d5ca12dc8": { + "balance": "2000000000000000000000" + }, + "91a8baaed012ea2e63803b593d0d0c2aab4c5b0a": { + "balance": "1500000000000000000000" + }, + "a97e072144499fe5ebbd354acc7e7efb58985d08": { + "balance": "2674000000000000000000" + }, + "75c2ffa1bef54919d2097f7a142d2e14f9b04a58": { + "balance": "2673866000000000000000" + }, + "53faf165be031ec18330d9fce5bd1281a1af08db": { + "balance": "140000000000000000000" + }, + "055ab658c6f0ed4f875ed6742e4bc7292d1abbf0": { + "balance": "83500000000000000000" + }, + "6f18ec767e320508195f1374500e3f2e125689ff": { + "balance": "1000000000000000000000" + }, + "90fc537b210658660a83baa9ac4a8402f65746a8": { + "balance": "1880000000000000000000" + }, + "34664d220fa7f37958024a3332d684bcc6d4c8bd": { + "balance": "10000000000000000000000" + }, + "15acb61568ec4af7ea2819386181b116a6c5ee70": { + "balance": "31000000000000000000000" + }, + "69d98f38a3ba3dbc01fa5c2c1427d862832f2f70": { + "balance": "100000000000000000000000" + }, + "ece1152682b7598fe2d1e21ec15533885435ac85": { + "balance": "4000000000000000000000" + }, + "f618d9b104411480a863e623fc55232d1a4f48aa": { + "balance": "265793000000000000000" + }, + "f9debaecb5f339beea4894e5204bfa340d067f25": { + "balance": "1665000000000000000000" + }, + "5e731b55ced452bb3f3fe871ddc3ed7ee6510a8f": { + "balance": "3000000000000000000000" + }, + "67df242d240dd4b8071d72f8fcf35bb3809d71e8": { + "balance": "4000000000000000000000" + }, + "c4cf930e5d116ab8d13b9f9a7ec4ab5003a6abde": { + "balance": "320000000000000000000" + }, + "01a25a5f5af0169b30864c3be4d7563ccd44f09e": { + "balance": "1430000000000000000000" + }, + "7f6efb6f4318876d2ee624e27595f44446f68e93": { + "balance": "1550000000000000000000" + }, + "82249fe70f61c6b16f19a324840fdc020231bb02": { + "balance": "9504014000000000000000" + }, + "205237c4be146fba99478f3a7dad17b09138da95": { + "balance": "2000000000000000000000" + }, + "fd1fb5a89a89a721b8797068fbc47f3e9d52e149": { + "balance": "236400000000000000000" + }, + "e47fbaed99fc209962604ebd20e240f74f4591f1": { + "balance": "2000000000000000000000" + }, + "a24c3ab62181e9a15b78c4621e4c7c588127be26": { + "balance": "162410000000000000000" + }, + "b6cd7432d5161be79768ad45de3e447a07982063": { + "balance": "4000000000000000000000" + }, + "32a70691255c9fc9791a4f75c8b81f388e0a2503": { + "balance": "985000000000000000000" + }, + "562f16d79abfcec3943e34b20f05f97bdfcda605": { + "balance": "4000000000000000000000" + }, + "dbc66965e426ff1ac87ad6eb78c1d95271158f9f": { + "balance": "18200000000000000000" + }, + "7e87863ec43a481df04d017762edcb5caa629b5a": { + "balance": "39400000000000000000" + }, + "587d6849b168f6c3332b7abae7eb6c42c37f48bf": { + "balance": "880000000000000000000" + }, + "721158be5762b119cc9b2035e88ee4ee78f29b82": { + "balance": "10000000000000000000000" + }, + "84b91e2e2902d05e2b591b41083bd7beb2d52c74": { + "balance": "9848621000000000000000" + }, + "632cecb10cfcf38ec986b43b8770adece9200221": { + "balance": "20000000000000000000" + }, + "c34e3ba1322ed0571183a24f94204ee49c186641": { + "balance": "58200000000000000000" + }, + "ae78bb849139a6ba38ae92a09a69601cc4cb62d1": { + "balance": "500000000000000000000" + }, + "5ce0b6862cce9162e87e0849e387cb5df4f9118c": { + "balance": "1670000000000000000000" + }, + "f52c0a7877345fe0c233bb0f04fd6ab18b6f14ba": { + "balance": "400440000000000000000000" + }, + "e016dc138e25815b90be3fe9eee8ffb2e105624f": { + "balance": "500000000000000000000" + }, + "5789d01db12c816ac268e9af19dc0dd6d99f15df": { + "balance": "200000000000000000000" + }, + "d8b77db9b81bbe90427b62f702b201ffc29ff618": { + "balance": "930200000000000000000" + }, + "5dff811dad819ece3ba602c383fb5dc64c0a3a48": { + "balance": "186000000000000000000" + }, + "af3087e62e04bf900d5a54dc3e946274da92423b": { + "balance": "20000000000000000000" + }, + "8c1023fde1574db8bb54f1739670157ca47da652": { + "balance": "6969382000000000000000" + }, + "bb3b010b18e6e2be1135871026b7ba15ea0fde24": { + "balance": "10044000000000000000000" + }, + "cabdaf354f4720a466a764a528d60e3a482a393c": { + "balance": "1000000000000000000000" + }, + "94bbc67d13f89ebca594be94bc5170920c30d9f3": { + "balance": "80200000000000000000" + }, + "3275496fd4dd8931fd69fb0a0b04c4d1ff879ef5": { + "balance": "446000000000000000000" + }, + "281250a29121270a4ee5d78d24feafe82c70ba3a": { + "balance": "1000000000000000000000" + }, + "590ccb5911cf78f6f622f535c474375f4a12cfcf": { + "balance": "20000000000000000000000" + }, + "542e8096bafb88162606002e8c8a3ed19814aeac": { + "balance": "2000000000000000000000" + }, + "a65426cff378ed23253513b19f496de45fa7e18f": { + "balance": "7200000000000000000000" + }, + "4aa693b122f314482a47b11cc77c68a497876162": { + "balance": "1970000000000000000000" + }, + "d9b783d31d32adc50fa3eacaa15d92b568eaeb47": { + "balance": "34010000000000000000000" + }, + "068e655766b944fb263619658740b850c94afa31": { + "balance": "35200000000000000000" + }, + "9e23c5e4b782b00a5fadf1aead87dacf5b0367a1": { + "balance": "20000000000000000000" + }, + "bf17f397f8f46f1bae45d187148c06eeb959fa4d": { + "balance": "1001440000000000000000" + }, + "8578e10212ca14ff0732a8241e37467db85632a9": { + "balance": "6000000000000000000000" + }, + "2cb5495a505336c2465410d1cae095b8e1ba5cdd": { + "balance": "20000000000000000000000" + }, + "695b0f5242753701b264a67071a2dc880836b8db": { + "balance": "16400000000000000000" + }, + "f2edde37f9a8c39ddea24d79f4015757d06bf786": { + "balance": "100000000000000000000000" + }, + "480f31b989311e4124c6a7465f5a44094d36f9d0": { + "balance": "1025000000000000000000" + }, + "cf157612764e0fd696c8cb5fba85df4c0ddc3cb0": { + "balance": "30000000000000000000000" + }, + "27521deb3b6ef1416ea4c781a2e5d7b36ee81c61": { + "balance": "2000000000000000000000" + }, + "6efd90b535e00bbd889fda7e9c3184f879a151db": { + "balance": "10100000000000000000000" + }, + "b635a4bc71fb28fdd5d2c322983a56c284426e69": { + "balance": "170000000000000000000" + }, + "a17c9e4323069518189d5207a0728dcb92306a3f": { + "balance": "1000000000000000000000" + }, + "6af940f63ec9b8d876272aca96fef65cdacecdea": { + "balance": "3000000000000000000000" + }, + "469358709332c82b887e20bcddd0220f8edba7d0": { + "balance": "17300000000000000000000" + }, + "a257ad594bd88328a7d90fc0a907df95eecae316": { + "balance": "520510000000000000000" + }, + "6f051666cb4f7bd2b1907221b829b555d7a3db74": { + "balance": "1760000000000000000000" + }, + "46bfc5b207eb2013e2e60f775fecd71810c5990c": { + "balance": "1550000000000000000000" + }, + "62b9081e7710345e38e02e16449ace1b85bcfc4e": { + "balance": "910000000000000000000" + }, + "bc73f7b1ca3b773b34249ada2e2c8a9274cc17c2": { + "balance": "2000000000000000000000" + }, + "1adaf4abfa867db17f99af6abebf707a3cf55df6": { + "balance": "6000000000000000000000" + }, + "8d629c20608135491b5013f1002586a0383130e5": { + "balance": "1370000000000000000000" + }, + "38e46de4453c38e941e7930f43304f94bb7b2be8": { + "balance": "2005500000000000000000" + }, + "3485f621256433b98a4200dad857efe55937ec98": { + "balance": "2000000000000000000000" + }, + "775c10c93e0db7205b2643458233c64fc33fd75b": { + "balance": "2000000000000000000000" + }, + "7c4401ae98f12ef6de39ae24cf9fc51f80eba16b": { + "balance": "200000000000000000000" + }, + "17b807afa3ddd647e723542e7b52fee39527f306": { + "balance": "400010000000000000000" + }, + "0ab366e6e7d5abbce6b44a438d69a1cabb90d133": { + "balance": "320000000000000000000" + }, + "194ffe78bbf5d20dd18a1f01da552e00b7b11db1": { + "balance": "7000000000000000000000" + }, + "c45d47ab0c9aa98a5bd62d16223ea2471b121ca4": { + "balance": "593640000000000000000" + }, + "2487c3c4be86a2723d917c06b458550170c3edba": { + "balance": "1000000000000000000000" + }, + "ec4d08aa2e47496dca87225de33f2b40a8a5b36f": { + "balance": "158000000000000000000" + }, + "aaa8defe11e3613f11067fb983625a08995a8dfc": { + "balance": "200000000000000000000" + }, + "50bb67c8b8d8bd0f63c4760904f2d333f400aace": { + "balance": "2000000000000000000000" + }, + "1227e10a4dbf9caca31b1780239f557615fc35c1": { + "balance": "200000000000000000000" + }, + "44a8989e32308121f72466978db395d1f76c3a4b": { + "balance": "7236900000000000000000" + }, + "59569a21d28fba4bda37753405a081f2063da150": { + "balance": "4000000000000000000000" + }, + "c3756bcdcc7eec74ed896adfc335275930266e08": { + "balance": "6000000000000000000000" + }, + "ce3a61f0461b00935e85fa1ead82c45e5a64d488": { + "balance": "500000000000000000000" + }, + "012f396a2b5eb83559bac515e5210df2c8c362ba": { + "balance": "200000000000000000000" + }, + "93bc7d9a4abd44c8bbb8fe8ba804c61ad8d6576c": { + "balance": "3999922000000000000000" + }, + "e20bb9f3966419e14bbbaaaa6789e92496cfa479": { + "balance": "3465116000000000000000" + }, + "9eef442d291a447d74c5d253c49ef324eac1d8f0": { + "balance": "3420000000000000000000" + }, + "db6c2a73dac7424ab0d031b66761122566c01043": { + "balance": "3000000000000000000000" + }, + "704d243c2978e46c2c86adbecd246e3b295ff633": { + "balance": "2012000000000000000000" + }, + "d2ff672016f63b2f85398f4a6fedbb60a50d3cce": { + "balance": "342500000000000000000" + }, + "d2051cb3cb6704f0548cc890ab0a19db3415b42a": { + "balance": "334000000000000000000" + }, + "1111e5dbf45e6f906d62866f1708101788ddd571": { + "balance": "1300200000000000000000" + }, + "6a686bf220b593deb9b7324615fb9144ded3f39d": { + "balance": "1460000000000000000000" + }, + "911feea61fe0ed50c5b9e5a0d66071399d28bdc6": { + "balance": "60000000000000000000" + }, + "3881defae1c07b3ce04c78abe26b0cdc8d73f010": { + "balance": "200000000000000000000" + }, + "ea94f32808a2ef8a9bf0861d1d2404f7b7be258a": { + "balance": "20000000000000000000" + }, + "2eef6b1417d7b10ecfc19b123a8a89e73e526c58": { + "balance": "600000000000000000000" + }, + "dd8af9e7765223f4446f44d3d509819a3d3db411": { + "balance": "10000000000000000000000" + }, + "2efc4c647dac6acac35577ad221758fef6616faa": { + "balance": "8000000000000000000000" + }, + "1547b9bf7ad66274f3413827231ba405ee8c88c1": { + "balance": "17300000000000000000000" + }, + "250a40cef3202397f240469548beb5626af4f23c": { + "balance": "92500000000000000000" + }, + "c175be3194e669422d15fee81eb9f2c56c67d9c9": { + "balance": "200000000000000000000" + }, + "c9e02608066828848aeb28c73672a12925181f4d": { + "balance": "500038000000000000000" + }, + "8229ceb9f0d70839498d44e6abed93c5ca059f5d": { + "balance": "123300000000000000000000" + }, + "39f198331e4b21c1b760a3155f4ab2fe00a74619": { + "balance": "2000000000000000000000" + }, + "3ffcb870d4023d255d5167d8a507cefc366b68ba": { + "balance": "649400000000000000000" + }, + "00dae27b350bae20c5652124af5d8b5cba001ec1": { + "balance": "40000000000000000000" + }, + "fc5500825105cf712a318a5e9c3bfc69c89d0c12": { + "balance": "4000000000000000000000" + }, + "1ed8bb3f06778b039e9961d81cb71a73e6787c8e": { + "balance": "2000000000000000000000" + }, + "530ffac3bc3412e2ec0ea47b7981c770f5bb2f35": { + "balance": "133700000000000000000" + }, + "5f344b01c7191a32d0762ac188f0ec2dd460911d": { + "balance": "1000000000000000000000" + }, + "5cfa9877f719c79d9e494a08d1e41cf103fc87c9": { + "balance": "200000000000000000000" + }, + "f6eaac7032d492ef17fd6095afc11d634f56b382": { + "balance": "500038000000000000000" + }, + "962c0dec8a3d464bf39b1215eafd26480ae490cd": { + "balance": "2001680000000000000000" + }, + "262a8bfd7d9dc5dd3ad78161b6bb560824373655": { + "balance": "1169820000000000000000" + }, + "9b4824ff9fb2abda554dee4fb8cf549165570631": { + "balance": "20000000000000000000" + }, + "bb3b9005f46fd2ca3b30162599928c77d9f6b601": { + "balance": "8000014000000000000000" + }, + "f7dc251196fbcbb77c947d7c1946b0ff65021cea": { + "balance": "1000000000000000000000" + }, + "af1148ef6c8e103d7530efc91679c9ac27000993": { + "balance": "200000000000000000000" + }, + "0bb2650ea01aca755bc0c017b64b1ab5a66d82e3": { + "balance": "1337000000000000000000" + }, + "0cda12bf72d461bbc479eb92e6491d057e6b5ad1": { + "balance": "10000000000000000000000" + }, + "4e5b77f9066159e615933f2dda7477fa4e47d648": { + "balance": "200000000000000000000" + }, + "391161b0e43c302066e8a68d2ce7e199ecdb1d57": { + "balance": "4000000000000000000000" + }, + "c7e330cd0c890ac99fe771fcc7e7b009b7413d8a": { + "balance": "4000000000000000000000" + }, + "d4b38a5fdb63e01714e9801db47bc990bd509183": { + "balance": "5999000000000000000000" + }, + "bc0f98598f88056a26339620923b8f1eb074a9fd": { + "balance": "200000000000000000000" + }, + "dbc59ed88973dead310884223af49763c05030f1": { + "balance": "20000000000000000000" + }, + "0f85e42b1df321a4b3e835b50c00b06173968436": { + "balance": "985000000000000000000" + }, + "d7788ef28658aa06cc53e1f3f0de58e5c371be78": { + "balance": "6685000000000000000000" + }, + "ecd276af64c79d1bd9a92b86b5e88d9a95eb88f8": { + "balance": "20000000000000000000" + }, + "81c9e1aee2d3365d53bcfdcd96c7c538b0fd7eec": { + "balance": "1820000000000000000000" + }, + "5d39ef9ea6bdfff15d11fe91f561a6f9e31f5da5": { + "balance": "2000000000000000000000" + }, + "99878f9d6e0a7ed9aec78297b73879a80195afe0": { + "balance": "3980000000000000000000" + }, + "7294c918b1aefb4d25927ef9d799e71f93a28e85": { + "balance": "197000000000000000000" + }, + "a33f70da7275ef057104dfa7db64f472e9f5d553": { + "balance": "80220000000000000000" + }, + "255bdd6474cc8262f26a22c38f45940e1ceea69b": { + "balance": "4000000000000000000000" + }, + "52f8b509fee1a874ab6f9d87367fbeaf15ac137f": { + "balance": "1000000000000000000000" + }, + "e2728a3e8c2aaac983d05dc6877374a8f446eee9": { + "balance": "197600000000000000000" + }, + "ed0206cb23315128f8caff26f6a30b985467d022": { + "balance": "40000000000000000000000" + }, + "87cf36ad03c9eae9053abb5242de9117bb0f2a0b": { + "balance": "500000000000000000000" + }, + "a929c8bd71db0c308dac06080a1747f21b1465aa": { + "balance": "500000000000000000000" + }, + "9da6e075989c7419094cc9f6d2e49393bb199688": { + "balance": "11100000000000000000000" + }, + "763eece0b08ac89e32bfa4bece769514d8cb5b85": { + "balance": "4000000000000000000000" + }, + "5df3277ca85936c7a0d2c0795605ad25095e7159": { + "balance": "2000000000000000000000" + }, + "7163758cbb6c4c525e0414a40a049dcccce919bb": { + "balance": "200000000000000000000" + }, + "14cdddbc8b09e6675a9e9e05091cb92238c39e1e": { + "balance": "5100000000000000000000" + }, + "b3b7f493b44a2c8d80ec78b1cdc75a652b73b06c": { + "balance": "2000000000000000000000" + }, + "c69b855539ce1b04714728eec25a37f367951de7": { + "balance": "2000000000000000000000" + }, + "052eab1f61b6d45517283f41d1441824878749d0": { + "balance": "4000000000000000000000" + }, + "515651d6db4faf9ecd103a921bbbbe6ae970fdd4": { + "balance": "20000000000000000000000" + }, + "c7aff91929797489555a2ff1d14d5c695a108355": { + "balance": "1000000000000000000000" + }, + "d7ca7fdcfebe4588eff5421d1522b61328df7bf3": { + "balance": "4001070000000000000000" + }, + "eefba12dfc996742db790464ca7d273be6e81b3e": { + "balance": "1000000000000000000000" + }, + "ebaa216de9cc5a43031707d36fe6d5bedc05bdf0": { + "balance": "1969606000000000000000" + }, + "559194304f14b1b93afe444f0624e053c23a0009": { + "balance": "400000000000000000000" + }, + "4ecc19948dd9cd87b4c7201ab48e758f28e7cc76": { + "balance": "500200000000000000000" + }, + "f224eb900b37b4490eee6a0b6420d85c947d8733": { + "balance": "970000000000000000000" + }, + "97810bafc37e84306332aacb35e92ad911d23d24": { + "balance": "1000000000000000000000" + }, + "bd67d2e2f82da8861341bc96a2c0791fddf39e40": { + "balance": "200014000000000000000" + }, + "1b6495891240e64e594493c2662171db5e30ce13": { + "balance": "172400000000000000000" + }, + "00bdd4013aa31c04616c2bc9785f2788f915679b": { + "balance": "13400000000000000000" + }, + "c6ae287ddbe1149ba16ddcca4fe06aa2eaa988a9": { + "balance": "400000000000000000000" + }, + "b7c9f12b038e73436d17e1c12ffe1aeccdb3f58c": { + "balance": "540000000000000000000" + }, + "c1b500011cfba95d7cd636e95e6cbf6167464b25": { + "balance": "200000000000000000000" + }, + "39e0db4d60568c800b8c5500026c2594f5768960": { + "balance": "1000000000000000000000" + }, + "40e3c283f7e24de0410c121bee60a5607f3e29a6": { + "balance": "1000000000000000000000" + }, + "2f7d3290851be5c6b4b43f7d4574329f61a792c3": { + "balance": "100000000000000000000" + }, + "c33ece935a8f4ef938ea7e1bac87cb925d8490ca": { + "balance": "33122000000000000000000" + }, + "57bddf078834009c89d88e6282759dc45335b470": { + "balance": "2148000000000000000000" + }, + "50ad187ab21167c2b6e78be0153f44504a07945e": { + "balance": "100076000000000000000" + }, + "5bd24aac3612b20c609eb46779bf95698407c57c": { + "balance": "1970000000000000000000" + }, + "16526c9edf943efa4f6d0f0bae81e18b31c54079": { + "balance": "985000000000000000000" + }, + "4c6a9dc2cab10abb2e7c137006f08fecb5b779e1": { + "balance": "499000000000000000000" + }, + "02c9f7940a7b8b7a410bf83dc9c22333d4275dd3": { + "balance": "5000000000000000000000" + }, + "b9fd3833e88e7cf1fa9879bdf55af4b99cd5ce3f": { + "balance": "1000000000000000000000" + }, + "7e268f131ddf687cc325c412f78ba961205e9112": { + "balance": "16000600000000000000000" + }, + "180478a655d78d0f3b0c4f202b61485bc4002fd5": { + "balance": "2000000000000000000000" + }, + "ed4014538cee664a2fbcb6dc669f7ab16d0ba57c": { + "balance": "200000000000000000000" + }, + "f63a579bc3eac2a9490410128dbcebe6d9de8243": { + "balance": "1490000000000000000000" + }, + "5d822d9b3ef4b502627407da272f67814a6becd4": { + "balance": "20000000000000000000" + }, + "eb52ab10553492329c1c54833ae610f398a65b9d": { + "balance": "152000000000000000000" + }, + "63340a57716bfa63eb6cd133721202575bf796f0": { + "balance": "209967000000000000000" + }, + "933bf33f8299702b3a902642c33e0bfaea5c1ca3": { + "balance": "15200000000000000000" + }, + "25bc49ef288cd165e525c661a812cf84fbec8f33": { + "balance": "338464000000000000000" + }, + "c8231ba5a411a13e222b29bfc1083f763158f226": { + "balance": "1000090000000000000000" + }, + "6c15ec3520bf8ebbc820bd0ff19778375494cf9d": { + "balance": "2005500000000000000000" + }, + "aaced8a9563b1bc311dbdffc1ae7f57519c4440c": { + "balance": "2000000000000000000000" + }, + "d90f3009db437e4e11c780bec8896f738d65ef0d": { + "balance": "4000000000000000000000" + }, + "5603241eb8f08f721e348c9d9ad92f48e390aa24": { + "balance": "200000000000000000000" + }, + "53cec6c88092f756efe56f7db11228a2db45b122": { + "balance": "4000000000000000000000" + }, + "194cebb4929882bf3b4bf9864c2b1b0f62c283f9": { + "balance": "571300000000000000000" + }, + "4be8628a8154874e048d80c142181022b180bcc1": { + "balance": "60000000000000000000" + }, + "5fd973af366aa5157c54659bcfb27cbfa5ac15d6": { + "balance": "4000000000000000000000" + }, + "303139bc596403d5d3931f774c66c4ba467454db": { + "balance": "1699830000000000000000" + }, + "87584a3f613bd4fac74c1e780b86d6caeb890cb2": { + "balance": "1700000000000000000000" + }, + "77f4e3bdf056883cc87280dbe640a18a0d02a207": { + "balance": "193806000000000000000" + }, + "4de3fe34a6fbf634c051997f47cc7f48791f5824": { + "balance": "1999000000000000000000" + }, + "c45a1ca1036b95004187cdac44a36e33a94ab5c3": { + "balance": "254800000000000000000" + }, + "65d33eb39cda6453b19e61c1fe4db93170ef9d34": { + "balance": "13370000000000000000" + }, + "f65616be9c8b797e7415227c9138faa0891742d7": { + "balance": "790000000000000000000" + }, + "e17812f66c5e65941e186c46922b6e7b2f0eeb46": { + "balance": "1820000000000000000000" + }, + "d47f50df89a1cff96513bef1b2ae3a2971accf2c": { + "balance": "840000000000000000000" + }, + "8ed1528b447ed4297902f639c514d0944a88f8c8": { + "balance": "198800000000000000000" + }, + "a4fb14409a67b45688a8593e5cc2cf596ced6f11": { + "balance": "1790000000000000000000" + }, + "855d9aef2c39c6230d09c99ef6494989abe68785": { + "balance": "161000000000000000000" + }, + "778c43d11afe3b586ff374192d96a7f23d2b9b7f": { + "balance": "2577139000000000000000" + }, + "e3ece1f632711d13bfffa1f8f6840871ee58fb27": { + "balance": "4000000000000000000000" + }, + "beb3358c50cf9f75ffc76d443c2c7f55075a0589": { + "balance": "2674000000000000000000" + }, + "f156dc0b2a981e5b55d3f2f03b8134e331dbadb7": { + "balance": "100000000000000000000" + }, + "eb9cc9fe0869d2dab52cc7aae8fd57adb35f9feb": { + "balance": "1966000000000000000000" + }, + "2467c6a5c696ede9a1e542bf1ad06bcc4b06aca0": { + "balance": "18500000000000000000" + }, + "ec75b4a47513120ba5f86039814f1998e3817ac3": { + "balance": "178756000000000000000" + }, + "9c3d0692ceeef80aa4965ceed262ffc7f069f2dc": { + "balance": "200000000000000000000" + }, + "e05029aceb0778675bef1741ab2cd2931ef7c84b": { + "balance": "5000057000000000000000" + }, + "41d3b731a326e76858baa5f4bd89b57b36932343": { + "balance": "394000000000000000000" + }, + "c346cb1fbce2ab285d8e5401f42dd7234d37e86d": { + "balance": "83500000000000000000" + }, + "45f4fc60f08eaca10598f0336329801e3c92cb46": { + "balance": "200000000000000000000" + }, + "f04a6a379708b9428d722aa2b06b77e88935cf89": { + "balance": "300000000000000000000" + }, + "232832cd5977e00a4c30d0163f2e24f088a6cb09": { + "balance": "3000000000000000000000" + }, + "d2ac0d3a58605e1d0f0eb3de25b2cad129ed6058": { + "balance": "4000000000000000000000" + }, + "a356551bb77d4f45a6d7e09f0a089e79cca249cb": { + "balance": "340000000000000000000" + }, + "b50c9f5789ae44e2dce017c714caf00c830084c2": { + "balance": "394000000000000000000" + }, + "21fd6c5d97f9c600b76821ddd4e776350fce2be0": { + "balance": "1999946000000000000000" + }, + "f0d5c31ccb6cbe30c7c9ea19f268d159851f8c9c": { + "balance": "16700000000000000000000" + }, + "ab7091932e4bc39dbb552380ca934fd7166d1e6e": { + "balance": "3340000000000000000000" + }, + "acd8dd91f714764c45677c63d852e56eb9eece2e": { + "balance": "2000000000000000000000" + }, + "57d032a43d164e71aa2ef3ffd8491b0a4ef1ea5b": { + "balance": "2000000000000000000000" + }, + "5af46a25ac09cb73616b53b14fb42ff0a51cddb2": { + "balance": "4000000000000000000000" + }, + "1ea6bf2f15ae9c1dbc64daa7f8ea4d0d81aad3eb": { + "balance": "4200000000000000000000" + }, + "03337012ae1d7ff3ee7f697c403e7780188bf0ef": { + "balance": "200000000000000000000" + }, + "32eb64be1b5dede408c6bdefbe6e405c16b7ed02": { + "balance": "1970000000000000000000" + }, + "22e2488e2da26a49ae84c01bd54b21f2947891c6": { + "balance": "1730000000000000000000" + }, + "be98a77fd41097b34f59d7589baad021659ff712": { + "balance": "900000000000000000000" + }, + "dda4ed2a58a8dd20a73275347b580d71b95bf99a": { + "balance": "399000000000000000000" + }, + "671110d96aaff11523cc546bf9940eedffb2faf7": { + "balance": "4000000000000000000000" + }, + "5d71799c8df3bccb7ee446df50b8312bc4eb71c5": { + "balance": "200000000000000000000" + }, + "ae179a460db66326743d24e67523a57b246daf7f": { + "balance": "4722920000000000000000" + }, + "198bfcf1b07ae308fa2c02069ac9dafe7135fb47": { + "balance": "20000000000000000000" + }, + "4662a1765ee921842ddc88898d1dc8627597bd7e": { + "balance": "10000000000000000000000" + }, + "783eec8aa5dac77b2e6623ed5198a431abbaee07": { + "balance": "440000000000000000000" + }, + "ed6643c0e8884b2d3211853785a08bf8f33ed29f": { + "balance": "1337000000000000000000" + }, + "5cc7d3066d45d27621f78bb4b339473e442a860f": { + "balance": "9999908000000000000000" + }, + "94ef8be45077c7d4c5652740de946a62624f713f": { + "balance": "100085000000000000000" + }, + "2f853817afd3b8f3b86e9f60ee77b5d97773c0e3": { + "balance": "1451450000000000000000" + }, + "3e0b8ed86ed669e12723af7572fbacfe829b1e16": { + "balance": "1499800000000000000000" + }, + "fa68e0cb3edf51f0a6f211c9b2cb5e073c9bffe6": { + "balance": "291200000000000000000" + }, + "2c234f505ca8dcc77d9b7e01d257c318cc19396d": { + "balance": "100000000000000000000" + }, + "f3f24fc29e20403fc0e8f5ebbb553426f78270a2": { + "balance": "100000000000000000000" + }, + "91546b79ecf69f936b5a561508b0d7e50cc5992f": { + "balance": "267400000000000000000" + }, + "435443b81dfdb9bd8c6787bc2518e2d47e57c15f": { + "balance": "5968500000000000000000" + }, + "3a06e3bb1edcfd0c44c3074de0bb606b049894a2": { + "balance": "10000000000000000000000" + }, + "3a3108c1e680a33b336c21131334409d97e5adec": { + "balance": "20000000000000000000" + }, + "2caf6bf4ec7d5a19c5e0897a5eeb011dcece4210": { + "balance": "139740000000000000000" + }, + "f44f8551ace933720712c5c491cdb6f2f951736c": { + "balance": "4000000000000000000000" + }, + "5bc1f95507b1018642e45cd9c0e22733b9b1a326": { + "balance": "100000000000000000000" + }, + "94ca56de777fd453177f5e0694c478e66aff8a84": { + "balance": "500000000000000000000" + }, + "afdd1b786162b8317e20f0e979f4b2ce486d765d": { + "balance": "20000000000000000000" + }, + "3a805fa0f7387f73055b7858ca8519edd93d634f": { + "balance": "1850000000000000000000" + }, + "8b36224c7356e751f0c066c35e3b44860364bfc2": { + "balance": "998987000000000000000" + }, + "cfecbea07c27002f65fe534bb8842d0925c78402": { + "balance": "4000000000000000000000" + }, + "482982ac1f1c6d1721feecd9b9c96cd949805055": { + "balance": "10000000000000000000000" + }, + "af880fc7567d5595cacce15c3fc14c8742c26c9e": { + "balance": "133700000000000000000" + }, + "acc1c78786ab4d2b3b277135b5ba123e0400486b": { + "balance": "78800000000000000000" + }, + "41f27e744bd29de2b0598f02a0bb9f98e681eaa4": { + "balance": "7760000000000000000000" + }, + "09a025316f967fa8b9a1d60700063f5a68001caa": { + "balance": "38200000000000000000" + }, + "391f20176d12360d724d51470a90703675594a4d": { + "balance": "1600000000000000000000" + }, + "fe4d8403216fd571572bf1bdb01d00578978d688": { + "balance": "9850000000000000000000" + }, + "900f0b8e35b668f81ef252b13855aa5007d012e7": { + "balance": "425000000000000000000" + }, + "c35b95a2a3737cb8f0f596b34524872bd30da234": { + "balance": "7540000000000000000000" + }, + "412a68f6c645559cc977fc4964047a201d1bb0e2": { + "balance": "50000000000000000000000" + }, + "d3dad1b6d08d4581ccae65a8732db6ac69f0c69e": { + "balance": "6000000000000000000000" + }, + "35855ec641ab9e081ed0c2a6dcd81354d0244a87": { + "balance": "1201897000000000000000" + }, + "88015d7203c5e0224aeda286ed12f1a51b789333": { + "balance": "4999711000000000000000" + }, + "251c12722c6879227992a304eb3576cd18434ea5": { + "balance": "2000000000000000000000" + }, + "1f6f0030349752061c96072bc3d6eb3549208d6b": { + "balance": "23891000000000000000" + }, + "86153063a1ae7f02f1a88136d4d69c7c5e3e4327": { + "balance": "1000000000000000000000" + }, + "78355df0a230f83d032c703154414de3eedab557": { + "balance": "2000000000000000000000" + }, + "c5b56cd234267c28e89c6f6b2266b086a12f970c": { + "balance": "4000000000000000000000" + }, + "3e3cd3bec06591d6346f254b621eb41c89008d31": { + "balance": "993800000000000000000" + }, + "378ea1dc8edc19bae82638029ea8752ce98bcfcd": { + "balance": "2000000000000000000000" + }, + "67632046dcb25a54936928a96f423f3320cbed92": { + "balance": "2000000000000000000000" + }, + "ddbee6f094eae63420b003fb4757142aea6cd0fd": { + "balance": "2000000000000000000000" + }, + "b555d00f9190cc3677aef314acd73fdc39399259": { + "balance": "2000000000000000000000" + }, + "e230fe1bff03186d0219f15d4c481b7d59be286a": { + "balance": "36710000000000000000" + }, + "3e4e9265223c9738324cf20bd06006d0073edb8c": { + "balance": "133700000000000000000" + }, + "7450ff7f99eaa9116275deac68e428df5bbcd8b9": { + "balance": "2000000000000000000000" + }, + "021f69043de88c4917ca10f1842897eec0589c7c": { + "balance": "1978760000000000000000" + }, + "351787843505f8e4eff46566cce6a59f4d1c5fe7": { + "balance": "9250000000000000000000" + }, + "ebd37b256563e30c6f9289a8e2702f0852880833": { + "balance": "1999944000000000000000" + }, + "ed41e1a28f5caa843880ef4e8b08bd6c33141edf": { + "balance": "790174000000000000000" + }, + "8d238e036596987643d73173c37b0ad06055b96c": { + "balance": "2089724000000000000000" + }, + "478e524ef2a381d70c82588a93ca7a5fa9d51cbf": { + "balance": "254908000000000000000000" + }, + "4419ac618d5dea7cdc6077206fb07dbdd71c1702": { + "balance": "4000000000000000000000" + }, + "ca25ff34934c1942e22a4e7bd56f14021a1af088": { + "balance": "197000000000000000000" + }, + "5552f4b3ed3e1da79a2f78bb13e8ae5a68a9df3b": { + "balance": "1000000000000000000000" + }, + "4354221e62dc09e6406436163a185ef06d114a81": { + "balance": "2000000000000000000000" + }, + "ca0432cb157b5179f02ebba5c9d1b54fec4d88ca": { + "balance": "1000000000000000000000" + }, + "8a780ab87a9145fe10ed60fa476a740af4cab1d2": { + "balance": "334000000000000000000" + }, + "4ff676e27f681a982d8fd9d20e648b3dce05e945": { + "balance": "2800000000000000000000" + }, + "6c63fc85029a2654d79b2bea4de349e4524577c5": { + "balance": "660000000000000000000" + }, + "1ac089c3bc4d82f06a20051a9d732dc0e734cb61": { + "balance": "700300000000000000000" + }, + "4bf4479799ef82eea20943374f56a1bf54001e5e": { + "balance": "3940000000000000000000" + }, + "08411652c871713609af0062a8a1281bf1bbcfd9": { + "balance": "1400000000000000000000" + }, + "e1bfaa5a45c504428923c4a61192a55b1400b45d": { + "balance": "2674000000000000000000" + }, + "5e1fbd4e58e2312b3c78d7aaaafa10bf9c3189e3": { + "balance": "40000000000000000000000" + }, + "bb27c6a7f91075475ab229619040f804c8ec7a6a": { + "balance": "10000000000000000000000" + }, + "5d8d31faa864e22159cd6f5175ccecc53fa54d72": { + "balance": "26980000000000000000000" + }, + "2dd8eeef87194abc2ce7585da1e35b7cea780cb7": { + "balance": "999999000000000000000" + }, + "0e1801e70b6262861b1134ccbc391f568afc92f7": { + "balance": "4000000000000000000000" + }, + "61042b80fd6095d1b87be2f00f109fabafd157a6": { + "balance": "100000000000000000000" + }, + "fb5518714cefc36d04865de5915ef0ff47dfe743": { + "balance": "2000000000000000000000" + }, + "b5add1e7809f7d03069bfe883b0a932210be8712": { + "balance": "1000000000000000000000" + }, + "c2e2d498f70dcd0859e50b023a710a6d4b2133bd": { + "balance": "1037130000000000000000" + }, + "4ad047fae67ef162fe68fedbc27d3b65caf10c36": { + "balance": "1970000000000000000000" + }, + "69cb3e2153998d86e5ee20c1fcd1a6baeeb2863f": { + "balance": "4000000000000000000000" + }, + "683633010a88686bea5a98ea53e87997cbf73e69": { + "balance": "99960000000000000000" + }, + "6cb11ecb32d3ce829601310636f5a10cf7cf9b5f": { + "balance": "20068370000000000000000" + }, + "a613456996408af1c2e93e177788ab55895e2b32": { + "balance": "6366000000000000000000" + }, + "8308ed0af7f8a3c1751fafc877b5a42af7d35882": { + "balance": "1000000000000000000000" + }, + "e5edf8123f2403ce1a0299becf7aac744d075f23": { + "balance": "200200000000000000000" + }, + "05665155cc49cbf6aabdd5ae92cbfaad82b8c0c1": { + "balance": "400000000000000000000" + }, + "00b277b099a8e866ca0ec65bcb87284fd142a582": { + "balance": "1970000000000000000000" + }, + "4b9e068fc4680976e61504912985fd5ce94bab0d": { + "balance": "668500000000000000000" + }, + "12134e7f6b017bf48e855a399ca58e2e892fa5c8": { + "balance": "1000000000000000000000" + }, + "dffcea5421ec15900c6ecfc777184e140e209e24": { + "balance": "19980000000000000000" + }, + "2132c0516a2e17174ac547c43b7b0020d1eb4c59": { + "balance": "985000000000000000000" + }, + "d39a5da460392b940b3c69bc03757bf3f2e82489": { + "balance": "7019250000000000000000" + }, + "66c8331efe7198e98b2d32b938688e3241d0e24f": { + "balance": "9620000000000000000000" + }, + "bdca2a0ff34588af625fa8e28fc3015ab5a3aa00": { + "balance": "2339800000000000000000" + }, + "7dfc342dffcf45dfee74f84c0995397bd1a63172": { + "balance": "250000000000000000000" + }, + "a202547242806f6e70e74058d6e5292defc8c8d4": { + "balance": "2002000000000000000000" + }, + "3bbc13d04accc0707aebdcaef087d0b87e0b5ee3": { + "balance": "3520000000000000000000" + }, + "be5cba8d37427986e8ca2600e858bb03c359520f": { + "balance": "2955000000000000000000" + }, + "4174fa1bc12a3b7183cbabb77a0b59557ba5f1db": { + "balance": "2000000000000000000000" + }, + "9eb3a7cb5e6726427a3a361cfa8d6164dbd0ba16": { + "balance": "804000000000000000000" + }, + "25e661c939863acc044e6f17b5698cce379ec3cc": { + "balance": "1370000000000000000000" + }, + "24bd5904059091d2f9e12d6a26a010ca22ab14e8": { + "balance": "1880000000000000000000" + }, + "c96626728aaa4c4fb3d31c26df3af310081710d1": { + "balance": "3340000000000000000000" + }, + "0fb5d2c673bfb1ddca141b9894fd6d3f05da6720": { + "balance": "100000000000000000000" + }, + "2de31afd189a13a76ff6fe73ead9f74bb5c4a629": { + "balance": "6000000000000000000000" + }, + "bd09126c891c4a83068059fe0e15796c4661a9f4": { + "balance": "800000000000000000000" + }, + "496f5843f6d24cd98d255e4c23d1e1f023227545": { + "balance": "1754143000000000000000" + }, + "540cf23dd95c4d558a279d778d2b3735b3164191": { + "balance": "10000000000000000000000" + }, + "9b5ec18e8313887df461d2902e81e67a8f113bb1": { + "balance": "100000000000000000000" + }, + "b7a7f77c348f92a9f1100c6bd829a8ac6d7fcf91": { + "balance": "1820000000000000000000" + }, + "2590126870e0bde8a663ab040a72a5573d8d41c2": { + "balance": "5000000000000000000000" + }, + "090fa9367bda57d0d3253a0a8ff76ce0b8e19a73": { + "balance": "1000000000000000000000" + }, + "2a5ba9e34cd58da54c9a2712663a3be274c8e47b": { + "balance": "197000000000000000000" + }, + "3e8641d43c42003f0a33c929f711079deb2b9e46": { + "balance": "500000000000000000000" + }, + "f4d97664cc4eec9edbe7fa09f4750a663b507d79": { + "balance": "4000000000000000000000" + }, + "b1540e94cff3465cc3d187e7c8e3bdaf984659e2": { + "balance": "2989950000000000000000" + }, + "f96883582459908c827627e86f28e646f9c7fc7a": { + "balance": "8350000000000000000000" + }, + "d4feed99e8917c5c5458635f3603ecb7e817a7d0": { + "balance": "300031000000000000000" + }, + "14b1603ec62b20022033eec4d6d6655ac24a015a": { + "balance": "50000000000000000000" + }, + "af8e1dcb314c950d3687434d309858e1a8739cd4": { + "balance": "267400000000000000000" + }, + "4b9206ba6b549a1a7f969e1d5dba867539d1fa67": { + "balance": "7880000000000000000000" + }, + "471010da492f4018833b088d9872901e06129174": { + "balance": "500000000000000000000" + }, + "d243184c801e5d79d2063f3578dbae81e7b3a9cb": { + "balance": "1989700000000000000000" + }, + "3eada8c92f56067e1bb73ce378da56dc2cdfd365": { + "balance": "2210000000000000000000" + }, + "33ea6b7855e05b07ab80dab1e14de9b649e99b6c": { + "balance": "532000000000000000000" + }, + "700711e311bb947355f755b579250ca7fd765a3e": { + "balance": "1790000000000000000000" + }, + "87fb26c31e48644d693134205cae43b21f18614b": { + "balance": "1370000000000000000000" + }, + "001d14804b399c6ef80e64576f657660804fec0b": { + "balance": "4200000000000000000000" + }, + "f9642086b1fbae61a6804dbe5fb15ec2d2b537f4": { + "balance": "2000000000000000000000" + }, + "6919dd5e5dfb1afa404703b9faea8cee35d00d70": { + "balance": "5910000000000000000000" + }, + "9ac4da51d27822d1e208c96ea64a1e5b55299723": { + "balance": "100040000000000000000" + }, + "1bd8ebaa7674bb18e19198db244f570313075f43": { + "balance": "150000000000000000000" + }, + "e64ef012658d54f8e8609c4e9023c09fe865c83b": { + "balance": "28000000000000000000" + }, + "43b079baf0727999e66bf743d5bcbf776c3b0922": { + "balance": "2000000000000000000000" + }, + "06ac26ad92cb859bd5905ddce4266aa0ec50a9c5": { + "balance": "775000000000000000000" + }, + "99c1d9f40c6ab7f8a92fce2fdce47a54a586c53f": { + "balance": "985000000000000000000" + }, + "4ae93082e45187c26160e66792f57fad3551c73a": { + "balance": "21658000000000000000000" + }, + "7da7613445a21299aa74f0ad71431ec43fbb1be9": { + "balance": "68000000000000000000" + }, + "4a9a26fd0a8ba10f977da4f77c31908dab4a8016": { + "balance": "1790000000000000000000" + }, + "972c2f96aa00cf8a2f205abcf8937c0c75f5d8d9": { + "balance": "200000000000000000000" + }, + "b5046cb3dc1dedbd364514a2848e44c1de4ed147": { + "balance": "16445100000000000000000" + }, + "48c2ee91a50756d8ce9abeeb7589d22c6fee5dfb": { + "balance": "3220000000000000000000" + }, + "46c1aa2244b9c8a957ca8fac431b0595a3b86824": { + "balance": "4000000000000000000000" + }, + "21fd0bade5f4ef7474d058b7f3d854cb1300524e": { + "balance": "20000000000000000000" + }, + "1864a3c7b48155448c54c88c708f166709736d31": { + "balance": "133700000000000000000" + }, + "5dd53ae897526b167d39f1744ef7c3da5b37a293": { + "balance": "8000000000000000000000" + }, + "ece111670b563ccdbebca52384290ecd68fe5c92": { + "balance": "20000000000000000000" + }, + "74d671d99cbea1ab57906375b63ff42b50451d17": { + "balance": "1000000000000000000000" + }, + "5717cc9301511d4a81b9f583148beed3d3cc8309": { + "balance": "2600000000000000000000" + }, + "8f92844f282a92999ee5b4a8d773d06b694dbd9f": { + "balance": "1940000000000000000000" + }, + "b5a606f4ddcbb9471ec67f658caf2b00ee73025e": { + "balance": "4325000000000000000000" + }, + "bdb60b823a1173d45a0792245fb496f1fd3301cf": { + "balance": "2000000000000000000000" + }, + "1d2615f8b6ca5012b663bdd094b0c5137c778ddf": { + "balance": "10000000000000000000000" + }, + "82ff716fdf033ec7e942c909d9831867b8b6e2ef": { + "balance": "1790000000000000000000" + }, + "44c14765127cde11fab46c5d2cf4d4b2890023fd": { + "balance": "2000000000000000000000" + }, + "c72cb301258e91bc08998a805dd192f25c2f9a35": { + "balance": "591000000000000000000" + }, + "ad732c976593eec4783b4e2ecd793979780bfedb": { + "balance": "2000000000000000000000" + }, + "d8f62036f03b7635b858f1103f8a1d9019a892b6": { + "balance": "50000000000000000000" + }, + "0a06fad7dcd7a492cbc053eeabde6934b39d8637": { + "balance": "20000000000000000000" + }, + "67f2bb78b8d3e11f7c458a10b5c8e0a1d374467d": { + "balance": "1790000000000000000000" + }, + "4b5cdb1e428c91dd7cb54a6aed4571da054bfe52": { + "balance": "88000000000000000000" + }, + "b3557d39b5411b84445f5f54f38f62d2714d0087": { + "balance": "600000000000000000000" + }, + "0b0e055b28cbd03dc5ff44aa64f3dce04f5e63fb": { + "balance": "2000000000000000000000" + }, + "9b2be7f56754f505e3441a10f7f0e20fd3ddf849": { + "balance": "340000000000000000000" + }, + "0b93fca4a4f09cac20db60e065edcccc11e0a5b6": { + "balance": "200000000000000000000" + }, + "3bc85d6c735b9cda4bba5f48b24b13e70630307b": { + "balance": "1970000000000000000000" + }, + "52102354a6aca95d8a2e86d5debda6de69346076": { + "balance": "2000000000000000000000" + }, + "cda4530f4b9bc50905b79d17c28fc46f95349bdf": { + "balance": "942000000000000000000" + }, + "ff545bbb66fbd00eb5e6373ff4e326f5feb5fe12": { + "balance": "20000000000000000000" + }, + "4030a925706b2c101c8c5cb9bd05fbb4f6759b18": { + "balance": "4000000000000000000000" + }, + "f11e01c7a9d12499005f4dae7716095a34176277": { + "balance": "400000000000000000000" + }, + "a4826b6c3882fad0ed5c8fbb25cc40cc4f33759f": { + "balance": "2068000000000000000000" + }, + "28510e6eff1fc829b6576f4328bc3938ec7a6580": { + "balance": "10000000000000000000000" + }, + "9ce5363b13e8238aa4dd15acd0b2e8afe0873247": { + "balance": "200000000000000000000" + }, + "d97bc84abd47c05bbf457b2ef659d61ca5e5e48f": { + "balance": "122000000000000000000" + }, + "4a719061f5285495b37b9d7ef8a51b07d6e6acac": { + "balance": "199800000000000000000" + }, + "8b714522fa2839620470edcf0c4401b713663df1": { + "balance": "200000000000000000000" + }, + "b6decf82969819ba02de29b9b593f21b64eeda0f": { + "balance": "740000000000000000000" + }, + "c87d3ae3d88704d9ab0009dcc1a0067131f8ba3c": { + "balance": "1969606000000000000000" + }, + "dccb370ed68aa922283043ef7cad1b9d403fc34a": { + "balance": "4000000000000000000000" + }, + "2d532df4c63911d1ce91f6d1fcbff7960f78a885": { + "balance": "1669833000000000000000" + }, + "1fcfd1d57f872290560cb62d600e1defbefccc1c": { + "balance": "1490000000000000000000" + }, + "d9e27eb07dfc71a706060c7f079238ca93e88539": { + "balance": "1000000000000000000000" + }, + "da7732f02f2e272eaf28df972ecc0ddeed9cf498": { + "balance": "205274000000000000000" + }, + "bf09d77048e270b662330e9486b38b43cd781495": { + "balance": "436000000000000000000000" + }, + "619f171445d42b02e2e07004ad8afe694fa53d6a": { + "balance": "20000000000000000000" + }, + "2bdd03bebbee273b6ca1059b34999a5bbd61bb79": { + "balance": "20000000000000000000" + }, + "8da1d359ba6cb4bcc57d7a437720d55db2f01c72": { + "balance": "80000000000000000000" + }, + "be935793f45b70d8045d2654d8dd3ad24b5b6137": { + "balance": "880000000000000000000" + }, + "ee71793e3acf12a7274f563961f537529d89c7de": { + "balance": "2000000000000000000000" + }, + "86f05d19063e9369c6004eb3f123943a7cff4eab": { + "balance": "1999944000000000000000" + }, + "87b10f9c280098179a2b76e9ce90be61fc844d0d": { + "balance": "1337000000000000000000" + }, + "243c84d12420570cc4ef3baba1c959c283249520": { + "balance": "2345000000000000000000" + }, + "6bc85acd5928722ef5095331ee88f484b8cf8357": { + "balance": "180000000000000000000" + }, + "2561a138dcf83bd813e0e7f108642be3de3d6f05": { + "balance": "999940000000000000000" + }, + "7d0350e40b338dda736661872be33f1f9752d755": { + "balance": "49933000000000000000" + }, + "e5dc9349cb52e161196122cf87a38936e2c57f34": { + "balance": "2000000000000000000000" + }, + "543a8c0efb8bcd15c543e2a6a4f807597631adef": { + "balance": "5893800000000000000000" + }, + "0413d0cf78c001898a378b918cd6e498ea773c4d": { + "balance": "280000000000000000000" + }, + "3708e59de6b4055088782902e0579c7201a8bf50": { + "balance": "200000000000000000000000" + }, + "699fc6d68a4775573c1dcdaec830fefd50397c4e": { + "balance": "60000000000000000000" + }, + "379a7f755a81a17edb7daaa28afc665dfa6be63a": { + "balance": "25000000000000000000" + }, + "260a230e4465077e0b14ee4442a482d5b0c914bf": { + "balance": "1677935000000000000000" + }, + "3daa01ceb70eaf9591fa521ba4a27ea9fb8ede4a": { + "balance": "1667400000000000000000" + }, + "7f3a1e45f67e92c880e573b43379d71ee089db54": { + "balance": "100000000000000000000000" + }, + "38643babea6011316cc797d9b093c897a17bdae7": { + "balance": "334400000000000000000" + }, + "84675e9177726d45eaa46b3992a340ba7f710c95": { + "balance": "1000000000000000000000" + }, + "0f83461ba224bb1e8fdd9dae535172b735acb4e0": { + "balance": "200000000000000000000" + }, + "31aa3b1ebe8c4dbcb6a708b1d74831e60e497660": { + "balance": "400000000000000000000" + }, + "a32cf7dde20c3dd5679ff5e325845c70c5962662": { + "balance": "20000000000000000000" + }, + "c007f0bdb6e7009202b7af3ea90902697c721413": { + "balance": "2999966000000000000000" + }, + "05c64004a9a826e94e5e4ee267fa2a7632dd4e6f": { + "balance": "16191931000000000000000" + }, + "f622e584a6623eaaf99f2be49e5380c5cbcf5cd8": { + "balance": "200000000000000000000" + }, + "9dc10fa38f9fb06810e11f60173ec3d2fd6a751e": { + "balance": "1970000000000000000000" + }, + "423c3107f4bace414e499c64390a51f74615ca5e": { + "balance": "2000000000000000000000" + }, + "92438e5203b6346ff886d7c36288aacccc78ceca": { + "balance": "1000000000000000000000" + }, + "bef07d97c3481f9d6aee1c98f9d91a180a32442b": { + "balance": "100000000000000000000000" + }, + "55aa5d313ebb084da0e7801091e29e92c5dec3aa": { + "balance": "2000000000000000000000" + }, + "89c433d601fad714da6369308fd26c1dc9942bbf": { + "balance": "2000000000000000000000" + }, + "25106ab6755df86d6b63a187703b0cfea0e594a0": { + "balance": "27400000000000000000" + }, + "494256e99b0f9cd6e5ebca3899863252900165c8": { + "balance": "14000000000000000000000" + }, + "5f4ace4c1cc13391e01f00b198e1f20b5f91cbf5": { + "balance": "5000196000000000000000" + }, + "135cecd955e5798370769230159303d9b1839f66": { + "balance": "5000000000000000000000" + }, + "ced81ec3533ff1bfebf3e3843ee740ad11758d3e": { + "balance": "1970000000000000000000" + }, + "688eb3853bbcc50ecfee0fa87f0ab693cabdef02": { + "balance": "31600000000000000000000" + }, + "2159240813a73095a7ebf7c3b3743e8028ae5f09": { + "balance": "2000000000000000000000" + }, + "99d1579cd42682b7644e1d4f7128441eeffe339d": { + "balance": "20000000000000000000000" + }, + "8a243a0a9fea49b839547745ff2d11af3f4b0522": { + "balance": "985000000000000000000" + }, + "c1a41a5a27199226e4c7eb198b031b59196f9842": { + "balance": "191000000000000000000" + }, + "7514adbdc63f483f304d8e94b67ff3309f180b82": { + "balance": "622911000000000000000" + }, + "74aeec915de01cc69b2cb5a6356feea14658c6c5": { + "balance": "232500000000000000000" + }, + "76f9ad3d9bbd04ae055c1477c0c35e7592cb2a20": { + "balance": "40200000000000000000000" + }, + "a8a7b68adab4e3eadff19ffa58e34a3fcec0d96a": { + "balance": "6000000000000000000000" + }, + "60de22a1507432a47b01cc68c52a0bf8a2e0d098": { + "balance": "19100000000000000000" + }, + "ceb33d78e7547a9da2e87d51aec5f3441c87923a": { + "balance": "20000000000000000000" + }, + "432809a2390f07c665921ff37d547d12f1c9966a": { + "balance": "30000000000000000000000" + }, + "d5e656a1b916f9bf45afb07dd8afaf73b4c56f41": { + "balance": "97000000000000000000" + }, + "e3410bb7557cf91d79fa69d0dfea0aa075402651": { + "balance": "2000000000000000000000" + }, + "dee942d5caf5fac11421d86b010b458e5c392990": { + "balance": "4000000000000000000000" + }, + "a98f109835f5eacd0543647c34a6b269e3802fac": { + "balance": "400000000000000000000" + }, + "932b9c04d40d2ac83083d94298169dae81ab2ed0": { + "balance": "2000000000000000000000" + }, + "ba10f2764290f875434372f79dbf713801caac01": { + "balance": "955000000000000000000" + }, + "a2c7eaffdc2c9d937345206c909a52dfb14c478f": { + "balance": "143000000000000000000" + }, + "6c67e0d7b62e2a08506945a5dfe38263339f1f22": { + "balance": "1970000000000000000000" + }, + "60c3714fdddb634659e4a2b1ea42c4728cc7b8ba": { + "balance": "13370000000000000000" + }, + "73b4d499de3f38bf35aaf769a6e318bc6d123692": { + "balance": "2000000000000000000000" + }, + "3b22dea3c25f1b59c7bd27bb91d3a3eaecef3984": { + "balance": "100000000000000000000" + }, + "1e3badb1b6e1380e27039c576ae6222e963a5b53": { + "balance": "20000000000000000000000" + }, + "abd4d6c1666358c0406fdf3af248f78ece830104": { + "balance": "2112000000000000000000" + }, + "0c925ad5eb352c8ef76d0c222d115b0791b962a1": { + "balance": "3180000000000000000000" + }, + "be9186c34a52514abb9107860f674f97b821bd5b": { + "balance": "509600000000000000000" + }, + "b7f67314cb832e32e63b15a40ce0d7ffbdb26985": { + "balance": "1060866000000000000000" + }, + "3f30d3bc9f602232bc724288ca46cd0b0788f715": { + "balance": "4000000000000000000000" + }, + "970abd53a54fca4a6429207c182d4d57bb39d4a0": { + "balance": "2000000000000000000000" + }, + "36d85dc3683156e63bf880a9fab7788cf8143a27": { + "balance": "20000000000000000000000" + }, + "2836123046b284e5ef102bfd22b1765e508116ad": { + "balance": "411880000000000000000" + }, + "de06d5ea777a4eb1475e605dbcbf43444e8037ea": { + "balance": "50000000000000000000000" + }, + "9af11399511c213181bfda3a8b264c05fc81b3ce": { + "balance": "14000000000000000000000" + }, + "e2191215983f33fd33e22cd4a2490054da53fddc": { + "balance": "15800000000000000000" + }, + "2eebf59432b52892f9380bd140aa99dcf8ad0c0f": { + "balance": "152000000000000000000" + }, + "dc087f9390fb9e976ac23ab689544a0942ec2021": { + "balance": "1820000000000000000000" + }, + "fd4b989558ae11be0c3b36e2d6f2a54a9343ca2e": { + "balance": "2000000000000000000000" + }, + "770c2fb2c4a81753ac0182ea460ec09c90a516f8": { + "balance": "20000000000000000000" + }, + "b28dbfc6499894f73a71faa00abe0f4bc9d19f2a": { + "balance": "100000000000000000000" + }, + "b0cef8e8fb8984a6019f01c679f272bbe68f5c77": { + "balance": "152000000000000000000" + }, + "f400f93d5f5c7e3fc303129ac8fb0c2f786407fa": { + "balance": "2000000000000000000000" + }, + "f2133431d1d9a37ba2f0762bc40c5acc8aa6978e": { + "balance": "2000000000000000000000" + }, + "9003d270891ba2df643da8341583193545e3e000": { + "balance": "4000000000000000000000" + }, + "8938d1b4daee55a54d738cf17e4477f6794e46f7": { + "balance": "18200000000000000000" + }, + "98e6f547db88e75f1f9c8ac2c5cf1627ba580b3e": { + "balance": "1000000000000000000000" + }, + "009fdbf44e1f4a6362b769c39a475f95a96c2bc7": { + "balance": "564000000000000000000" + }, + "d0f9597811b0b992bb7d3757aa25b4c2561d32e2": { + "balance": "500000000000000000000" + }, + "dcd10c55bb854f754434f1219c2c9a98ace79f03": { + "balance": "4000086000000000000000" + }, + "67048f3a12a4dd1f626c64264cb1d7971de2ca38": { + "balance": "180000000000000000000" + }, + "d33cf82bf14c592640a08608914c237079d5be34": { + "balance": "2000000000000000000000" + }, + "f5b068989df29c253577d0405ade6e0e7528f89e": { + "balance": "1610000000000000000000" + }, + "a9a8eca11a23d64689a2aa3e417dbb3d336bb59a": { + "balance": "262025000000000000000" + }, + "99413704b1a32e70f3bc0d69dd881c38566b54cb": { + "balance": "27382708000000000000000" + }, + "2a085e25b64862f5e68d768e2b0f7a8529858eee": { + "balance": "1983618000000000000000" + }, + "833d3fae542ad5f8b50ce19bde2bec579180c88c": { + "balance": "346000000000000000000" + }, + "c3483d6e88ac1f4ae73cc4408d6c03abe0e49dca": { + "balance": "17000000000000000000000" + }, + "fde395bc0b6d5cbb4c1d8fea3e0b4bff635e9db7": { + "balance": "2000000000000000000000" + }, + "eddacd94ec89a2ef968fcf977a08f1fae2757869": { + "balance": "8000000000000000000000" + }, + "dc29119745d2337320da51e19100c948d980b915": { + "balance": "160000000000000000000" + }, + "640bf87415e0cf407301e5599a68366da09bbac8": { + "balance": "493207000000000000000" + }, + "afcc7dbb8356d842d43ae7e23c8422b022a30803": { + "balance": "30400000000000000000000" + }, + "9120e71173e1ba19ba8f9f4fdbdcaa34e1d6bb78": { + "balance": "2000000000000000000000" + }, + "9092918707c621fdbd1d90fb80eb787fd26f7350": { + "balance": "2460000000000000000000" + }, + "263e57dacbe0149f82fe65a2664898866ff5b463": { + "balance": "38000000000000000000000" + }, + "315db7439fa1d5b423afa7dd7198c1cf74c918bc": { + "balance": "600000000000000000000" + }, + "09b4668696f86a080f8bebb91db8e6f87015915a": { + "balance": "656010000000000000000" + }, + "5c31996dcac015f9be985b611f468730ef244d90": { + "balance": "200000000000000000000" + }, + "b1179589e19db9d41557bbec1cb24ccc2dec1c7f": { + "balance": "100000000000000000000000" + }, + "3b1937d5e793b89b63fb8eb5f1b1c9ca6ba0fa8e": { + "balance": "2000000000000000000000" + }, + "c9127b7f6629ee13fc3f60bc2f4467a20745a762": { + "balance": "16465639000000000000000" + }, + "7306de0e288b56cfdf987ef0d3cc29660793f6dd": { + "balance": "508060000000000000000" + }, + "2aa192777ca5b978b6b2c2ff800ac1860f753f47": { + "balance": "335000000000000000000" + }, + "55da9dcdca61cbfe1f133c7bcefc867b9c8122f9": { + "balance": "880000000000000000000" + }, + "cdd9efac4d6d60bd71d95585dce5d59705c13564": { + "balance": "100000000000000000000" + }, + "ad8e48a377695de014363a523a28b1a40c78f208": { + "balance": "1000000000000000000000" + }, + "252b6555afdc80f2d96d972d17db84ea5ad521ac": { + "balance": "7880000000000000000000" + }, + "60ab71cd26ea6d6e59a7a0f627ee079c885ebbf6": { + "balance": "26740000000000000000" + }, + "f40b134fea22c6b29c8457f49f000f9cda789adb": { + "balance": "600000000000000000000" + }, + "85a2f6ea94d05e8c1d9ae2f4910338a358e98ded": { + "balance": "2000000000000000000000" + }, + "ae13a08511110f32e53be4127845c843a1a57c7b": { + "balance": "500000000000000000000" + }, + "40db1ba585ce34531edec5494849391381e6ccd3": { + "balance": "1790000000000000000000" + }, + "0c5589a7a89b9ad15b02751930415948a875fbef": { + "balance": "126000000000000000000" + }, + "89054430dcdc28ac15fa635ef87c105e602bf70c": { + "balance": "108000000000000000000" + }, + "6c882c27732cef5c7c13a686f0a2ea77555ac289": { + "balance": "100000000000000000000000" + }, + "de374299c1d07d79537385190f442ef9ca24061f": { + "balance": "133700000000000000000" + }, + "b146a0b925553cf06fcaf54a1b4dfea621290757": { + "balance": "2000200000000000000000" + }, + "09ae49e37f121df5dc158cfde806f173a06b0c7f": { + "balance": "3988000000000000000000" + }, + "b758896f1baa864f17ebed16d953886fee68aae6": { + "balance": "1000000000000000000000" + }, + "30730466b8eb6dc90d5496aa76a3472d7dbe0bbe": { + "balance": "1999800000000000000000" + }, + "fc02734033e57f70517e0afc7ee62461f06fad8e": { + "balance": "394000000000000000000" + }, + "a9b2d2e0494eab18e07d37bbb856d80e80f84cd3": { + "balance": "10000000000000000000000" + }, + "95278b08dee7c0f2c8c0f722f9fcbbb9a5241fda": { + "balance": "2408672000000000000000" + }, + "dab6bcdb83cf24a0ae1cb21b3b5b83c2f3824927": { + "balance": "50000000000000000000000" + }, + "94439ca9cc169a79d4a09cae5e67764a6f871a21": { + "balance": "240000000000000000000" + }, + "e06c29a81517e0d487b67fb0b6aabc4f57368388": { + "balance": "401100000000000000000" + }, + "458e3cc99e947844a18e6a42918fef7e7f5f5eb3": { + "balance": "36400000000000000000000" + }, + "0a9804137803ba6868d93a55f9985fcd540451e4": { + "balance": "13370000000000000000" + }, + "40630024bd2c58d248edd8465617b2bf1647da0e": { + "balance": "1000000000000000000000" + }, + "15224ad1c0face46f9f556e4774a3025ad06bd52": { + "balance": "13370000000000000000" + }, + "2e2810dee44ae4dff3d86342ab126657d653c336": { + "balance": "200000000000000000000" + }, + "48a30de1c919d3fd3180e97d5f2b2a9dbd964d2d": { + "balance": "44000000000000000000" + }, + "46a30b8a808931217445c3f5a93e882c0345b426": { + "balance": "250019000000000000000" + }, + "455396a4bbd9bae8af9fb7c4d64d471db9c24505": { + "balance": "161000000000000000000" + }, + "edfda2d5db98f9380714664d54b4ee971a1cae03": { + "balance": "40044000000000000000" + }, + "f5eadcd2d1b8657a121f33c458a8b13e76b65526": { + "balance": "249828000000000000000" + }, + "90e7070f4d033fe6910c9efe5a278e1fc6234def": { + "balance": "100392000000000000000" + }, + "d55508adbbbe9be81b80f97a6ea89add68da674f": { + "balance": "2000000000000000000000" + }, + "66925de3e43f4b41bf9dadde27d5488ef569ea0d": { + "balance": "39400000000000000000" + }, + "b7c077946674ba9341fb4c747a5d50f5d2da6415": { + "balance": "1000000000000000000000" + }, + "c52d1a0c73c2a1be84915185f8b34faa0adf1de3": { + "balance": "1400001000000000000000" + }, + "79b8aad879dd30567e8778d2d231c8f37ab8734e": { + "balance": "2000000000000000000000" + }, + "3aae4872fd9093cbcad1406f1e8078bab50359e2": { + "balance": "39400000000000000000" + }, + "b2e9d76bf50fc36bf7d3944b63e9ca889b699968": { + "balance": "2660000000000000000000" + }, + "405f596b94b947344c033ce2dcbff12e25b79784": { + "balance": "2000000000000000000000" + }, + "232cb1cd49993c144a3f88b3611e233569a86bd6": { + "balance": "15576000000000000000000" + }, + "9e232c08c14dc1a6ed0b8a3b2868977ba5c17d10": { + "balance": "20000000000000000000" + }, + "095270cc42141dd998ad2862dbd1fe9b44e7e650": { + "balance": "1200000000000000000000" + }, + "15d99468507aa0413fb60dca2adc7f569cb36b54": { + "balance": "2000000000000000000000" + }, + "04852732b4c652f6c2e58eb36587e60a62da14db": { + "balance": "20000000000000000000000" + }, + "ecf24cdd7c22928c441e694de4aa31b0fab59778": { + "balance": "600000000000000000000" + }, + "512b91bbfaa9e581ef683fc90d9db22a8f49f48b": { + "balance": "310000000000000000000000" + }, + "a88577a073fbaf33c4cd202e00ea70ef711b4006": { + "balance": "2000000000000000000000" + }, + "00acc6f082a442828764d11f58d6894ae408f073": { + "balance": "60000000000000000000000" + }, + "0355bcacbd21441e95adeedc30c17218c8a408ce": { + "balance": "400000000000000000000" + }, + "4e73cf2379f124860f73d6d91bf59acc5cfc845b": { + "balance": "40110000000000000000" + }, + "2a742b8910941e0932830a1d9692cfd28494cf40": { + "balance": "499986000000000000000" + }, + "41a8c2830081b102df6e0131657c07ab635b54ce": { + "balance": "1999944000000000000000" + }, + "b63064bd3355e6e07e2d377024125a33776c4afa": { + "balance": "38800000000000000000000" + }, + "1a25e1c5bc7e5f50ec16f8885f210ea1b938800e": { + "balance": "4000000000000000000000" + }, + "09b59b8698a7fbd3d2f8c73a008988de3e406b2b": { + "balance": "40000000000000000000000" + }, + "c555b93156f09101233c6f7cf6eb3c4f196d3346": { + "balance": "3000000000000000000000" + }, + "12f32c0a1f2daab676fe69abd9e018352d4ccd45": { + "balance": "50000000000000000000" + }, + "5956b28ec7890b76fc061a1feb52d82ae81fb635": { + "balance": "2000000000000000000000" + }, + "c739259e7f85f2659bef5f609ed86b3d596c201e": { + "balance": "200000000000000000000" + }, + "fae92c1370e9e1859a5df83b56d0f586aa3b404c": { + "balance": "106480000000000000000" + }, + "d5a7bec332adde18b3104b5792546aa59b879b52": { + "balance": "2000000000000000000000" + }, + "4f88dfd01091a45a9e2676021e64286cd36b8d34": { + "balance": "1000000000000000000000" + }, + "102c477d69aadba9a0b0f62b7459e17fbb1c1561": { + "balance": "2000000000000000000000" + }, + "34272d5e7574315dcae9abbd317bac90289d4765": { + "balance": "1820000000000000000000" + }, + "fe615d975c0887e0c9113ec7298420a793af8b96": { + "balance": "8000000000000000000000" + }, + "487adf7d70a6740f8d51cbdd68bb3f91c4a5ce68": { + "balance": "66850000000000000000" + }, + "7e5d9993104e4cb545e179a2a3f971f744f98482": { + "balance": "2000000000000000000000" + }, + "5529830a61c1f13c197e550beddfd6bd195c9d02": { + "balance": "10000000000000000000000" + }, + "2f282abbb6d4a3c3cd3b5ca812f7643e80305f06": { + "balance": "1850000000000000000000" + }, + "7352586d021ad0cf77e0e928404a59f374ff4582": { + "balance": "3400000000000000000000" + }, + "03f7b92008813ae0a676eb212814afab35221069": { + "balance": "2000000000000000000000" + }, + "056686078fb6bcf9ba0a8a8dc63a906f5feac0ea": { + "balance": "499800000000000000000" + }, + "8063379a7bf2cb923a84c5093e68dac7f75481c5": { + "balance": "322102000000000000000" + }, + "200264a09f8c68e3e6629795280f56254f8640d0": { + "balance": "20000000000000000000" + }, + "5a891155f50e42074374c739baadf7df2651153a": { + "balance": "4775000000000000000000" + }, + "80022a1207e910911fc92849b069ab0cdad043d3": { + "balance": "13370000000000000000" + }, + "e781ec732d401202bb9bd13860910dd6c29ac0b6": { + "balance": "1240000000000000000000" + }, + "4c2f1afef7c5868c44832fc77cb03b55f89e6d6e": { + "balance": "20000000000000000000000" + }, + "34ff582952ff24458f7b13d51f0b4f987022c1fe": { + "balance": "2804400000000000000000" + }, + "73914b22fc2f131584247d82be4fecbf978ad4ba": { + "balance": "2000000000000000000000" + }, + "562be95aba17c5371fe2ba828799b1f55d2177d6": { + "balance": "38200000000000000000000" + }, + "648f5bd2a2ae8902db37847d1cb0db9390b06248": { + "balance": "7769965000000000000000" + }, + "6a9758743b603eea3aa0524b42889723c4153948": { + "balance": "10100000000000000000000" + }, + "5985c59a449dfc5da787d8244e746c6d70caa55f": { + "balance": "100000000000000000000" + }, + "56ee197f4bbf9f1b0662e41c2bbd9aa1f799e846": { + "balance": "1000000000000000000000" + }, + "d47c242edffea091bc54d57df5d1fdb93101476c": { + "balance": "2914000000000000000000" + }, + "d482e7f68e41f238fe517829de15477fe0f6dd1d": { + "balance": "500000000000000000000" + }, + "05bf4fcfe772e45b826443852e6c351350ce72a2": { + "balance": "8000000000000000000000" + }, + "f10462e58fcc07f39584a187639451167e859201": { + "balance": "169830000000000000000" + }, + "1aa27699cada8dc3a76f7933aa66c71919040e88": { + "balance": "400000000000000000000" + }, + "24046b91da9b61b629cb8b8ec0c351a07e0703e4": { + "balance": "2000000000000000000000" + }, + "41033c1b6d05e1ca89b0948fc64453fbe87ab25e": { + "balance": "1337000000000000000000" + }, + "369822f5578b40dd1f4471706b22cd971352da6b": { + "balance": "346000000000000000000" + }, + "044e853144e3364495e7a69fa1d46abea3ac0964": { + "balance": "49225000000000000000" + }, + "abf728cf9312f22128024e7046c251f5dc5901ed": { + "balance": "29550000000000000000000" + }, + "d781f7fc09184611568570b4986e2c72872b7ed0": { + "balance": "20002000000000000000" + }, + "6bb4a661a33a71d424d49bb5df28622ed4dffcf4": { + "balance": "630400000000000000000" + }, + "fef3b3dead1a6926d49aa32b12c22af54d9ff985": { + "balance": "1000000000000000000000" + }, + "fa410971ad229c3036f41acf852f2ac999281950": { + "balance": "3997400000000000000000" + }, + "de176b5284bcee3a838ba24f67fc7cbf67d78ef6": { + "balance": "37600000000000000000" + }, + "23120046f6832102a752a76656691c863e17e59c": { + "balance": "329800000000000000000" + }, + "a2f472fe4f22b77db489219ea4023d11582a9329": { + "balance": "40000000000000000000000" + }, + "f0d64cf9df09741133d170485fd24b005011d520": { + "balance": "498680000000000000000" + }, + "8b505e2871f7deb7a63895208e8227dcaa1bff05": { + "balance": "61216600000000000000000" + }, + "481e3a91bfdc2f1c8428a0119d03a41601417e1c": { + "balance": "1000000000000000000000" + }, + "bc69a0d2a31c3dbf7a9122116901b2bdfe9802a0": { + "balance": "3000000000000000000000" + }, + "20a81680e465f88790f0074f60b4f35f5d1e6aa5": { + "balance": "1279851000000000000000" + }, + "194a6bb302b8aba7a5b579df93e0df1574967625": { + "balance": "500000000000000000000" + }, + "264cc8086a8710f91b21720905912cd7964ae868": { + "balance": "26740000000000000000" + }, + "24aca08d5be85ebb9f3132dfc1b620824edfedf9": { + "balance": "18200000000000000000" + }, + "1851a063ccdb30549077f1d139e72de7971197d5": { + "balance": "2000000000000000000000" + }, + "f64a4ac8d540a9289c68d960d5fb7cc45a77831c": { + "balance": "2000000000000000000000" + }, + "c3db5657bb72f10d58f231fddf11980aff678693": { + "balance": "5910000000000000000000" + }, + "b46ace865e2c50ea4698d216ab455dff5a11cd72": { + "balance": "1000000000000000000000" + }, + "9faea13c733412dc4b490402bfef27a0397a9bc3": { + "balance": "310000000000000000000" + }, + "b40594c4f3664ef849cca6227b8a25aa690925ee": { + "balance": "4000000000000000000000" + }, + "672fa0a019088db3166f6119438d07a99f8ba224": { + "balance": "13370000000000000000000" + }, + "c1ffad07db96138c4b2a530ec1c7de29b8a0592c": { + "balance": "17600000000000000000" + }, + "87af25d3f6f8eea15313d5fe4557e810c524c083": { + "balance": "19700000000000000000000" + }, + "d6a22e598dabd38ea6e958bd79d48ddd9604f4df": { + "balance": "1000000000000000000000" + }, + "a2a435de44a01bd0ecb29e44e47644e46a0cdffb": { + "balance": "500171000000000000000" + }, + "549b47649cfad993e4064d2636a4baa0623305cc": { + "balance": "601650000000000000000" + }, + "1321b605026f4ffb296a3e0edcb390c9c85608b7": { + "balance": "2000000000000000000000" + }, + "b4bf24cb83686bc469869fefb044b909716993e2": { + "balance": "2000000000000000000000" + }, + "12d91a92d74fc861a729646db192a125b79f5374": { + "balance": "18200000000000000000" + }, + "7f0662b410298c99f311d3a1454a1eedba2fea76": { + "balance": "200000000000000000000" + }, + "83908aa7478a6d1c9b9b0281148f8f9f242b9fdc": { + "balance": "2000000000000000000000" + }, + "c1438c99dd51ef1ca8386af0a317e9b041457888": { + "balance": "223500000000000000000" + }, + "545bb070e781172eb1608af7fc2895d6cb87197e": { + "balance": "2244000000000000000000" + }, + "161d26ef6759ba5b9f20fdcd66f16132c352415e": { + "balance": "2000000000000000000000" + }, + "d7f370d4bed9d57c6f49c999de729ee569d3f4e4": { + "balance": "200000000000000000000" + }, + "90e35aabb2deef408bb9b5acef714457dfde6272": { + "balance": "100076000000000000000" + }, + "0fcfc4065008cfd323305f6286b57a4dd7eee23b": { + "balance": "20000000000000000000000" + }, + "cd725d70be97e677e3c8e85c0b26ef31e9955045": { + "balance": "1337000000000000000000" + }, + "dcf6b657266e91a4dae6033ddac15332dd8d2b34": { + "balance": "1760000000000000000000" + }, + "31f006f3494ed6c16eb92aaf9044fa8abb5fd5a3": { + "balance": "500000000000000000000" + }, + "cdea386f9d0fd804d02818f237b7d9fa7646d35e": { + "balance": "3012139000000000000000" + }, + "d45b3341e8f15c80329320c3977e3b90e7826a7e": { + "balance": "500000000000000000000" + }, + "0b649da3b96a102cdc6db652a0c07d65b1e443e6": { + "balance": "2000000000000000000000" + }, + "0a58fddd71898de773a74fdae45e7bd84ef43646": { + "balance": "20000000000000000000" + }, + "0256149f5b5063bea14e15661ffb58f9b459a957": { + "balance": "704000000000000000000" + }, + "4438e880cb2766b0c1ceaec9d2418fceb952a044": { + "balance": "133712000000000000000" + }, + "9ed80eda7f55054db9fb5282451688f26bb374c1": { + "balance": "300000000000000000000" + }, + "8dab948ae81da301d972e3f617a912e5a753712e": { + "balance": "400000000000000000000" + }, + "5b5d8c8eed6c85ac215661de026676823faa0a0c": { + "balance": "20000000000000000000000" + }, + "46722a36a01e841d03f780935e917d85d5a67abd": { + "balance": "14900000000000000000" + }, + "d4b8bdf3df9a51b0b91d16abbea05bb4783c8661": { + "balance": "1000000000000000000000" + }, + "98f6b8e6213dbc9a5581f4cce6655f95252bdb07": { + "balance": "319968000000000000000" + }, + "3599493ce65772cf93e98af1195ec0955dc98002": { + "balance": "1500048000000000000000" + }, + "ecab5aba5b828de1705381f38bc744b32ba1b437": { + "balance": "940000000000000000000" + }, + "9a82826d3c29481dcc2bd2950047e8b60486c338": { + "balance": "20000000000000000000000" + }, + "6c474bc66a54780066aa4f512eefa773abf919c7": { + "balance": "94000000000000000000" + }, + "d5903e9978ee20a38c3f498d63d57f31a39f6a06": { + "balance": "10380000000000000000000" + }, + "341480cc8cb476f8d01ff30812e7c70e05afaf5d": { + "balance": "2000000000000000000000" + }, + "af771039345a343001bc0f8a5923b126b60d509c": { + "balance": "985000000000000000000" + }, + "b5a4679685fa14196c2e9230c8c4e33bffbc10e2": { + "balance": "1400000000000000000000" + }, + "2a400dff8594de7228b4fd15c32322b75bb87da8": { + "balance": "95810000000000000000" + }, + "a1336dfb96b6bcbe4b3edf3205be5723c90fad52": { + "balance": "5000000000000000000000" + }, + "e9b1f1fca3fa47269f21b061c353b7f5e96d905a": { + "balance": "500000000000000000000" + }, + "0ee414940487fd24e390378285c5d7b9334d8b65": { + "balance": "2680000000000000000000" + }, + "6ab5b4c41cddb829690c2fda7f20c85e629dd5d5": { + "balance": "1860000000000000000000" + }, + "dd63042f25ed32884ad26e3ad959eb94ea36bf67": { + "balance": "21340000000000000000000" + }, + "c0b3f244bca7b7de5b48a53edb9cbeab0b6d88c0": { + "balance": "5820000000000000000000" + }, + "ed1a5c43c574d4e934299b24f1472cdc9fd6f010": { + "balance": "200000000000000000000" + }, + "b2d9ab9664bcf6df203c346fc692fd9cbab9205e": { + "balance": "438000000000000000000" + }, + "ede8c2cb876fbe8a4cca8290361a7ea01a69fdf8": { + "balance": "7813091000000000000000" + }, + "6a7c252042e7468a3ff773d6450bba85efa26391": { + "balance": "500000000000000000000" + }, + "a106e6923edd53ca8ed650968a9108d6ccfd9670": { + "balance": "9499935000000000000000" + }, + "031e25db516b0f099faebfd94f890cf96660836b": { + "balance": "2000000000000000000000" + }, + "7fdbc3a844e40d96b2f3a635322e6065f4ca0e84": { + "balance": "2000000000000000000000" + }, + "df47a61b72535193c561cccc75c3f3ce0804a20e": { + "balance": "398000000000000000000" + }, + "ed31305c319f9273d3936d8f5b2f71e9b1b22963": { + "balance": "100000000000000000000" + }, + "a6b2d573297360102c07a18fc21df2e7499ff4eb": { + "balance": "4011000000000000000000" + }, + "f68464bf64f2411356e4d3250efefe5c50a5f65b": { + "balance": "20000000000000000000" + }, + "927cc2bfda0e088d02eff70b38b08aa53cc30941": { + "balance": "1852700000000000000000" + }, + "41cb9896445f70a10a14215296daf614e32cf4d5": { + "balance": "1910000000000000000000" + }, + "3ad70243d88bf0400f57c8c1fd57811848af162a": { + "balance": "860000000000000000000" + }, + "63b9754d75d12d384039ec69063c0be210d5e0e3": { + "balance": "2694055000000000000000" + }, + "ad1799aad7602b4540cd832f9db5f11150f1687a": { + "balance": "2000000000000000000000" + }, + "a8b65ba3171a3f77a6350b9daf1f8d55b4d201eb": { + "balance": "745000000000000000000" + }, + "ad0a4ae478e9636e88c604f242cf5439c6d45639": { + "balance": "3520000000000000000000" + }, + "4cd0b0a6436362595ceade052ebc9b929fb6c6c0": { + "balance": "2000000000000000000000" + }, + "c1d4af38e9ba799040894849b8a8219375f1ac78": { + "balance": "20000000000000000000000" + }, + "49ddee902e1d0c99d1b11af3cc8a96f78e4dcf1a": { + "balance": "199358000000000000000" + }, + "ae842210f44d14c4a4db91fc9d3b3b50014f7bf7": { + "balance": "4000000000000000000000" + }, + "10a1c42dc1ba746986b985a522a73c93eae64c63": { + "balance": "1000000000000000000000" + }, + "5103bc09933e9921fd53dc536f11f05d0d47107d": { + "balance": "4000000000000000000000" + }, + "c88eec54d305c928cc2848c2fee23531acb96d49": { + "balance": "1999946000000000000000" + }, + "9a2ce43b5d89d6936b8e8c354791b8afff962425": { + "balance": "2000000000000000000000" + }, + "562020e3ed792d2f1835fe5f55417d5111460c6a": { + "balance": "20000000000000000000000" + }, + "ed16ce39feef3bd7f5d162045e0f67c0f00046bb": { + "balance": "20000000000000000000" + }, + "ab948a4ae3795cbca13126e19253bdc21d3a8514": { + "balance": "200000000000000000000" + }, + "c12b7f40df9a2f7bf983661422ab84c9c1f50858": { + "balance": "8000000000000000000000" + }, + "62e6b2f5eb94fa7a43831fc87e254a3fe3bf8f89": { + "balance": "250000000000000000000" + }, + "423bca47abc00c7057e3ad34fca63e375fbd8b4a": { + "balance": "18000000000000000000000" + }, + "5ff326cd60fd136b245e29e9087a6ad3a6527f0d": { + "balance": "1880000000000000000000" + }, + "79ffb4ac13812a0b78c4a37b8275223e176bfda5": { + "balance": "17300000000000000000" + }, + "f757fc8720d3c4fa5277075e60bd5c411aebd977": { + "balance": "2000000000000000000000" + }, + "0bdbc54cc8bdbbb402a08911e2232a5460ce866b": { + "balance": "3000000000000000000000" + }, + "9ee9760cc273d4706aa08375c3e46fa230aff3d5": { + "balance": "8950000000000000000000" + }, + "d23a24d7f9468343c143a41d73b88f7cbe63be5e": { + "balance": "200000000000000000000" + }, + "46d80631284203f6288ecd4e5758bb9d41d05dbe": { + "balance": "2000000000000000000000" + }, + "3f4cd1399f8a34eddb9a17a471fc922b5870aafc": { + "balance": "200000000000000000000" + }, + "44c54eaa8ac940f9e80f1e74e82fc14f1676856a": { + "balance": "7880000000000000000000" + }, + "aec27ff5d7f9ddda91183f46f9d52543b6cd2b2f": { + "balance": "450000000000000000000" + }, + "203c6283f20df7bc86542fdfb4e763ecdbbbeef5": { + "balance": "25000000000000000000000" + }, + "bcaf347918efb2d63dde03e39275bbe97d26df50": { + "balance": "100000000000000000000" + }, + "974d0541ab4a47ec7f75369c0069b64a1b817710": { + "balance": "400000000000000000000" + }, + "5da54785c9bd30575c89deb59d2041d20a39e17b": { + "balance": "1967031000000000000000" + }, + "1fb463a0389983df7d593f7bdd6d78497fed8879": { + "balance": "20000000000000000000" + }, + "6e1ea4b183e252c9bb7767a006d4b43696cb8ae9": { + "balance": "294245000000000000000" + }, + "c2aa74847e86edfdd3f3db22f8a2152feee5b7f7": { + "balance": "2048852000000000000000" + }, + "a13b9d82a99b3c9bba5ae72ef2199edc7d3bb36c": { + "balance": "1999944000000000000000" + }, + "5135fb8757600cf474546252f74dc0746d06262c": { + "balance": "2000000000000000000000" + }, + "43e7ec846358d7d0f937ad1c350ba069d7bf72bf": { + "balance": "118800000000000000000" + }, + "f2ed3e77254acb83231dc0860e1a11242ba627db": { + "balance": "1980000000000000000000" + }, + "c0a02ab94ebe56d045b41b629b98462e3a024a93": { + "balance": "100000000000000000000" + }, + "f21549bdd1487912f900a7523db5f7626121bba3": { + "balance": "10000000000000000000000" + }, + "886d0a9e17c9c095af2ea2358b89ec705212ee94": { + "balance": "28000000000000000000" + }, + "211b29cefc79ae976744fdebcebd3cbb32c51303": { + "balance": "14000000000000000000000" + }, + "b8c2703d8c3f2f44c584bc10e7c0a6b64c1c097e": { + "balance": "5550000000000000000000" + }, + "ec30addd895b82ee319e54fb04cb2bb03971f36b": { + "balance": "2000000000000000000000" + }, + "b71b62f4b448c02b1201cb5e394ae627b0a560ee": { + "balance": "500000000000000000000" + }, + "e1334e998379dfe983177062791b90f80ee22d8d": { + "balance": "500000000000000000000" + }, + "1d633097a85225a1ff4321b12988fdd55c2b3844": { + "balance": "4000000000000000000000" + }, + "8bd8d4c4e943f6c8073921dc17e3e8d7a0761627": { + "balance": "2933330000000000000000" + }, + "a5d96e697d46358d119af7819dc7087f6ae47fef": { + "balance": "14605131000000000000000" + }, + "d0809498c548047a1e2a2aa6a29cd61a0ee268bd": { + "balance": "2000000000000000000000" + }, + "3cd6b7593cbee77830a8b19d0801958fcd4bc57a": { + "balance": "500000000000000000000" + }, + "ead4d2eefb76abae5533961edd11400406b298fc": { + "balance": "3880000000000000000000" + }, + "6331028cbb5a21485bc51b565142993bdb2582a9": { + "balance": "534800000000000000000" + }, + "163bad4a122b457d64e8150a413eae4d07023e6b": { + "balance": "18800000000000000000" + }, + "c522e20fbf04ed7f6b05a37b4718d6fce0142e1a": { + "balance": "4000000000000000000000" + }, + "2d9bad6f1ee02a70f1f13def5cccb27a9a274031": { + "balance": "1790000000000000000000" + }, + "5ed0d6338559ef44dc7a61edeb893fa5d83fa1b5": { + "balance": "220000000000000000000" + }, + "ec8c1d7b6aaccd429db3a91ee4c9eb1ca4f6f73c": { + "balance": "4250000000000000000000" + }, + "3896ad743579d38e2302454d1fb6e2ab69e01bfd": { + "balance": "1880000000000000000000" + }, + "e73ccf436725c151e255ccf5210cfce5a43f13e3": { + "balance": "19982000000000000000" + }, + "9483d98f14a33fdc118d403955c29935edfc5f70": { + "balance": "459600000000000000000" + }, + "1cfcf7517f0c08459720942b647ad192aa9c8828": { + "balance": "800000000000000000000" + }, + "8d378f0edc0bb0f0686d6a20be6a7692c4fa24b8": { + "balance": "100000000000000000000" + }, + "06f68de3d739db41121eacf779aada3de8762107": { + "balance": "28000000000000000000" + }, + "9909650dd5b1397b8b8b0eb69499b291b0ad1213": { + "balance": "200000000000000000000" + }, + "b66675142e3111a1c2ea1eb2419cfa42aaf7a234": { + "balance": "1000000000000000000000" + }, + "7836f7ef6bc7bd0ff3acaf449c84dd6b1e2c939f": { + "balance": "4142296000000000000000" + }, + "3ddedbe48923fbf9e536bf9ffb0747c9cdd39eef": { + "balance": "16100000000000000000000" + }, + "c47d610b399250f70ecf1389bab6292c91264f23": { + "balance": "288800000000000000000" + }, + "51a6d627f66a8923d88d6094c4715380d3057cb6": { + "balance": "1152044000000000000000" + }, + "6c0cc917cbee7d7c099763f14e64df7d34e2bf09": { + "balance": "250000000000000000000" + }, + "aaaae68b321402c8ebc13468f341c63c0cf03fce": { + "balance": "1520000000000000000000" + }, + "819cdaa5303678ef7cec59d48c82163acc60b952": { + "balance": "14523448000000000000000" + }, + "d071192966eb69c3520fca3aa4dd04297ea04b4e": { + "balance": "110000000000000000000" + }, + "e53425d8df1f11c341ff58ae5f1438abf1ca53cf": { + "balance": "322000000000000000000" + }, + "8ffe322997b8e404422d19c54aadb18f5bc8e9b7": { + "balance": "3940000000000000000000" + }, + "305f78d618b990b4295bac8a2dfa262884f804ea": { + "balance": "4000000000000000000000" + }, + "274d69170fe7141401882b886ac4618c6ae40edb": { + "balance": "955000000000000000000" + }, + "69c94e07c4a9be3384d95dfa3cb9290051873b7b": { + "balance": "70000000000000000000" + }, + "859c600cf13d1d0273d5d1da3cd789e495899f27": { + "balance": "2674000000000000000000" + }, + "c06cebbbf7f5149a66f7eb976b3e47d56516da2f": { + "balance": "2000000000000000000000" + }, + "37bbc47212d82fcb5ee08f5225ecc2041ad2da7d": { + "balance": "3280000000000000000000" + }, + "11e7997edd904503d77da6038ab0a4c834bbd563": { + "balance": "388000000000000000000" + }, + "d333627445f2d787901ef33bb2a8a3675e27ffec": { + "balance": "400000000000000000000" + }, + "16a58e985dccd707a594d193e7cca78b5d027849": { + "balance": "1360000000000000000000" + }, + "f8ae857b67a4a2893a3fbe7c7a87ff1c01c6a6e7": { + "balance": "4000000000000000000000" + }, + "491561db8b6fafb9007e62d050c282e92c4b6bc8": { + "balance": "30000000000000000000000" + }, + "21df1ec24b4e4bfe79b0c095cebae198f291fbd1": { + "balance": "20000000000000000000000" + }, + "e208812a684098f3da4efe6aba256256adfe3fe6": { + "balance": "2000000000000000000000" + }, + "f4ec8e97a20aa5f8dd206f55207e06b813df2cc0": { + "balance": "200000000000000000000" + }, + "29eb7eefdae9feb449c63ff5f279d67510eb1422": { + "balance": "19400000000000000000" + }, + "0d678706d037187f3e22e6f69b99a592d11ebc59": { + "balance": "1580000000000000000000" + }, + "de6d363106cc6238d2f092f0f0372136d1cd50c6": { + "balance": "5348000000000000000000" + }, + "c8710d7e8b5a3bd69a42fe0fa8b87c357fddcdc8": { + "balance": "4000000000000000000000" + }, + "5267f4d41292f370863c90d793296903843625c7": { + "balance": "1400000000000000000000" + }, + "4cda41dd533991290794e22ae324143e309b3d3d": { + "balance": "2400000000000000000000" + }, + "f8a50cee2e688ceee3aca4d4a29725d4072cc483": { + "balance": "2000000000000000000000" + }, + "5ed3bbc05240e0d399eb6ddfe60f62de4d9509af": { + "balance": "193999806000000000000000" + }, + "0befb54707f61b2c9fb04715ab026e1bb72042bd": { + "balance": "4000000000000000000000" + }, + "cab9a301e6bd46e940355028eccd40ce4d5a1ac3": { + "balance": "400000000000000000000" + }, + "64672da3ab052821a0243d1ce4b6e0a36517b8eb": { + "balance": "200000000000000000000" + }, + "eac0827eff0c6e3ff28a7d4a54f65cb7689d7b99": { + "balance": "2856500000000000000000" + }, + "f4b6cdcfcb24230b337d770df6034dfbd4e1503f": { + "balance": "19000000000000000000000" + }, + "7be2f7680c802da6154c92c0194ae732517a7169": { + "balance": "18200000000000000000" + }, + "869f1aa30e4455beb1822091de5cadec79a8f946": { + "balance": "8000000000000000000000" + }, + "c4681e73bb0e32f6b726204831ff69baa4877e32": { + "balance": "1820000000000000000000" + }, + "962cd22a8edf1e4f4e55b4b15ddbfb5d9d541971": { + "balance": "2000000000000000000000" + }, + "131df8d330eb7cc7147d0a55576f05de8d26a8b7": { + "balance": "188000000000000000000" + }, + "19f99f2c0b46ce8906875dc9f90ae104dae35594": { + "balance": "4507300000000000000000" + }, + "91bb3f79022bf3c453f4ff256e269b15cf2c9cbd": { + "balance": "1519000000000000000000" + }, + "7301dc4cf26d7186f2a11bf8b08bf229463f64a3": { + "balance": "2000000000000000000000" + }, + "7cbca88fca6a0060b960985c9aa1b02534dc2208": { + "balance": "462500000000000000000" + }, + "f3c1abd29dc57b41dc192d0e384d021df0b4f6d4": { + "balance": "2798000000000000000000" + }, + "5d32f6f86e787ff78e63d78b0ef95fe6071852b8": { + "balance": "401100000000000000000" + }, + "1678c5f2a522393225196361894f53cc752fe2f3": { + "balance": "1936000000000000000000" + }, + "1cf04cb14380059efd3f238b65d5beb86afa14d8": { + "balance": "20000000000000000000" + }, + "52e1731350f983cc2c4189842fde0613fad50ce1": { + "balance": "11640000000000000000000" + }, + "d0b11d6f2bce945e0c6a5020c3b52753f803f9d1": { + "balance": "200000000000000000000" + }, + "409bd75085821c1de70cdc3b11ffc3d923c74010": { + "balance": "4000000000000000000000" + }, + "0bb7160aba293762f8734f3e0326ffc9a4cac190": { + "balance": "1000000000000000000000" + }, + "7aad4dbcd3acf997df93586956f72b64d8ad94ee": { + "balance": "4000000000000000000000" + }, + "2dec98329d1f96c3a59caa7981755452d4da49d5": { + "balance": "200000000000000000000" + }, + "c18ab467feb5a0aadfff91230ff056464d78d800": { + "balance": "2000000000000000000000" + }, + "c90c3765156bca8e4897ab802419153cbe5225a9": { + "balance": "200000000000000000000" + }, + "85c8f3cc7a354feac99a5e7bfe7cdfa351cfe355": { + "balance": "400000000000000000000" + }, + "f4fc4d39bc0c2c4068a36de50e4ab4d4db7e340a": { + "balance": "25380000000000000000" + }, + "f50abbd4aa45d3eb88515465a8ba0b310fd9b521": { + "balance": "6685000000000000000000" + }, + "4d200110124008d56f76981256420c946a6ff45c": { + "balance": "199955000000000000000" + }, + "f4ba6a46d55140c439cbcf076cc657136262f4f8": { + "balance": "2000000000000000000000" + }, + "fa7adf660b8d99ce15933d7c5f072f3cbeb99d33": { + "balance": "5910000000000000000000" + }, + "84503334630d77f74147f68b2e086613c8f1ade9": { + "balance": "1600000000000000000000" + }, + "31ed858788bda4d5270992221cc04206ec62610d": { + "balance": "1176000000000000000000" + }, + "bfbca418d3529cb393081062032a6e1183c6b2dc": { + "balance": "8000000000000000000000" + }, + "8263ece5d709e0d7ae71cca868ed37cd2fef807b": { + "balance": "990000000000000000000" + }, + "23ba3864da583dab56f420873c37679690e02f00": { + "balance": "9800000000000000000000" + }, + "cedcb3a1d6843fb6bef643617deaf38f8e98dd5f": { + "balance": "477500000000000000000" + }, + "8fac748f784a0fed68dba43319b42a75b4649c6e": { + "balance": "910000000000000000000" + }, + "18b8bcf98321da61fb4e3eacc1ec5417272dc27e": { + "balance": "880000000000000000000" + }, + "776943ffb2ef5cdd35b83c28bc046bd4f4677098": { + "balance": "3000000000000000000000" + }, + "fb8113f94d9173eefd5a3073f516803a10b286ae": { + "balance": "80000000000000000000" + }, + "3e8349b67f5745449f659367d9ad4712db5b895a": { + "balance": "1820000000000000000000" + }, + "79cfa9780ae6d87b2c31883f09276986c89a6735": { + "balance": "1000000000000000000000" + }, + "5006fe4c22173980f00c74342b39cd231c653129": { + "balance": "2000000000000000000000" + }, + "13848b46ea75beb7eaa85f59d866d77fd24cf21a": { + "balance": "50000000000000000000000" + }, + "d64a2d50f8858537188a24e0f50df1681ab07ed7": { + "balance": "38800000000000000000000" + }, + "4f9ce2af9b8c5e42c6808a3870ec576f313545d1": { + "balance": "10000000000000000000000" + }, + "8764d02722000996ecd475b433298e9f540b05bf": { + "balance": "200000000000000000000" + }, + "3b7c77dbe95dc2602ce3269a9545d04965fefdbd": { + "balance": "2000000000000000000000" + }, + "c9dcbb056f4db7d9da39936202c5bd8230b3b477": { + "balance": "20000000000000000000000" + }, + "9ecbabb0b22782b3754429e1757aaba04b81189f": { + "balance": "823743000000000000000" + }, + "831c44b3084047184b2ad218680640903750c45d": { + "balance": "1970000000000000000000" + }, + "ff8eb07de3d49d9d52bbe8e5b26dbe1d160fa834": { + "balance": "3986000000000000000000" + }, + "8ccf3aa21ab742576ad8c422f71bb188591dea8a": { + "balance": "1000000000000000000000" + }, + "ddac312a9655426a9c0c9efa3fd82559ef4505bf": { + "balance": "401100000000000000000" + }, + "9a3e2b1bf346dd070b027357feac44a4b2c97db8": { + "balance": "10000000000000000000000" + }, + "69d39d510889e552a396135bfcdb06e37e387633": { + "balance": "4000000000000000000000" + }, + "83a3148833d9644984f7c475a7850716efb480ff": { + "balance": "3400000000000000000000" + }, + "62b4a9226e61683c72c183254690daf511b4117a": { + "balance": "260000000000000000000" + }, + "50763add868fd7361178342fc055eaa2b95f6846": { + "balance": "66838000000000000000" + }, + "91898eab8c05c0222883cd4db23b7795e1a24ad7": { + "balance": "2000000000000000000000" + }, + "066647cfc85d23d37605573d208ca154b244d76c": { + "balance": "10000000000000000000000" + }, + "aaf9ee4b886c6d1e95496fd274235bf4ecfcb07d": { + "balance": "1400000000000000000000" + }, + "06860a93525955ff624940fadcffb8e149fd599c": { + "balance": "1999800000000000000000" + }, + "e81c2d346c0adf4cc56708f6394ba6c8c8a64a1e": { + "balance": "2000000000000000000000" + }, + "41a8e236a30e6d63c1ff644d132aa25c89537e01": { + "balance": "20000000000000000000" + }, + "6a679e378fdce6bfd97fe62f043c6f6405d79e99": { + "balance": "4000000000000000000000" + }, + "933436c8472655f64c3afaaf7c4c621c83a62b38": { + "balance": "1000000000000000000000" + }, + "abe07ced6ac5ddf991eff6c3da226a741bd243fe": { + "balance": "10000000000000000000000" + }, + "bb56a404723cff20d0685488b05a02cdc35aacaa": { + "balance": "20000000000000000000" + }, + "0d551ec1a2133c981d5fc6a8c8173f9e7c4f47af": { + "balance": "2000000000000000000000" + }, + "23376ecabf746ce53321cf42c86649b92b67b2ff": { + "balance": "2000000000000000000000" + }, + "644ba6c61082e989109f5c11d4b40e991660d403": { + "balance": "4000000000000000000000" + }, + "680d5911ed8dd9eec45c060c223f89a7f620bbd5": { + "balance": "20000000000000000000000" + }, + "cb1bb6f1da5eb10d4899f7e61d06c1b00fdfb52d": { + "balance": "1038000000000000000000" + }, + "303a30ac4286ae17cf483dad7b870c6bd64d7b4a": { + "balance": "500000000000000000000" + }, + "7b0b31ff6e24745ead8ed9bb85fc0bf2fe1d55d4": { + "balance": "800000000000000000000" + }, + "854691ce714f325ced55ce5928ce9ba12facd1b8": { + "balance": "4380000000000000000000" + }, + "a13cfe826d6d1841dcae443be8c387518136b5e8": { + "balance": "140000000000000000000000" + }, + "5fcd84546896dd081db1a320bd4d8c1dd1528c4c": { + "balance": "20000000000000000000" + }, + "3db5fe6a68bd3612ac15a99a61e555928eeceaf3": { + "balance": "1580000000000000000000" + }, + "7a79e30ff057f70a3d0191f7f53f761537af7dff": { + "balance": "400000000000000000000" + }, + "3d3fad49c9e5d2759c8e8e5a7a4d60a0dd135692": { + "balance": "20000000000000000000" + }, + "05a830724302bc0f6ebdaa1ebeeeb46e6ce00b39": { + "balance": "98500000000000000000" + }, + "e4b6ae22c7735f5b89f34dd77ad0975f0acc9181": { + "balance": "1000000000000000000000" + }, + "3f2dd55db7eab0ebee65b33ed8202c1e992e958b": { + "balance": "820000000000000000000" + }, + "395d6d255520a8db29abc47d83a5db8a1a7df087": { + "balance": "100000000000000000000" + }, + "1cc90876004109cd79a3dea866cb840ac364ba1b": { + "balance": "2000000000000000000000" + }, + "c83e9d6a58253beebeb793e6f28b054a58491b74": { + "balance": "281800000000000000000" + }, + "901d99b699e5c6911519cb2076b4c76330c54d22": { + "balance": "2000000000000000000000" + }, + "3a9132b7093d3ec42e1e4fb8cb31ecdd43ae773c": { + "balance": "2000000000000000000000" + }, + "b41eaf5d51a5ba1ba39bb418dbb54fab750efb1f": { + "balance": "1000000000000000000000" + }, + "aa493d3f4fb866491cf8f800efb7e2324ed7cfe5": { + "balance": "1700000000000000000000" + }, + "509982f56237ee458951047e0a2230f804e2e895": { + "balance": "17500000000000000000000" + }, + "316e92a91bbda68b9e2f98b3c048934e3cc0b416": { + "balance": "2000000000000000000000" + }, + "a3430e1f647f321ed34739562323c7d623410b56": { + "balance": "999942000000000000000" + }, + "fca43bbc23a0d321ba9e46b929735ce7d8ef0c18": { + "balance": "20000000000000000000" + }, + "ff45cb34c928364d9cc9d8bb00373474618f06f3": { + "balance": "100000000000000000000" + }, + "8c999591fd72ef7111efca7a9e97a2356b3b000a": { + "balance": "4084000000000000000000" + }, + "8579dadf1a395a3471e20b6f763d9a0ff19a3f6f": { + "balance": "4000000000000000000000" + }, + "c8d4e1599d03b79809e0130a8dc38408f05e8cd3": { + "balance": "2945500000000000000000" + }, + "2abce1808940cd4ef5b5e05285f82df7a9ab5e03": { + "balance": "9800000000000000000000" + }, + "0bb0c12682a2f15c9b5741b2385cbe41f034068e": { + "balance": "1500000000000000000000" + }, + "08b7bdcf944d5570838be70460243a8694485858": { + "balance": "2000000000000000000000" + }, + "c452e0e4b3d6ae06b836f032ca09db409ddfe0fb": { + "balance": "800000000000000000000" + }, + "48d4f2468f963fd79a006198bb67895d2d5aa4d3": { + "balance": "1400000000000000000000" + }, + "f9e7222faaf0f4da40c1c4a40630373a09bed7b6": { + "balance": "2865000000000000000000" + }, + "bf59aee281fa43fe97194351a9857e01a3b897b2": { + "balance": "600000000000000000000" + }, + "da0d4b7ef91fb55ad265f251142067f10376ced6": { + "balance": "20000000000000000000000" + }, + "2c6f5c124cc789f8bb398e3f889751bc4b602d9e": { + "balance": "24928000000000000000" + }, + "c85ef27d820403805fc9ed259fff64acb8d6346a": { + "balance": "2000000000000000000000" + }, + "9aa8308f42910e5ade09c1a5e282d6d91710bdbf": { + "balance": "200000000000000000000" + }, + "9e4cec353ac3e381835e3c0991f8faa5b7d0a8e6": { + "balance": "9999917000000000000000" + }, + "137cf341e8516c815814ebcd73e6569af14cf7bc": { + "balance": "1000000000000000000000" + }, + "889da662eb4a0a2a069d2bc24b05b4ee2e92c41b": { + "balance": "1663417000000000000000" + }, + "0998d8273115b56af43c505e087aff0676ed3659": { + "balance": "3999984000000000000000" + }, + "3e4d13c55a84e46ed7e9cb90fd355e8ad991e38f": { + "balance": "1000000000000000000000" + }, + "abc068b4979b0ea64a62d3b7aa897d73810dc533": { + "balance": "1970000000000000000000" + }, + "d8fdf546674738c984d8fab857880b3e4280c09e": { + "balance": "20000000000000000000" + }, + "aff161740a6d909fe99c59a9b77945c91cc91448": { + "balance": "60000000000000000000" + }, + "92ad1b3d75fba67d54663da9fc848a8ade10fa67": { + "balance": "2000000000000000000000" + }, + "819eb4990b5aba5547093da12b6b3c1093df6d46": { + "balance": "1000000000000000000000" + }, + "643d9aeed4b180947ed2b9207cce4c3ddc55e1f7": { + "balance": "200000000000000000000" + }, + "ab3e62e77a8b225e411592b1af300752fe412463": { + "balance": "9850000000000000000000" + }, + "650b425555e4e4c51718146836a2c1ee77a5b421": { + "balance": "20000000000000000000000" + }, + "ba8e46d69d2e2343d86c60d82cf42c2041a0c1c2": { + "balance": "100000000000000000000" + }, + "f9570e924c95debb7061369792cf2efec2a82d5e": { + "balance": "20000000000000000000" + }, + "4dc4bf5e7589c47b28378d7503cf96488061dbbd": { + "balance": "1760000000000000000000" + }, + "3d7ea5bf03528100ed8af8aed2653e921b6e6725": { + "balance": "1000000000000000000000" + }, + "a02bde6461686e19ac650c970d0672e76dcb4fc2": { + "balance": "8865000000000000000000" + }, + "b0e760bb07c081777345e0578e8bc898226d4e3b": { + "balance": "2000000000000000000000" + }, + "979cbf21dfec8ace3f1c196d82df962534df394f": { + "balance": "2832860000000000000000" + }, + "9f8245c3ab7d173164861cd3991b94f1ba40a93a": { + "balance": "2860000000000000000000" + }, + "c25cf826550c8eaf10af2234fef904ddb95213be": { + "balance": "1000000000000000000000" + }, + "967bfaf76243cdb9403c67d2ceefdee90a3feb73": { + "balance": "970582000000000000000" + }, + "0b2113504534642a1daf102eee10b9ebde76e261": { + "balance": "2733351000000000000000" + }, + "74bc4a5e2045f4ff8db184cf3a9b0c065ad807d2": { + "balance": "2000000000000000000000" + }, + "f1da40736f99d5df3b068a5d745fafc6463fc9b1": { + "balance": "121546000000000000000" + }, + "0fa6c7b0973d0bae2940540e247d3627e37ca347": { + "balance": "1000000000000000000000" + }, + "72b05962fb2ad589d65ad16a22559eba1458f387": { + "balance": "133700000000000000000" + }, + "6ceae3733d8fa43d6cd80c1a96e8eb93109c83b7": { + "balance": "298000000000000000000" + }, + "28eaea78cd4d95faecfb68836eafe83520f3bbb7": { + "balance": "200000000000000000000" + }, + "f49f6f9baabc018c8f8e119e0115f491fc92a8a4": { + "balance": "10000000000000000000000" + }, + "833316985d47742bfed410604a91953c05fb12b0": { + "balance": "2000000000000000000000" + }, + "ead75016e3a0815072b6b108bcc1b799acf0383e": { + "balance": "2000000000000000000000" + }, + "0032403587947b9f15622a68d104d54d33dbd1cd": { + "balance": "77500000000000000000" + }, + "8f64b9c1246d857831643107d355b5c75fef5d4f": { + "balance": "1999944000000000000000" + }, + "15dcafcc2bace7b55b54c01a1c514626bf61ebd8": { + "balance": "9400000000000000000000" + }, + "6886ada7bbb0617bda842191c68c922ea3a8ac82": { + "balance": "1160000000000000000000" + }, + "f736dc96760012388fe88b66c06efe57e0d7cf0a": { + "balance": "2100000000000000000000" + }, + "0b288a5a8b75f3dc4191eb0457e1c83dbd204d25": { + "balance": "4853000000000000000000" + }, + "56b6c23dd2ec90b4728f3bb2e764c3c50c85f144": { + "balance": "1000000000000000000000" + }, + "6310b020fd98044957995092090f17f04e52cdfd": { + "balance": "1580000000000000000000" + }, + "b0baeb30e313776c4c6d247402ba4167afcda1cc": { + "balance": "1970000000000000000000" + }, + "7641f7d26a86cddb2be13081810e01c9c83c4b20": { + "balance": "13370000000000000000" + }, + "07a8dadec142571a7d53a4297051786d072cba55": { + "balance": "22729000000000000000" + }, + "cc73dd356b4979b579b401d4cc7a31a268ddce5a": { + "balance": "500000000000000000000" + }, + "adf1acfe99bc8c14b304c8d905ba27657b8a7bc4": { + "balance": "20000000000000000000000" + }, + "72dabb5b6eed9e99be915888f6568056381608f8": { + "balance": "208433000000000000000" + }, + "9de20ae76aa08263b205d5142461961e2408d266": { + "balance": "252000000000000000000" + }, + "9d4ff989b7bed9ab109d10c8c7e55f02d76734ad": { + "balance": "1000000000000000000000" + }, + "e58dd23238ee6ea7c2138d385df500c325f376be": { + "balance": "1820000000000000000000" + }, + "4bd6dd0cff23400e1730ba7b894504577d14e74a": { + "balance": "206028000000000000000000" + }, + "35147430c3106500e79fa2f502462e94703c23b1": { + "balance": "1999944000000000000000" + }, + "c0ae14d724832e2fce2778de7f7b8daf7b12a93e": { + "balance": "20000000000000000000" + }, + "b57413060af3f14eb479065f1e9d19b3757ae8cc": { + "balance": "40000000000000000000" + }, + "7d04d2edc058a1afc761d9c99ae4fc5c85d4c8a6": { + "balance": "314807840000000000000000" + }, + "1c94d636e684eb155895ce6db4a2588fba1d001b": { + "balance": "2000000000000000000000" + }, + "c721b2a7aa44c21298e85039d00e2e460e670b9c": { + "balance": "140800000000000000000" + }, + "2d89a8006a4f137a20dc2bec46fe2eb312ea9654": { + "balance": "200000000000000000000" + }, + "646afba71d849e80c0ed59cac519b278e7f7abe4": { + "balance": "1000000000000000000000" + }, + "71f2cdd1b046e2da2fbb5a26723422b8325e25a3": { + "balance": "99960000000000000000" + }, + "2c9fa72c95f37d08e9a36009e7a4b07f29bad41a": { + "balance": "16100000000000000000" + }, + "848fbd29d67cf4a013cb02a4b176ef244e9ee68d": { + "balance": "20116000000000000000" + }, + "68190ca885da4231874c1cfb42b1580a21737f38": { + "balance": "3820000000000000000000" + }, + "9adf458bff3599eee1a26398853c575bc38c6313": { + "balance": "280000000000000000000" + }, + "b72220ade364d0369f2d2da783ca474d7b9b34ce": { + "balance": "499986000000000000000" + }, + "38e2af73393ea98a1d993a74df5cd754b98d529a": { + "balance": "1790000000000000000000" + }, + "4d38d90f83f4515c03cc78326a154d358bd882b7": { + "balance": "185000000000000000000" + }, + "aa8eb0823b07b0e6d20aadda0e95cf3835be192e": { + "balance": "32000000000000000000" + }, + "008639dabbe3aeac887b5dc0e43e13bcd287d76c": { + "balance": "310200000000000000000" + }, + "fa3a0c4b903f6ea52ea7ab7b8863b6a616ad6650": { + "balance": "20000000000000000000" + }, + "e26bf322774e18288769d67e3107deb7447707b8": { + "balance": "2000000000000000000000" + }, + "e061a4f2fc77b296d19ada238e49a5cb8ecbfa70": { + "balance": "4000000000000000000000" + }, + "b320834836d1dbfda9e7a3184d1ad1fd4320ccc0": { + "balance": "1000000000000000000000" + }, + "0ed3bb3a4eb554cfca97947d575507cdfd6d21d8": { + "balance": "547863000000000000000" + }, + "32fa0e86cd087dd68d693190f32d93310909ed53": { + "balance": "4000000000000000000000" + }, + "5b759fa110a31c88469f54d44ba303d57dd3e10f": { + "balance": "1683760000000000000000" + }, + "136f4907cab41e27084b9845069ff2fd0c9ade79": { + "balance": "4000000000000000000000" + }, + "3d89e505cb46e211a53f32f167a877bec87f4b0a": { + "balance": "25019000000000000000" + }, + "57a852fdb9b1405bf53ccf9508f83299d3206c52": { + "balance": "2000000000000000000000" + }, + "747abc9649056d3926044d28c3ad09ed17b67d70": { + "balance": "5000057000000000000000" + }, + "5c29f9e9a523c1f8669448b55c48cbd47c25e610": { + "balance": "964320000000000000000" + }, + "30a9da72574c51e7ee0904ba1f73a6b7b83b9b9d": { + "balance": "20200000000000000000" + }, + "220e2b92c0f6c902b513d9f1e6fab6a8b0def3d7": { + "balance": "800000000000000000000" + }, + "5af7c072b2c5acd71c76addcce535cf7f8f93585": { + "balance": "20000000000000000000" + }, + "81556db27349ab8b27004944ed50a46e941a0f5f": { + "balance": "3998000000000000000000" + }, + "987618c85656207c7bac1507c0ffefa2fb64b092": { + "balance": "64419000000000000000" + }, + "e0f372347c96b55f7d4306034beb83266fd90966": { + "balance": "400000000000000000000" + }, + "71784c105117c1f68935797fe159abc74e43d16a": { + "balance": "2001600000000000000000" + }, + "9284f96ddb47b5186ee558aa31324df5361c0f73": { + "balance": "16000000000000000000000" + }, + "a60c1209754f5d87b181da4f0817a81859ef9fd8": { + "balance": "50000000000000000000" + }, + "5afda9405c8e9736514574da928de67456010918": { + "balance": "6008500000000000000000" + }, + "6978696d5150a9a263513f8f74c696f8b1397cab": { + "balance": "6640000000000000000000" + }, + "a9ad1926bc66bdb331588ea8193788534d982c98": { + "balance": "30000000000000000000000" + }, + "e3f80b40fb83fb97bb0d5230af4f6ed59b1c7cc8": { + "balance": "1337000000000000000000" + }, + "e207578e1f4ddb8ff6d5867b39582d71b9812ac5": { + "balance": "3880000000000000000000" + }, + "86883d54cd3915e549095530f9ab1805e8c5432d": { + "balance": "4000000000000000000000" + }, + "6974c8a414ceaefd3c2e4dfdbef430568d9a960b": { + "balance": "334250000000000000000" + }, + "532d32b00f305bcc24dcef56817d622f34fb2c24": { + "balance": "1800000000000000000000" + }, + "761f8a3a2af0a8bdbe1da009321fb29764eb62a1": { + "balance": "10000000000000000000000" + }, + "4677b04e0343a32131fd6abb39b1b6156bba3d5b": { + "balance": "200000000000000000000" + }, + "ef69781f32ffce33346f2c9ae3f08493f3e82f89": { + "balance": "18200000000000000000" + }, + "e3b3d2c9bf570be6a2f72adca1862c310936a43c": { + "balance": "100100000000000000000" + }, + "d19caf39bb377fdf2cf19bd4fb52591c2631a63c": { + "balance": "1000000000000000000000" + }, + "5d68324bcb776d3ffd0bf9fea91d9f037fd6ab0f": { + "balance": "2000000000000000000000" + }, + "1c99fe9bb6c6d1066d912099547fd1f4809eacd9": { + "balance": "2000000000000000000000" + }, + "bbfe0a830cace87b7293993a7e9496ce64f8e394": { + "balance": "6000000000000000000000" + }, + "26c0054b700d3a7c2dcbe275689d4f4cad16a335": { + "balance": "2000000000000000000000" + }, + "7d7e7c61779adb7706c94d32409a2bb4e994bf60": { + "balance": "865992000000000000000" + }, + "d037d215d11d1df3d54fbd321cd295c5465e273b": { + "balance": "1400000000000000000000" + }, + "08166f02313feae18bb044e7877c808b55b5bf58": { + "balance": "1970000000000000000000" + }, + "781b1501647a2e06c0ed43ff197fccec35e1700b": { + "balance": "3000000000000000000000" + }, + "74316adf25378c10f576d5b41a6f47fa98fce33d": { + "balance": "336082000000000000000" + }, + "44e2fdc679e6bee01e93ef4a3ab1bcce012abc7c": { + "balance": "410231000000000000000" + }, + "178eaf6b8554c45dfde16b78ce0c157f2ee31351": { + "balance": "320000000000000000000" + }, + "cf923a5d8fbc3d01aa079d1cfe4b43ce071b1611": { + "balance": "2000000000000000000000" + }, + "0c28847e4f09dfce5f9b25af7c4e530f59c880fe": { + "balance": "1000000000000000000000" + }, + "54ce88275956def5f9458e3b95decacd484021a0": { + "balance": "2000000000000000000000" + }, + "9d4213339a01551861764c87a93ce8f85f87959a": { + "balance": "200000000000000000000" + }, + "e559b5fd337b9c5572a9bf9e0f2521f7d446dbe4": { + "balance": "200000000000000000000" + }, + "dcb03bfa6c1131234e56b7ea7c4f721487546b7a": { + "balance": "1337000000000000000000" + }, + "db6ff71b3db0928f839e05a7323bfb57d29c87aa": { + "balance": "910000000000000000000" + }, + "eb7c202b462b7cc5855d7484755f6e26ef43a115": { + "balance": "2000000000000000000000" + }, + "323486ca64b375474fb2b759a9e7a135859bd9f6": { + "balance": "400000000000000000000" + }, + "2c1df8a76f48f6b54bcf9caf56f0ee1cf57ab33d": { + "balance": "10118000000000000000000" + }, + "2cd87866568dd81ad47d9d3ad0846e5a65507373": { + "balance": "400000000000000000000" + }, + "8566610901aace38b83244f3a9c831306a67b9dc": { + "balance": "3256000000000000000000" + }, + "1c257ad4a55105ea3b58ed374b198da266c85f63": { + "balance": "10000000000000000000000" + }, + "cf4f1138f1bd6bf5b6d485cce4c1017fcb85f07d": { + "balance": "882038000000000000000" + }, + "c934becaf71f225f8b4a4bf7b197f4ac9630345c": { + "balance": "20000000000000000000000" + }, + "1e2bf4ba8e5ef18d37de6d6ad636c4cae489d0cc": { + "balance": "2000000000000000000000" + }, + "9d78a975b7db5e4d8e28845cfbe7e31401be0dd9": { + "balance": "1340000000000000000000" + }, + "16aa52cb0b554723e7060f21f327b0a68315fea3": { + "balance": "250000000000000000000" + }, + "97e28973b860c567402800fbb63ce39a048a3d79": { + "balance": "97000000000000000000" + }, + "4ac5acad000b8877214cb1ae00eac9a37d59a0fd": { + "balance": "4000000000000000000000" + }, + "01226e0ad8d62277b162621c62c928e96e0b9a8c": { + "balance": "2000000000000000000000" + }, + "479abf2da4d58716fd973a0d13a75f530150260a": { + "balance": "20000000000000000000" + }, + "31d81d526c195e3f10b5c6db52b5e59afbe0a995": { + "balance": "264000000000000000000" + }, + "749087ac0f5a97c6fad021538bf1d6cda18e0daa": { + "balance": "1000000000000000000000" + }, + "1565af837ef3b0bd4e2b23568d5023cd34b16498": { + "balance": "393284000000000000000" + }, + "997d6592a31589acc31b9901fbeb3cc3d65b3215": { + "balance": "2000000000000000000000" + }, + "9d207517422cc0d60de7c237097a4d4fce20940c": { + "balance": "500000000000000000000" + }, + "24b8b446debd1947955dd084f2c544933346d3ad": { + "balance": "4324135000000000000000" + }, + "107a03cf0842dbdeb0618fb587ca69189ec92ff5": { + "balance": "1970000000000000000000" + }, + "7f603aec1759ea5f07c7f8d41a1428fbbaf9e762": { + "balance": "20000000000000000000" + }, + "53a244672895480f4a2b1cdf7da5e5a242ec4dbc": { + "balance": "1000000000000000000000" + }, + "7db4c7d5b797e9296e6382f203693db409449d62": { + "balance": "400000000000000000000" + }, + "2ae82dab92a66389eea1abb901d1d57f5a7cca0b": { + "balance": "2000000000000000000000" + }, + "16bc40215abbd9ae5d280b95b8010b4514ff1292": { + "balance": "200000000000000000000" + }, + "bba4fac3c42039d828e742cde0efffe774941b39": { + "balance": "1999946000000000000000" + }, + "5431ca427e6165a644bae326bd09750a178c650d": { + "balance": "2000000000000000000000" + }, + "dcf33965531380163168fc11f67e89c6f1bc178a": { + "balance": "334885000000000000000" + }, + "65fd02d704a12a4dace9471b0645f962a89671c8": { + "balance": "28615000000000000000" + }, + "135d1719bf03e3f866312479fe338118cd387e70": { + "balance": "2000000000000000000000" + }, + "f3159866c2bc86bba40f9d73bb99f1eee57bb9d7": { + "balance": "1000000000000000000000" + }, + "e3a4621b66004588e31206f718cb00a319889cf0": { + "balance": "2000000000000000000000" + }, + "abcdbc8f1dd13af578d4a4774a62182bedf9f9be": { + "balance": "36660000000000000000" + }, + "9fbe066de57236dc830725d32a02aef9246c6c5e": { + "balance": "2000000000000000000000" + }, + "81cfad760913d3c322fcc77b49c2ae3907e74f6e": { + "balance": "197000000000000000000" + }, + "0ab59d390702c9c059db148eb4f3fcfa7d04c7e7": { + "balance": "18200000000000000000" + }, + "2c2db28c3309375eea3c6d72cd6d0eec145afcc0": { + "balance": "2000000000000000000000" + }, + "08306de51981e7aca1856859b7c778696a6b69f9": { + "balance": "3200000000000000000000" + }, + "f814799f6ddf4dcb29c7ee870e75f9cc2d35326d": { + "balance": "1000000000000000000000" + }, + "ee867d20916bd2e9c9ece08aa04385db667c912e": { + "balance": "50000000000000000000000" + }, + "97a86f01ce3f7cfd4441330e1c9b19e1b10606ef": { + "balance": "2000000000000000000000" + }, + "4c759813ad1386bed27ffae9e4815e3630cca312": { + "balance": "2000000000000000000000" + }, + "8f226096c184ebb40105e08dac4d22e1c2d54d30": { + "balance": "306552000000000000000" + }, + "13acada8980affc7504921be84eb4944c8fbb2bd": { + "balance": "1601600000000000000000" + }, + "122dcfd81addb97d1a0e4925c4b549806e9f3beb": { + "balance": "1514954000000000000000" + }, + "232f525d55859b7d4e608d20487faadb00293135": { + "balance": "4000000000000000000000" + }, + "6f7ac681d45e418fce8b3a1db5bc3be6f06c9849": { + "balance": "2000000000000000000000" + }, + "0c8692eeff2a53d6d1688ed56a9ddbbd68dabba1": { + "balance": "2000000000000000000000" + }, + "6a6337833f8f6a6bf10ca7ec21aa810ed444f4cb": { + "balance": "1028200000000000000000" + }, + "209377b6ad3fe101c9685b3576545c6b1684e73c": { + "balance": "1820000000000000000000" + }, + "560fc08d079f047ed8d7df75551aa53501f57013": { + "balance": "7600000000000000000000" + }, + "8e78f351457d016f4ad2755ec7424e5c21ba6d51": { + "balance": "146000000000000000000" + }, + "2ce11a92fad024ff2b3e87e3b542e6c60dcbd996": { + "balance": "4000000000000000000000" + }, + "8ab839aeaf2ad37cb78bacbbb633bcc5c099dc46": { + "balance": "2000000000000000000000" + }, + "673144f0ec142e770f4834fee0ee311832f3087b": { + "balance": "500038000000000000000" + }, + "ba8a63f3f40de4a88388bc50212fea8e064fbb86": { + "balance": "2000000000000000000000" + }, + "ee899b02cbcb3939cd61de1342d50482abb68532": { + "balance": "1760000000000000000000" + }, + "c2d9eedbc9019263d9d16cc5ae072d1d3dd9db03": { + "balance": "20000000000000000000000" + }, + "355c0c39f5d5700b41d375b3f17851dcd52401f9": { + "balance": "3979000000000000000000" + }, + "8179c80970182cc5b7d82a4df06ea94db63a25f3": { + "balance": "727432000000000000000" + }, + "b388b5dfecd2c5e4b596577c642556dbfe277855": { + "balance": "20000000000000000000" + }, + "a9e28337e6357193d9e2cb236b01be44b81427df": { + "balance": "2200000000000000000000" + }, + "04ba4bb87140022c214a6fac42db5a16dd954045": { + "balance": "1000000000000000000000" + }, + "67c926093e9b8927933810d98222d62e2b8206bb": { + "balance": "1910000000000000000000" + }, + "ed7346766e1a676d0d06ec821867a276a083bf31": { + "balance": "4012890000000000000000" + }, + "92558226b384626cad48e09d966bf1395ee7ea5d": { + "balance": "334250000000000000000" + }, + "bdf693f833c3fe471753184788eb4bfe4adc3f96": { + "balance": "1970000000000000000000" + }, + "4474299d0ee090dc90789a1486489c3d0d645e6d": { + "balance": "1000000000000000000000" + }, + "b1178ad47383c31c8134a1941cbcd474d06244e2": { + "balance": "1000000000000000000000" + }, + "979d681c617da16f21bcaca101ed16ed015ab696": { + "balance": "1880000000000000000000" + }, + "6b20c080606a79c73bd8e75b11717a4e8db3f1c3": { + "balance": "299720000000000000000" + }, + "b85218f342f8012eda9f274e63ce2152b2dcfdab": { + "balance": "3100000000000000000000" + }, + "530b61e42f39426d2408d40852b9e34ab5ebebc5": { + "balance": "267400000000000000000" + }, + "76afc225f4fa307de484552bbe1d9d3f15074c4a": { + "balance": "2998800000000000000000" + }, + "1e783e522ab7df0acaac9eeed3593039e5ac7579": { + "balance": "203435800000000000000000" + }, + "0f7bf6373f771a4601762c4dae5fbbf4fedd9cc9": { + "balance": "2000000000000000000000" + }, + "7a8797690ab77b5470bf7c0c1bba612508e1ac7d": { + "balance": "8865000000000000000000" + }, + "2a2ab6b74c7af1d9476bb5bcb4524797bedc3552": { + "balance": "1000000000000000000000" + }, + "523e140dc811b186dee5d6c88bf68e90b8e096fd": { + "balance": "2000000000000000000000" + }, + "ea8168fbf225e786459ca6bb18d963d26b505309": { + "balance": "500000000000000000000" + }, + "20ff3ede8cadb5c37b48cb14580fb65e23090a7b": { + "balance": "42000000000000000000000" + }, + "e482d255ede56b04c3e8df151f56e9ca62aaa8c2": { + "balance": "500000000000000000000" + }, + "2e0880a34596230720f05ac8f065af8681dcb6c2": { + "balance": "100000000000000000000000" + }, + "c674f28c8afd073f8b799691b2f0584df942e844": { + "balance": "2000000000000000000000" + }, + "b646df98b49442746b61525c81a3b04ba3106250": { + "balance": "1970000000000000000000" + }, + "d55c1c8dfbe1e02cacbca60fdbdd405b09f0b75f": { + "balance": "2000000000000000000000" + }, + "65ebaed27edb9dcc1957aee5f452ac2105a65c0e": { + "balance": "43531987000000000000000" + }, + "f079e1b1265f50e8c8a98ec0c7815eb3aeac9eb4": { + "balance": "20094000000000000000" + }, + "867eba56748a5904350d2ca2a5ce9ca00b670a9b": { + "balance": "20000000000000000000000" + }, + "51ee0cca3bcb10cd3e983722ced8493d926c0866": { + "balance": "999972000000000000000" + }, + "88d541c840ce43cefbaf6d19af6b9859b573c145": { + "balance": "170000000000000000000" + }, + "f851b010f633c40af1a8f06a73ebbaab65077ab5": { + "balance": "4400000000000000000000" + }, + "e0aa69365555b73f282333d1e30c1bbd072854e8": { + "balance": "7000000000000000000000" + }, + "c7b1c83e63203f9547263ef6282e7da33b6ed659": { + "balance": "18200000000000000000" + }, + "af06f5fa6d1214ec43967d1bd4dde74ab814a938": { + "balance": "88000000000000000000" + }, + "991173601947c2084a62d639527e961512579af9": { + "balance": "600000000000000000000" + }, + "7a381122bada791a7ab1f6037dac80432753baad": { + "balance": "10000000000000000000000" + }, + "e766f34ff16f3cfcc97321721f43ddf5a38b0cf4": { + "balance": "1550000000000000000000" + }, + "d785a8f18c38b9bc4ffb9b8fa8c7727bd642ee1c": { + "balance": "1000000000000000000000" + }, + "aebd4f205de799b64b3564b256d42a711d37ef99": { + "balance": "1177100000000000000000" + }, + "a2fa17c0fb506ce494008b9557841c3f641b8cae": { + "balance": "20000000000000000000" + }, + "a8aca748f9d312ec747f8b6578142694c7e9f399": { + "balance": "2000000000000000000000" + }, + "950c68a40988154d2393fff8da7ccda99614f72c": { + "balance": "4597943000000000000000" + }, + "075d15e2d33d8b4fa7dba8b9e607f04a261e340b": { + "balance": "1910000000000000000000" + }, + "3616d448985f5d32aefa8b93a993e094bd854986": { + "balance": "205400000000000000000" + }, + "4bb9655cfb2a36ea7c637a7b859b4a3154e26ebe": { + "balance": "16000000000000000000000" + }, + "84949dba559a63bfc845ded06e9f2d9b7f11ef24": { + "balance": "2000000000000000000000" + }, + "937563d8a80fd5a537b0e66d20a02525d5d88660": { + "balance": "2500000000000000000000" + }, + "b183ebee4fcb42c220e47774f59d6c54d5e32ab1": { + "balance": "1604266000000000000000" + }, + "21e5d77320304c201c1e53b261a123d0a1063e81": { + "balance": "86972000000000000000" + }, + "fa14b566234abee73042c31d21717182cba14aa1": { + "balance": "328000000000000000000" + }, + "2da617695009cc57d26ad490b32a5dfbeb934e5e": { + "balance": "20000000000000000000000" + }, + "3326b88de806184454c40b27f309d9dd6dcfb978": { + "balance": "17900000000000000000000" + }, + "95e6a54b2d5f67a24a4875af75107ca7ea9fd2fa": { + "balance": "1337000000000000000000" + }, + "8db58e406e202df9bc703c480bd8ed248d52a032": { + "balance": "2000000000000000000000" + }, + "f777361a3dd8ab62e5f1b9b047568cc0b555704c": { + "balance": "1000000000000000000000" + }, + "83a93b5ba41bf88720e415790cdc0b67b4af34c4": { + "balance": "200000000000000000000" + }, + "8a1cc5ac111c49bfcfd848f37dd768aa65c88802": { + "balance": "10000000000000000000000" + }, + "52214378b54004056a7cc08c891327798ac6b248": { + "balance": "15200000000000000000000" + }, + "ad80d865b85c34d2e6494b2e7aefea6b9af184db": { + "balance": "4000000000000000000000" + }, + "e7d6240620f42c5edbb2ede6aec43da4ed9b5757": { + "balance": "1000000000000000000000" + }, + "d0e35e047646e759f4517093d6408642517f084d": { + "balance": "3939507000000000000000" + }, + "9340345ca6a3eabdb77363f2586043f29438ce0b": { + "balance": "530922000000000000000" + }, + "6640ccf053555c130ae2b656647ea6e31637b9ab": { + "balance": "1970000000000000000000" + }, + "184d86f3466ae6683b19729982e7a7e1a48347b2": { + "balance": "10000000000000000000000" + }, + "84ec06f24700fe42414cb9897c154c88de2f6132": { + "balance": "1337000000000000000000" + }, + "d1e5e234a9f44266a4a6241a84d7a1a55ad5a7fe": { + "balance": "20000000000000000000000" + }, + "e8a9a41740f44f54c3688b53e1ddd42e43c9fe94": { + "balance": "4000000000000000000000" + }, + "6e3a51db743d334d2fe88224b5fe7c008e80e624": { + "balance": "106000000000000000000" + }, + "3e94df5313fa520570ef232bc3311d5f622ff183": { + "balance": "2000000000000000000000" + }, + "8957727e72cf629020f4e05edf799aa7458062d0": { + "balance": "2200000000000000000000" + }, + "cf5e0eacd1b39d0655f2f77535ef6608eb950ba0": { + "balance": "2000000000000000000000" + }, + "f4aaa3a6163e3706577b49c0767e948a681e16ee": { + "balance": "2000000000000000000000" + }, + "97f1fe4c8083e596212a187728dd5cf80a31bec5": { + "balance": "20000000000000000000" + }, + "57d5fd0e3d3049330ffcdcd020456917657ba2da": { + "balance": "1991240000000000000000" + }, + "49bdbc7ba5abebb6389e91a3285220d3451bd253": { + "balance": "1000000000000000000000" + }, + "ae126b382cf257fad7f0bc7d16297e54cc7267da": { + "balance": "300000000000000000000" + }, + "bbf8616d97724af3def165d0e28cda89b800009a": { + "balance": "114063000000000000000" + }, + "adb948b1b6fefe207de65e9bbc2de98e605d0b57": { + "balance": "2000000000000000000000" + }, + "8a217db38bc35f215fd92906be42436fe7e6ed19": { + "balance": "6000000000000000000000" + }, + "e28b062259e96eeb3c8d4104943f9eb325893cf5": { + "balance": "1337000000000000000000" + }, + "6a6b18a45a76467e2e5d5a2ef911c3e12929857b": { + "balance": "82000000000000000000000" + }, + "cb68ae5abe02dcf8cbc5aa719c25814651af8b85": { + "balance": "500000000000000000000" + }, + "4c7e2e2b77ad0cd6f44acb2861f0fb8b28750ef9": { + "balance": "20000000000000000000" + }, + "58ba1569650e5bbbb21d35d3e175c0d6b0c651a9": { + "balance": "500000000000000000000" + }, + "1eb4bf73156a82a0a6822080c6edf49c469af8b9": { + "balance": "1910000000000000000000" + }, + "4103299671d46763978fa4aa19ee34b1fc952784": { + "balance": "200000000000000000000" + }, + "e321bb4a946adafdade4571fb15c0043d39ee35f": { + "balance": "1575212000000000000000" + }, + "893608751d68d046e85802926673cdf2f57f7cb8": { + "balance": "19700000000000000000" + }, + "70fee08b00c6c2c04a3c625c1ff77caf1c32df01": { + "balance": "200000000000000000000" + }, + "7b0fea1176d52159333a143c294943da36bbddb4": { + "balance": "9380000000000000000000" + }, + "d331c823825a9e5263d052d8915d4dcde07a5c37": { + "balance": "564000000000000000000" + }, + "a45432a6f2ac9d56577b938a37fabac8cc7c461c": { + "balance": "1000000000000000000000" + }, + "764fc46d428b6dbc228a0f5f55c9508c772eab9f": { + "balance": "26000000000000000000000" + }, + "1a95a8a8082e4652e4170df9271cb4bb4305f0b2": { + "balance": "50000000000000000000" + }, + "08c9f1bfb689fdf804d769f82123360215aff93b": { + "balance": "1970000000000000000000" + }, + "1572cdfab72a01ce968e78f5b5448da29853fbdd": { + "balance": "5061500000000000000000" + }, + "379c7166849bc24a02d6535e2def13daeef8aa8d": { + "balance": "100000000000000000000" + }, + "e0a254ac09b9725bebc8e460431dd0732ebcabbf": { + "balance": "6000000000000000000000" + }, + "3225c1ca5f2a9c88156bb7d9cdc44a326653c214": { + "balance": "400000000000000000000" + }, + "84686c7bad762c54b667d59f90943cd14d117a26": { + "balance": "20000000000000000000" + }, + "3d5a8b2b80be8b35d8ecf789b5ed7a0775c5076c": { + "balance": "20000000000000000000" + }, + "2ccf80e21898125eb4e807cd82e09b9d28592f6e": { + "balance": "2000000000000000000000" + }, + "dde969aef34ea87ac299b7597e292b4a0155cc8a": { + "balance": "298819000000000000000" + }, + "19e94e620050aad766b9e1bad931238312d4bf49": { + "balance": "2396000000000000000000" + }, + "959f57fded6ae37913d900b81e5f48a79322c627": { + "balance": "255599000000000000000" + }, + "b9b0a3219a3288d9b35b091b14650b8fe23dce2b": { + "balance": "14000000000000000000000" + }, + "3575c770668a9d179f1ef768c293f80166e2aa3d": { + "balance": "474000000000000000000" + }, + "58f05b262560503ca761c61890a4035f4c737280": { + "balance": "8000000000000000000000" + }, + "3286d1bc657a312c8847d93cb3cb7950f2b0c6e3": { + "balance": "20000000000000000000000" + }, + "1d9e6aaf8019a05f230e5def05af5d889bd4d0f2": { + "balance": "133700000000000000000" + }, + "a375b4bc24a24e1f797593cc302b2f331063fa5c": { + "balance": "200000000000000000000" + }, + "108ba7c2895c50e072dc6f964932d50c282d3034": { + "balance": "500000000000000000000" + }, + "b6b34a263f10c3d2eceb0acc559a7b2ab85ce565": { + "balance": "4000000000000000000000" + }, + "a4d2b429f1ad5349e31704969edc5f25ee8aca10": { + "balance": "10000000000000000000000" + }, + "674adb21df4c98c7a347ac4c3c24266757dd7039": { + "balance": "2000000000000000000000" + }, + "33565ba9da2c03e778ce12294f081dfe81064d24": { + "balance": "16000000000000000000000" + }, + "4ddda7586b2237b053a7f3289cf460dc57d37a09": { + "balance": "10000000000000000000000" + }, + "cc4faac00be6628f92ef6b8cb1b1e76aac81fa18": { + "balance": "205410000000000000000" + }, + "5f99dc8e49e61d57daef606acdd91b4d7007326a": { + "balance": "3000000000000000000000" + }, + "b8a979352759ba09e35aa5935df175bff678a108": { + "balance": "20000000000000000000" + }, + "86fff220e59305c09f483860d6f94e96fbe32f57": { + "balance": "42900000000000000000" + }, + "03e8b084537557e709eae2e1e1a5a6bce1ef8314": { + "balance": "20000000000000000000" + }, + "dda4ff7de491c687df4574dd1b17ff8f246ba3d1": { + "balance": "19600000000000000000000" + }, + "2538532936813c91e653284f017c80c3b8f8a36f": { + "balance": "2002000000000000000000" + }, + "5a82f96cd4b7e2d93d10f3185dc8f43d4b75aa69": { + "balance": "1999400000000000000000" + }, + "86740a46648e845a5d96461b18091ff57be8a16f": { + "balance": "98000000000000000000000" + }, + "7e3f63e13129a221ba1ab06326342cd98b5126ae": { + "balance": "1597960000000000000000" + }, + "1f5f3b34bd134b2781afe5a0424ac5846cdefd11": { + "balance": "99000000000000000000" + }, + "39936c2719450b9420cc2522cf91db01f227c1c1": { + "balance": "500000000000000000000" + }, + "967076a877b18ec15a415bb116f06ef32645dba3": { + "balance": "2000000000000000000000" + }, + "a42908e7fe53980a9abf4044e957a54b70e99cbe": { + "balance": "2000000000000000000000" + }, + "5eb371c407406c427b3b7de271ad3c1e04269579": { + "balance": "3000000000000000000000" + }, + "a570223ae3caa851418a9843a1ac55db4824f4fd": { + "balance": "200000000000000000000" + }, + "764692cccb33405dd0ab0c3379b49caf8e6221ba": { + "balance": "20000000000000000000" + }, + "a365918bfe3f2627b9f3a86775d8756e0fd8a94b": { + "balance": "400000000000000000000" + }, + "069ed0ab7aa77de571f16106051d92afe195f2d0": { + "balance": "200000000000000000000" + }, + "bd432a3916249b4724293af9146e49b8280a7f2a": { + "balance": "4000000000000000000000" + }, + "61c9dce8b2981cb40e98b0402bc3eb28348f03ac": { + "balance": "196910000000000000000" + }, + "8f1fcc3c51e252b693bc5b0ec3f63529fe69281e": { + "balance": "6000000000000000000000" + }, + "55fd08d18064bd202c0ec3d2cce0ce0b9d169c4d": { + "balance": "1970000000000000000000" + }, + "383a7c899ee18bc214969870bc7482f6d8f3570e": { + "balance": "10000000000000000000000" + }, + "b14cc8de33d6338236539a489020ce4655a32bc6": { + "balance": "8000000000000000000000" + }, + "448bf410ad9bbc2fecc4508d87a7fc2e4b8561ad": { + "balance": "199955000000000000000" + }, + "06f7dc8d1b9462cef6feb13368a7e3974b097f9f": { + "balance": "2000000000000000000000" + }, + "9c9f89a3910f6a2ae8a91047a17ab788bddec170": { + "balance": "10000000000000000000000" + }, + "5de598aba344378cab4431555b4f79992dc290c6": { + "balance": "1337000000000000000000" + }, + "87e6034ecf23f8b5639d5f0ea70a22538a920423": { + "balance": "328000000000000000000" + }, + "8b27392206b958cd375d7ef8af2cf8ef0598c0bc": { + "balance": "1000000000000000000000" + }, + "49136fe6e28b7453fcb16b6bbbe9aaacba8337fd": { + "balance": "2000000000000000000000" + }, + "6982fe8a867e93eb4a0bd051589399f2ec9a5292": { + "balance": "2000000000000000000000" + }, + "9fd1052a60506bd1a9ef003afd9d033c267d8e99": { + "balance": "1000000000000000000000" + }, + "d38fa2c4cc147ad06ad5a2f75579281f22a7cc1f": { + "balance": "20000000000000000000000" + }, + "6f794dbdf623daa6e0d00774ad6962737c921ea4": { + "balance": "2000000000000000000000" + }, + "e96b184e1f0f54924ac874f60bbf44707446b72b": { + "balance": "2910840000000000000000" + }, + "b5ba29917c78a1d9e5c5c713666c1e411d7f693a": { + "balance": "3100000000000000000000" + }, + "81d619ff5726f2405f12904c72eb1e24a0aaee4f": { + "balance": "20000000000000000000000" + }, + "b02fa29387ec12e37f6922ac4ce98c5b09e0b00f": { + "balance": "2000000000000000000000" + }, + "b7230d1d1ff2aca366963914a79df9f7c5ea2c98": { + "balance": "8000000000000000000000" + }, + "7b4007c45e5a573fdbb6f8bd746bf94ad04a3c26": { + "balance": "15202564000000000000000" + }, + "8d9a0c70d2262042df1017d6c303132024772712": { + "balance": "2000000000000000000000" + }, + "323aad41df4b6fc8fece8c93958aa901fa680843": { + "balance": "970000000000000000000" + }, + "db04fad9c49f9e880beb8fcf1d3a3890e4b3846f": { + "balance": "1242482000000000000000" + }, + "27824666d278d70423f03dfe1dc7a3f02f43e2b5": { + "balance": "1000070000000000000000" + }, + "e04920dc6ecc1d6ecc084f88aa0af5db97bf893a": { + "balance": "182000000000000000000" + }, + "b0c1b177a220e41f7c74d07cde8569c21c75c2f9": { + "balance": "5600000000000000000000" + }, + "7864dc999fe4f8e003c0f43decc39aae1522dc0f": { + "balance": "94400000000000000000" + }, + "c75c37ce2da06bbc40081159c6ba0f976e3993b1": { + "balance": "1078640000000000000000" + }, + "179a825e0f1f6e985309668465cffed436f6aea9": { + "balance": "20000000000000000000" + }, + "2c6b699d9ead349f067f45711a074a641db6a897": { + "balance": "20000000000000000000" + }, + "068ce8bd6e902a45cb83b51541b40f39c4469712": { + "balance": "5240000000000000000000" + }, + "767ac690791c2e23451089fe6c7083fe55deb62b": { + "balance": "820000000000000000000" + }, + "b34f04b8db65bba9c26efc4ce6efc50481f3d65d": { + "balance": "20000000000000000000000" + }, + "29aef48de8c9fbad4b9e4ca970797a5533eb722d": { + "balance": "10000000000000000000000" + }, + "0a0ecda6636f7716ef1973614687fd89a820a706": { + "balance": "394000000000000000000" + }, + "b32825d5f3db249ef4e85cc4f33153958976e8bc": { + "balance": "501375000000000000000" + }, + "7ef16fd8d15b378a0fba306b8d03dd98fc92619f": { + "balance": "700000000000000000000" + }, + "b58b52865ea55d8036f2fab26098b352ca837e18": { + "balance": "18200000000000000000" + }, + "9b658fb361e046d4fcaa8aef6d02a99111223625": { + "balance": "2000000000000000000000" + }, + "b2a498f03bd7178bd8a789a00f5237af79a3e3f8": { + "balance": "19400000000000000000000" + }, + "cb48fe8265d9af55eb7006bc335645b0a3a183be": { + "balance": "3000000000000000000000" + }, + "3cf9a1d465e78b7039e3694478e2627b36fcd141": { + "balance": "1372000000000000000000" + }, + "5db84400570069a9573cab04b4e6b69535e202b8": { + "balance": "9700000000000000000000" + }, + "214c89c5bd8e7d22bc574bb35e48950211c6f776": { + "balance": "18903000000000000000" + }, + "53396f4a26c2b4604496306c5442e7fcba272e36": { + "balance": "20055000000000000000000" + }, + "720994dbe56a3a95929774e20e1fe525cf3704e4": { + "balance": "8000000000000000000000" + }, + "3571cf7ad304ecaee595792f4bbfa484418549d6": { + "balance": "5825500000000000000000" + }, + "6042c644bae2b96f25f94d31f678c90dc96690db": { + "balance": "2000000000000000000000" + }, + "2e24b597873bb141bdb237ea8a5ab747799af02d": { + "balance": "20000000000000000000000" + }, + "08c802f87758349fa03e6bc2e2fd0791197eea9a": { + "balance": "2000000000000000000000" + }, + "297a88921b5fca10e5bb9ded60025437ae221694": { + "balance": "200000000000000000000" + }, + "aee49d68adedb081fd43705a5f78c778fb90de48": { + "balance": "20000000000000000000" + }, + "4cee901b4ac8b156c5e2f8a6f1bef572a7dceb7e": { + "balance": "1000000000000000000000" + }, + "dfaf31e622c03d9e18a0ddb8be60fbe3e661be0a": { + "balance": "9999800000000000000000" + }, + "00aa5381b2138ebeffc191d5d8c391753b7098d2": { + "balance": "990049000000000000000" + }, + "5b4c0c60f10ed2894bdb42d9dd1d210587810a0d": { + "balance": "500000000000000000000" + }, + "c44f4ab5bc60397c737eb0683391b633f83c48fa": { + "balance": "1000000000000000000000" + }, + "50bef2756248f9a7a380f91b051ba3be28a649ed": { + "balance": "1999884000000000000000" + }, + "1bd909ac0d4a1102ec98dcf2cca96a0adcd7a951": { + "balance": "20055000000000000000" + }, + "9ec03e02e587b7769def538413e97f7e55be71d8": { + "balance": "19700000000000000000000" + }, + "9874803fe1f3a0365e7922b14270eaeb032cc1b5": { + "balance": "1124500000000000000000" + }, + "4e2310191ead8d3bc6489873a5f0c2ec6b87e1be": { + "balance": "1000000000000000000000" + }, + "93678a3c57151aeb68efdc43ef4d36cb59a009f3": { + "balance": "30060000000000000000" + }, + "f483f607a21fcc28100a018c568ffbe140380410": { + "balance": "1000000000000000000000" + }, + "2a91a9fed41b7d0e5cd2d83158d3e8a41a9a2d71": { + "balance": "1940000000000000000000" + }, + "240e559e274aaef0c258998c979f671d1173b88b": { + "balance": "4000000000000000000000" + }, + "108a2b7c336f784779d8b54d02a8d31d9a139c0a": { + "balance": "10000000000000000000000" + }, + "9c98fdf1fdcd8ba8f4c5b04c3ae8587efdf0f6e6": { + "balance": "6000000000000000000000" + }, + "194ff44aefc17bd20efd7a204c47d1620c86db5d": { + "balance": "2999400000000000000000" + }, + "1f8116bd0af5570eaf0c56c49c7ab5e37a580458": { + "balance": "2000000000000000000000" + }, + "d79835e404fb86bf845fba090d6ba25e0c8866a6": { + "balance": "2400000000000000000000" + }, + "a8e7201ff619faffc332e6ad37ed41e301bf014a": { + "balance": "600000000000000000000" + }, + "286906b6bd4972e3c71655e04baf36260c7cb153": { + "balance": "340000000000000000000" + }, + "db4bc83b0e6baadb1156c5cf06e0f721808c52c7": { + "balance": "880000000000000000000" + }, + "a158148a2e0f3e92dc2ce38febc20107e3253c96": { + "balance": "2000000000000000000000" + }, + "9f6a322a6d469981426ae844865d7ee0bb15c7b3": { + "balance": "50003000000000000000" + }, + "32f29e8727a74c6b4301e3ffff0687c1b870dae9": { + "balance": "1000000000000000000000" + }, + "19918aa09e7d494e98ffa5db50350892f7156ac6": { + "balance": "10000000000000000000000" + }, + "5a5f8508da0ebebb90be9033bd4d9e274105ae00": { + "balance": "6685000000000000000000" + }, + "6fc25e7e00ca4f60a9fe6f28d1fde3542e2d1079": { + "balance": "792000000000000000000" + }, + "72094f3951ffc9771dced23ada080bcaf9c7cca7": { + "balance": "6000000000000000000000" + }, + "43f7e86e381ec51ec4906d1476cba97a3db584e4": { + "balance": "1000000000000000000000" + }, + "05696b73916bd3033e05521e3211dfec026e98e4": { + "balance": "2000000000000000000000" + }, + "5e7f70378775589fc66a81d3f653e954f55560eb": { + "balance": "2434000000000000000000" + }, + "895613236f3584216ad75c5d3e07e3fa6863a778": { + "balance": "2000000000000000000000" + }, + "4eb1454b573805c8aca37edec7149a41f61202f4": { + "balance": "300000000000000000000" + }, + "d99999a2490d9494a530cae4daf38554f4dd633e": { + "balance": "120000000000000000000" + }, + "1704cefcfb1331ec7a78388b29393e85c1af7916": { + "balance": "400000000000000000000" + }, + "ac4acfc36ed6094a27e118ecc911cd473e8fb91f": { + "balance": "1799800000000000000000" + }, + "a975b077fcb4cc8efcbf838459b6fa243a4159d6": { + "balance": "40000000000000000000" + }, + "9c405cf697956138065e11c5f7559e67245bd1a5": { + "balance": "200000000000000000000" + }, + "cafde855864c2598da3cafc05ad98df2898e8048": { + "balance": "14179272000000000000000" + }, + "8ef711e43a13918f1303e81d0ea78c9eefd67eb2": { + "balance": "4000000000000000000000" + }, + "0b14891999a65c9ef73308efe3100ca1b20e8192": { + "balance": "800000000000000000000" + }, + "47cf9cdaf92fc999cc5efbb7203c61e4f1cdd4c3": { + "balance": "131400000000000000000" + }, + "04ba8a3f03f08b895095994dda619edaacee3e7a": { + "balance": "2000000000000000000000" + }, + "02b6d65cb00b7b36e1fb5ed3632c4cb20a894130": { + "balance": "20000000000000000000000" + }, + "f99aee444b5783c093cfffd1c4632cf93c6f050c": { + "balance": "400000000000000000000" + }, + "2541314a0b408e95a694444977712a50713591ab": { + "balance": "1634706000000000000000" + }, + "3096dca34108085bcf04ae72b94574a13e1a3e1d": { + "balance": "200000000000000000000" + }, + "56df05bad46c3f00ae476ecf017bb8c877383ff1": { + "balance": "197248000000000000000" + }, + "6d59b21cd0e2748804d9abe064eac2bef0c95f27": { + "balance": "2000000000000000000000" + }, + "b29f5b7c1930d9f97a115e067066f0b54db44b3b": { + "balance": "1000000000000000000000" + }, + "888c16144933197cac26504dd76e06fd6600c789": { + "balance": "100000000000000000000" + }, + "dfe3c52a92c30396a4e33a50170dc900fcf8c9cf": { + "balance": "50000000000000000000" + }, + "f76f69cee4faa0a63b30ae1e7881f4f715657010": { + "balance": "200000000000000000000" + }, + "ee0007b0960d00908a94432a737557876aac7c31": { + "balance": "53053000000000000000" + }, + "effc15e487b1beda0a8d1325bdb4172240dc540a": { + "balance": "64940000000000000000" + }, + "40ab0a3e83d0c8ac9366910520eab1772bac3b1a": { + "balance": "976600000000000000000" + }, + "1895a0eb4a4372722fcbc5afe6936f289c88a419": { + "balance": "910000000000000000000" + }, + "81efe296ae76c860d1c5fbd33d47e8ce9996d157": { + "balance": "1000000000000000000000" + }, + "9ddd355e634ee9927e4b7f6c97e7bf3a2f1e687a": { + "balance": "50000000000000000000" + }, + "f2b4ab2c9427a9015ef6eefff5edb60139b719d1": { + "balance": "716800000000000000000" + }, + "765be2e12f629e6349b97d21b62a17b7c830edab": { + "balance": "6000000000000000000000" + }, + "ff61c9c1b7a3d8b53bba20b34466544b7b216644": { + "balance": "2000000000000000000000" + }, + "36a08fd6fd1ac17ce15ed57eefb12a2be28188bf": { + "balance": "1337000000000000000000" + }, + "17049311101d817efb1d65910f663662a699c98c": { + "balance": "1999800000000000000000" + }, + "30511832918d8034a7bee72ef2bfee440ecbbcf6": { + "balance": "16100000000000000000000" + }, + "d27c234ff7accace3d996708f8f9b04970f97d36": { + "balance": "1337000000000000000000" + }, + "a961171f5342b173dd70e7bfe5b5ca238b13bcdd": { + "balance": "3397053000000000000000" + }, + "30bf61b2d877fe10635126326fa189e4b0b1c3b0": { + "balance": "1027580000000000000000" + }, + "4bb6d86b8314c22d8d37ea516d0019f156aae12d": { + "balance": "1000000000000000000000" + }, + "5f363e0ab747e02d1b3b66abb69ea53c7baf523a": { + "balance": "11640000000000000000000" + }, + "283e11203749b1fa4f32febb71e49d135919382a": { + "balance": "1000000000000000000000" + }, + "ac5999a89d2dd286d5a80c6dee7e86aad40f9e12": { + "balance": "3880000000000000000000" + }, + "3f6dd3650ee428dcb7759553b017a96a94286ac9": { + "balance": "1337000000000000000000" + }, + "b3fc1d6881abfcb8becc0bb021b8b73b7233dd91": { + "balance": "50000000000000000000" + }, + "f0832a6bb25503eeca435be31b0bf905ca1fcf57": { + "balance": "6685000000000000000000" + }, + "9d7fda7070bf3ee9bbd9a41f55cad4854ae6c22c": { + "balance": "11027380000000000000000" + }, + "4b0bd8acfcbc53a6010b40d4d08ddd2d9d69622d": { + "balance": "668500000000000000000" + }, + "f3b668b3f14d920ebc379092db98031b67b219b3": { + "balance": "199955000000000000000" + }, + "d91d889164479ce436ece51763e22cda19b22d6b": { + "balance": "3365200000000000000000" + }, + "ffe28db53c9044b4ecd4053fd1b4b10d7056c688": { + "balance": "100000000000000000000" + }, + "c77b01a6e911fa988d01a3ab33646beef9c138f3": { + "balance": "721400000000000000000" + }, + "c0064f1d9474ab915d56906c9fb320a2c7098c9b": { + "balance": "358000000000000000000" + }, + "4e3edad4864dab64cae4c5417a76774053dc6432": { + "balance": "590943000000000000000" + }, + "71d2cc6d02578c65f73c575e76ce8fbcfadcf356": { + "balance": "72400000000000000000" + }, + "9971df60f0ae66dce9e8c84e17149f09f9c52f64": { + "balance": "200000000000000000000" + }, + "58e661d0ba73d6cf24099a5562b808f7b3673b68": { + "balance": "2000000000000000000000" + }, + "84b0ee6bb837d3a4c4c5011c3a228c0edab4634a": { + "balance": "20000000000000000000" + }, + "84375afbf59b3a1d61a1be32d075e0e15a4fbca5": { + "balance": "200000000000000000000" + }, + "9ae9476bfecd3591964dd325cf8c2a24faed82c1": { + "balance": "4000000000000000000000" + }, + "6a4c8907b600248057b1e46354b19bdc859c991a": { + "balance": "20000000000000000000" + }, + "1c045649cd53dc23541f8ed4d341812808d5dd9c": { + "balance": "7000000000000000000000" + }, + "c5e488cf2b5677933971f64cb8202dd05752a2c0": { + "balance": "1000000000000000000000" + }, + "eb25481fcd9c221f1ac7e5fd1ecd9307a16215b8": { + "balance": "197000000000000000000" + }, + "a61887818f914a20e31077290b83715a6b2d6ef9": { + "balance": "1880000000000000000000" + }, + "679437eacf437878dc293d48a39c87b7421a216c": { + "balance": "64528000000000000000" + }, + "331a1c26cc6994cdd3c14bece276ffff4b9df77c": { + "balance": "18049000000000000000" + }, + "75b95696e8ec4510d56868a7c1a735c68b244890": { + "balance": "6400000000000000000000" + }, + "a77f3ee19e9388bbbb2215c62397b96560132360": { + "balance": "200000000000000000000" + }, + "bc7afc8477412274fc265df13c054473427d43c6": { + "balance": "130034000000000000000" + }, + "91050a5cffadedb4bb6eaafbc9e5013428e96c80": { + "balance": "1700000000000000000000" + }, + "24586ec5451735eeaaeb470dc8736aae752f82e5": { + "balance": "17600000000000000000" + }, + "51039377eed0c573f986c5e8a95fb99a59e9330f": { + "balance": "1970000000000000000000" + }, + "fbb161fe875f09290a4b262bc60110848f0d2226": { + "balance": "2000000000000000000000" + }, + "ed52a2cc0869dc9e9f842bd0957c47a8e9b0c9ff": { + "balance": "9550000000000000000000" + }, + "bad235d5085dc7b068a67c412677b03e1836884c": { + "balance": "2000000000000000000000" + }, + "055eac4f1ad3f58f0bd024d68ea60dbe01c6afb3": { + "balance": "100000000000000000000" + }, + "4058808816fdaa3a5fc98ed47cfae6c18315422e": { + "balance": "199800000000000000000" + }, + "3540c7bd7a8442d5bee21a2180a1c4edff1649e0": { + "balance": "1239295000000000000000" + }, + "c5edbbd2ca0357654ad0ea4793f8c5cecd30e254": { + "balance": "6000000000000000000000" + }, + "b5906b0ae9a28158e8ac550e39da086ee3157623": { + "balance": "200000000000000000000" + }, + "4d801093c19ca9b8f342e33cc9c77bbd4c8312cf": { + "balance": "345005000000000000000" + }, + "206482ee6f138a778fe1ad62b180ce856fbb23e6": { + "balance": "2000000000000000000000" + }, + "c0ed0d4ad10de03435b153a0fc25de3b93f45204": { + "balance": "3160000000000000000000" + }, + "29e67990e1b6d52e1055ffe049c53195a81542cf": { + "balance": "20000000000000000000000" + }, + "e6d22209ffd0b87509ade3a8e2ef429879cb89b5": { + "balance": "17260000000000000000000" + }, + "d6644d40e90bc97fe7dfe7cabd3269fd579ba4b3": { + "balance": "159000000000000000000" + }, + "ece1290877b583e361a2d41b009346e6274e2538": { + "balance": "300000000000000000000" + }, + "ab3861226ffec1289187fb84a08ec3ed043264e8": { + "balance": "1000000000000000000000" + }, + "60e0bdd0a259bb9cb09d3f37e5cd8b9daceabf8a": { + "balance": "1370000000000000000000" + }, + "28b77585cb3d55a199ab291d3a18c68fe89a848a": { + "balance": "1960000000000000000000" + }, + "73128173489528012e76b41a5e28c68ba4e3a9d4": { + "balance": "1000000000000000000000" + }, + "018492488ba1a292342247b31855a55905fef269": { + "balance": "140000000000000000000" + }, + "0bb54c72fd6610bfa4363397e020384b022b0c49": { + "balance": "1337000000000000000000" + }, + "520f66a0e2657ff0ac4195f2f064cf2fa4b24250": { + "balance": "40000000000000000000" + }, + "a1432ed2c6b7777a88e8d46d388e70477f208ca5": { + "balance": "7999538000000000000000" + }, + "149ba10f0da2725dc704733e87f5a524ca88515e": { + "balance": "7880000000000000000000" + }, + "b287f7f8d8c3872c1b586bcd7d0aedbf7e732732": { + "balance": "20000000000000000000" + }, + "c46bbdef76d4ca60d316c07f5d1a780e3b165f7e": { + "balance": "2000000000000000000000" + }, + "b5a589dd9f4071dbb6fba89b3f5d5dae7d96c163": { + "balance": "2000000000000000000000" + }, + "d218efb4db981cdd6a797f4bd48c7c26293ceb40": { + "balance": "2975000000000000000000" + }, + "af87d2371ef378957fbd05ba2f1d66931b01e2b8": { + "balance": "700000000000000000000" + }, + "86ef6426211949cc37f4c75e7850369d0cf5f479": { + "balance": "13399196000000000000000" + }, + "fb3a0b0d6b6a718f6fc0292a825dc9247a90a5d0": { + "balance": "199950000000000000000" + }, + "da16dd5c3d1a2714358fe3752cae53dbab2be98c": { + "balance": "19400000000000000000000" + }, + "9eb7834e171d41e069a77947fca87622f0ba4e48": { + "balance": "100000000000000000000" + }, + "e1d91b0954cede221d6f24c7985fc59965fb98b8": { + "balance": "2000000000000000000000" + }, + "85d0d88754ac84b8b21ba93dd2bfec72626faba8": { + "balance": "1000000000000000000000" + }, + "695b4cce085856d9e1f9ff3e79942023359e5fbc": { + "balance": "5000000000000000000000" + }, + "9156d18029350e470408f15f1aa3be9f040a67c6": { + "balance": "1000000000000000000000" + }, + "a9d64b4f3bb7850722b58b478ba691375e224e42": { + "balance": "6000000000000000000000" + }, + "17e4a0e52bac3ee44efe0954e753d4b85d644e05": { + "balance": "2000000000000000000000" + }, + "b8a79c84945e47a9c3438683d6b5842cff7684b1": { + "balance": "2000000000000000000000" + }, + "cfac2e1bf33205b05533691a02267ee19cd81836": { + "balance": "1000000000000000000000" + }, + "6b992521ec852370848ad697cc2df64e63cc06ff": { + "balance": "1000000000000000000000" + }, + "60af0ee118443c9b37d2fead77f5e521debe1573": { + "balance": "1910000000000000000000" + }, + "c6dbdb9efd5ec1b3786e0671eb2279b253f215ed": { + "balance": "1000000000000000000000" + }, + "659c0a72c767a3a65ced0e1ca885a4c51fd9b779": { + "balance": "2000000000000000000000" + }, + "ed1276513b6fc68628a74185c2e20cbbca7817bf": { + "balance": "191000000000000000000" + }, + "5ad12c5ed4fa827e2150cfa0d68c0aa37b1769b8": { + "balance": "800000000000000000000" + }, + "17c0fef6986cfb2e4041f9979d9940b69dff3de2": { + "balance": "4000000000000000000000" + }, + "ca98c7988efa08e925ef9c9945520326e9f43b99": { + "balance": "4000000000000000000000" + }, + "fe8f1fdcab7fbec9a6a3fcc507619600505c36a3": { + "balance": "19700000000000000000" + }, + "4420aa35465be617ad2498f370de0a3cc4d230af": { + "balance": "2000000000000000000000" + }, + "8232d1f9742edf8dd927da353b2ae7b4cbce7592": { + "balance": "668500000000000000000" + }, + "eca5f58792b8c62d2af556717ee3ee3028be4dce": { + "balance": "2000000000000000000000" + }, + "6bf86f1e2f2b8032a95c4d7738a109d3d0ed8104": { + "balance": "1820000000000000000000" + }, + "3ac2f0ff1612e4a1c346d53382abf6d8a25baa53": { + "balance": "2000000000000000000000" + }, + "daa1bd7a9148fb865cd612dd35f162861d0f3bdc": { + "balance": "3066243000000000000000" + }, + "5169c60aee4ceed1849ab36d664cff97061e8ea8": { + "balance": "3000000000000000000000" + }, + "2a5e3a40d2cd0325766de73a3d671896b362c73b": { + "balance": "100000000000000000000000" + }, + "a83382b6e15267974a8550b98f7176c1a353f9be": { + "balance": "3541608000000000000000" + }, + "b50c149a1906fad2786ffb135aab501737e9e56f": { + "balance": "388000000000000000000" + }, + "d9775965b716476675a8d513eb14bbf7b07cd14a": { + "balance": "5076200000000000000000" + }, + "66662006015c1f8e3ccfcaebc8ee6807ee196303": { + "balance": "500024000000000000000" + }, + "78746a958dced4c764f876508c414a68342cecb9": { + "balance": "50600000000000000000" + }, + "e982e6f28c548f5f96f45e63f7ab708724f53fa1": { + "balance": "396238000000000000000" + }, + "740bfd52e01667a3419b029a1b8e45576a86a2db": { + "balance": "16800000000000000000000" + }, + "2bd252e0d732ff1d7c78f0a02e6cb25423cf1b1a": { + "balance": "2674000000000000000000" + }, + "2e2d7ea66b9f47d8cc52c01c52b6e191bc7d4786": { + "balance": "3999800000000000000000" + }, + "3e3161f1ea2fbf126e79da1801da9512b37988c9": { + "balance": "49250000000000000000000" + }, + "7e2ba86da52e785d8625334f3397ba1c4bf2e8d1": { + "balance": "197000000000000000000" + }, + "7608f437b31f18bc0b64d381ae86fd978ed7b31f": { + "balance": "50000000000000000000" + }, + "25a5a44d38a2f44c6a9db9cdbc6b1e2e97abb509": { + "balance": "17000000000000000000000" + }, + "745ad3abc6eeeb2471689b539e789ce2b8268306": { + "balance": "1129977000000000000000" + }, + "09e437d448861228a232b62ee8d37965a904ed9c": { + "balance": "21708305000000000000000" + }, + "be53322f43fbb58494d7cce19dda272b2450e827": { + "balance": "200018000000000000000" + }, + "4166fc08ca85f766fde831460e9dc93c0e21aa6c": { + "balance": "1000000000000000000000" + }, + "99c0174cf84e0783c220b4eb6ae18fe703854ad3": { + "balance": "2074800000000000000000" + }, + "3cf484524fbdfadae26dc185e32b2b630fd2e726": { + "balance": "448798000000000000000" + }, + "fdcd5d80b105897a57abc47865768b2900524295": { + "balance": "6400000000000000000000" + }, + "f22f4078febbbaa8b0e78e642c8a42f35d433905": { + "balance": "1999944000000000000000" + }, + "eac768bf14b8f9432e69eaa82a99fbeb94cd0c9c": { + "balance": "98500000000000000000000" + }, + "2639eee9873ceec26fcc9454b548b9e7c54aa65c": { + "balance": "1000000000000000000000" + }, + "c3c3c2510d678020485a63735d1307ec4ca6302b": { + "balance": "1000000000000000000000" + }, + "b73d6a77559c86cf6574242903394bacf96e3570": { + "balance": "91200000000000000000" + }, + "5ce2e7ceaaa18af0f8aafa7fbad74cc89e3cd436": { + "balance": "20000000000000000000000" + }, + "03377c0e556b640103289a6189e1aeae63493467": { + "balance": "20000000000000000000000" + }, + "6eb0a5a9ae96d22cf01d8fd6483b9f38f08c2c8b": { + "balance": "4000000000000000000000" + }, + "fc8215a0a69913f62a43bf1c8590b9ddcd0d8ddb": { + "balance": "2000000000000000000000" + }, + "4a835c25824c47ecbfc79439bf3f5c3481aa75cd": { + "balance": "1400000000000000000000" + }, + "b5493ef173724445cf345c035d279ba759f28d51": { + "balance": "20000000000000000000" + }, + "b9e90c1192b3d5d3e3ab0700f1bf655f5dd4347a": { + "balance": "499928000000000000000" + }, + "419bde7316cc1ed295c885ace342c79bf7ee33ea": { + "balance": "6000000000000000000000" + }, + "e4625501f52b7af52b19ed612e9d54fdd006b492": { + "balance": "209440000000000000000" + }, + "e9d599456b2543e6db80ea9b210e908026e2146e": { + "balance": "200000000000000000000" + }, + "2c06dd922b61514aafedd84488c0c28e6dcf0e99": { + "balance": "100000000000000000000000" + }, + "06b5ede6fdf1d6e9a34721379aeaa17c713dd82a": { + "balance": "2000000000000000000000" + }, + "d8930a39c77357c30ad3a060f00b06046331fd62": { + "balance": "820000000000000000000" + }, + "b2a2c2111612fb8bbb8e7dd9378d67f1a384f050": { + "balance": "20000000000000000000" + }, + "1f174f40a0447234e66653914d75bc003e5690dc": { + "balance": "160000000000000000000" + }, + "e06cb6294704eea7437c2fc3d30773b7bf38889a": { + "balance": "20094000000000000000" + }, + "cd06f8c1b5cdbd28e2d96b6346c3e85a0483ba24": { + "balance": "1000000000000000000000" + }, + "f316ef1df2ff4d6c1808dba663ec8093697968e0": { + "balance": "1794400000000000000000" + }, + "1e6915ebd9a19c81b692ad99b1218a592c1ac7b1": { + "balance": "4000000000000000000000" + }, + "885493bda36a0432976546c1ddce71c3f4570021": { + "balance": "216700000000000000000" + }, + "18b0407cdad4ce52600623bd5e1f6a81ab61f026": { + "balance": "319489000000000000000" + }, + "187d9f0c07f8eb74faaad15ebc7b80447417f782": { + "balance": "20000000000000000000" + }, + "5d6ccf806738091042ad97a6e095fe8c36aa79c5": { + "balance": "188000000000000000000" + }, + "53437fecf34ab9d435f4deb8ca181519e2592035": { + "balance": "188000000000000000000" + }, + "fd1faa347b0fcc804c2da86c36d5f1d18b7087bb": { + "balance": "52380000000000000000" + }, + "650cf67db060cce17568d5f2a423687c49647609": { + "balance": "100000000000000000000" + }, + "bcd95ef962462b6edfa10fda87d72242fe3edb5c": { + "balance": "334133000000000000000" + }, + "3b5e8b3c77f792decb7a8985df916efb490aac23": { + "balance": "2000000000000000000000" + }, + "f13b083093ba564e2dc631568cf7540d9a0ec719": { + "balance": "1999944000000000000000" + }, + "373c547e0cb5ce632e1c5ad66155720c01c40995": { + "balance": "4691588000000000000000" + }, + "7313461208455455465445a459b06c3773b0eb30": { + "balance": "2000000000000000000000" + }, + "441f37e8a029fd02482f289c49b5d06d00e408a4": { + "balance": "333333000000000000000" + }, + "d30d4c43adcf55b2cb53d68323264134498d89ce": { + "balance": "1000000000000000000000" + }, + "f648ea89c27525710172944e79edff847803b775": { + "balance": "100000000000000000000000" + }, + "0c7f869f8e90d53fdc03e8b2819b016b9d18eb26": { + "balance": "20000000000000000000000" + }, + "c71f92a3a54a7b8c2f5ea44305fccb84eee23148": { + "balance": "49980000000000000000" + }, + "7988901331e387f713faceb9005cb9b65136eb14": { + "balance": "1970000000000000000000" + }, + "e9a39a8bac0f01c349c64cedb69897f633234ed2": { + "balance": "3980000000000000000000" + }, + "ad2a5c00f923aaf21ab9f3fb066efa0a03de2fb2": { + "balance": "999996000000000000000" + }, + "f25259a5c939cd25966c9b6303d3731c53ddbc4c": { + "balance": "200000000000000000000" + }, + "d1682c2159018dc3d07f08240a8c606daf65f8e1": { + "balance": "200000000000000000000000" + }, + "a99991cebd98d9c838c25f7a7416d9e244ca250d": { + "balance": "1000000000000000000000" + }, + "5a285755391e914e58025faa48cc685f4fd4f5b8": { + "balance": "26000000000000000000000" + }, + "4d24b7ac47d2f27de90974ba3de5ead203544bcd": { + "balance": "100000000000000000000" + }, + "21b182f2da2b384493cf5f35f83d9d1ee14f2a21": { + "balance": "2000000000000000000000" + }, + "31ab088966ecc7229258f6098fce68cf39b38485": { + "balance": "1000000000000000000000" + }, + "4977a7939d0939689455ce2639d0ee5a4cd910ed": { + "balance": "1820000000000000000000" + }, + "07af938c1237a27c9030094dcf240750246e3d2c": { + "balance": "500000000000000000000" + }, + "4e2bfa4a466f82671b800eee426ad00c071ba170": { + "balance": "4000000000000000000000" + }, + "107379d4c467464f235bc18e55938aad3e688ad7": { + "balance": "50000000000000000000" + }, + "f7b29b82195c882dab7897c2ae95e77710f57875": { + "balance": "2199000000000000000000" + }, + "56586391040c57eec6f5affd8cd4abde10b50acc": { + "balance": "4000000000000000000000" + }, + "ac608e2bac9dd20728d2947effbbbf900a9ce94b": { + "balance": "6000600000000000000000" + }, + "48548b4ba62bcb2f0d34a88dc69a680e539cf046": { + "balance": "100084000000000000000" + }, + "1665ab1739d71119ee6132abbd926a279fe67948": { + "balance": "100000000000000000000" + }, + "af4493e8521ca89d95f5267c1ab63f9f45411e1b": { + "balance": "200000000000000000000" + }, + "bf6925c00751008440a6739a02bf2b6cdaab5e3a": { + "balance": "1000000000000000000000" + }, + "3fe40fbd919aad2818df01ee4df46c46842ac539": { + "balance": "6000000000000000000000" + }, + "455b9296921a74d1fc41617f43b8303e6f3ed76c": { + "balance": "4200000000000000000000" + }, + "7086b4bde3e35d4aeb24b825f1a215f99d85f745": { + "balance": "1999800000000000000000" + }, + "d4ee4919fb37f2bb970c3fff54aaf1f3dda6c03f": { + "balance": "40000000000000000000000" + }, + "a4489a50ead5d5445a7bee4d2d5536c2a76c41f8": { + "balance": "200000000000000000000" + }, + "505e4f7c275588c533a20ebd2ac13b409bbdea3c": { + "balance": "17600000000000000000" + }, + "3bb53598cc20e2055dc553b049404ac9b7dd1e83": { + "balance": "615020000000000000000" + }, + "52cd20403ba7eda6bc307a3d63b5911b817c1263": { + "balance": "20000000000000000000" + }, + "a211da03cc0e31ecce5309998718515528a090df": { + "balance": "200000000000000000000" + }, + "bcb422dc4dd2aae94abae95ea45dd1731bb6b0ba": { + "balance": "447500000000000000000" + }, + "cbde9734b8e6aa538c291d6d7facedb0f338f857": { + "balance": "2000000000000000000000" + }, + "171ca02a8b6d62bf4ca47e906914079861972cb2": { + "balance": "200000000000000000000" + }, + "d40d0055fd9a38488aff923fd03d35ec46d711b3": { + "balance": "4999711000000000000000" + }, + "3887192c7f705006b630091276b39ac680448d6b": { + "balance": "60000000000000000000" + }, + "3f3c8e61e5604cef0605d436dd22accd862217fc": { + "balance": "1337000000000000000000" + }, + "4258fd662fc4ce3295f0d4ed8f7bb1449600a0a9": { + "balance": "6719600000000000000000" + }, + "4571de672b9904bad8743692c21c4fdcea4c2e01": { + "balance": "4000000000000000000000" + }, + "5be045512a026e3f1cebfd5a7ec0cfc36f2dc16b": { + "balance": "120000000000000000000" + }, + "d6300b3215b11de762ecde4b70b7927d01291582": { + "balance": "2000000000000000000000" + }, + "f9e37447406c412197b2e2aebc001d6e30c98c60": { + "balance": "8346700000000000000000" + }, + "bd047ff1e69cc6b29ad26497a9a6f27a903fc4dd": { + "balance": "865000000000000000000" + }, + "23fa7eb51a48229598f97e762be0869652dffc66": { + "balance": "1000000000000000000000" + }, + "6679aeecd87a57a73f3356811d2cf49d0c4d96dc": { + "balance": "600000000000000000000" + }, + "23c55aeb5739876f0ac8d7ebea13be729685f000": { + "balance": "1337000000000000000000" + }, + "757b65876dbf29bf911d4f0692a2c9beb1139808": { + "balance": "4124263000000000000000" + }, + "e8fc36b0131ec120ac9e85afc10ce70b56d8b6ba": { + "balance": "200000000000000000000" + }, + "1a89899cbebdbb64bb26a195a63c08491fcd9eee": { + "balance": "2000000000000000000000" + }, + "6edf7f5283725c953ee64317f66188af1184b033": { + "balance": "8050000000000000000000" + }, + "297385e88634465685c231a314a0d5dcd146af01": { + "balance": "1550000000000000000000" + }, + "018f20a27b27ec441af723fd9099f2cbb79d6263": { + "balance": "2167000000000000000000" + }, + "a5a4227f6cf98825c0d5baff5315752ccc1a1391": { + "balance": "10000000000000000000000" + }, + "69517083e303d4fbb6c2114514215d69bc46a299": { + "balance": "100000000000000000000" + }, + "1dab172effa6fbee534c94b17e794edac54f55f8": { + "balance": "1970000000000000000000" + }, + "c6ee35934229693529dc41d9bb71a2496658b88e": { + "balance": "19700000000000000000000" + }, + "a8ee1df5d44b128469e913569ef6ac81eeda4fc8": { + "balance": "500000000000000000000" + }, + "35bd246865fab490ac087ac1f1d4f2c10d0cda03": { + "balance": "400000000000000000000" + }, + "4bf8bf1d35a231315764fc8001809a949294fc49": { + "balance": "66850000000000000000" + }, + "c70fa45576bf9c865f983893002c414926f61029": { + "balance": "400400000000000000000" + }, + "fdeaac2acf1d138e19f2fc3f9fb74592e3ed818a": { + "balance": "668500000000000000000" + }, + "bfbfbcb656c2992be8fcde8219fbc54aadd59f29": { + "balance": "9999924000000000000000" + }, + "1722c4cbe70a94b6559d425084caeed4d6e66e21": { + "balance": "4000000000000000000000" + }, + "00e681bc2d10db62de85848324492250348e90bf": { + "balance": "20000000000000000000000" + }, + "5c308bac4857d33baea074f3956d3621d9fa28e1": { + "balance": "4999711000000000000000" + }, + "68c08490c89bf0d6b6f320b1aca95c8312c00608": { + "balance": "4000000000000000000000" + }, + "ce1884ddbbb8e10e4dba6e44feeec2a7e5f92f05": { + "balance": "4000000000000000000000" + }, + "427417bd16b1b3d22dbb902d8f9657016f24a61c": { + "balance": "2000000000000000000000" + }, + "5ff93de6ee054cad459b2d5eb0f6870389dfcb74": { + "balance": "220000000000000000000" + }, + "71946b7117fc915ed107385f42d99ddac63249c2": { + "balance": "2000000000000000000000" + }, + "11ec00f849b6319cf51aa8dd8f66b35529c0be77": { + "balance": "2000000000000000000000" + }, + "610fd6ee4eebab10a8c55d0b4bd2e7d6ef817156": { + "balance": "20002000000000000000" + }, + "a422e4bf0bf74147cc895bed8f16d3cef3426154": { + "balance": "349281000000000000000" + }, + "745aecbaf9bb39b74a67ea1ce623de368481baa6": { + "balance": "10000000000000000000000" + }, + "9f496cb2069563144d0811677ba0e4713a0a4143": { + "balance": "1122000000000000000000" + }, + "c500b720734ed22938d78c5e48b2ba9367a575ba": { + "balance": "33400000000000000000000" + }, + "cd072e6e1833137995196d7bb1725fef8761f655": { + "balance": "6000000000000000000000" + }, + "94644ad116a41ce2ca7fbec609bdef738a2ac7c7": { + "balance": "5000000000000000000000" + }, + "e8d942d82f175ecb1c16a405b10143b3f46b963a": { + "balance": "568600000000000000000" + }, + "f73dd9c142b71bce11d06e30e7e7d032f2ec9c9e": { + "balance": "1970000000000000000000" + }, + "1327d759d56e0ab87af37ecf63fe01f310be100a": { + "balance": "659200000000000000000" + }, + "28fa2580f9ebe420f3e5eefdd371638e3b7af499": { + "balance": "6000000000000000000000" + }, + "024bdd2c7bfd500ee7404f7fb3e9fb31dd20fbd1": { + "balance": "180000000000000000000" + }, + "b4b14bf45455d0ab0803358b7524a72be1a2045b": { + "balance": "500000000000000000000" + }, + "b1e2dd95e39ae9775c55aeb13f12c2fa233053ba": { + "balance": "2000000000000000000000" + }, + "35b03ea4245736f57b85d2eb79628f036ddcd705": { + "balance": "4000000000000000000000" + }, + "eb2ef3d38fe652403cd4c9d85ed7f0682cd7c2de": { + "balance": "42784000000000000000000" + }, + "690594d306613cd3e2fd24bca9994ad98a3d73f8": { + "balance": "2000000000000000000000" + }, + "8397a1bc47acd647418159b99cea57e1e6532d6e": { + "balance": "9169160000000000000000" + }, + "b44815a0f28e569d0e921a4ade8fb2642526497a": { + "balance": "55500000000000000000" + }, + "e24109be2f513d87498e926a286499754f9ed49e": { + "balance": "886500000000000000000" + }, + "37ac29bda93f497bc4aeaab935452c431510341e": { + "balance": "985000000000000000000" + }, + "4a81abe4984c7c6bef63d69820e55743c61f201c": { + "balance": "16011846000000000000000" + }, + "66dcc5fb4ee7fee046e141819aa968799d644491": { + "balance": "1337000000000000000000" + }, + "43ff38743ed0cd43308c066509cc8e7e72c862aa": { + "balance": "1940000000000000000000" + }, + "b8f20005b61352ffa7699a1b52f01f5ab39167f1": { + "balance": "10000000000000000000000" + }, + "1cda411bd5163baeca1e558563601ce720e24ee1": { + "balance": "18200000000000000000" + }, + "86245f596691093ece3f3d3ca2263eace81941d9": { + "balance": "188000000000000000000" + }, + "f52a5882e8927d944b359b26366ba2b9cacfbae8": { + "balance": "25000080000000000000000" + }, + "118c18b2dce170e8f445753ba5d7513cb7636d2d": { + "balance": "8800000000000000000000" + }, + "7168b3bb8c167321d9bdb023a6e9fd11afc9afd9": { + "balance": "1790000000000000000000" + }, + "d9103bb6b67a55a7fece2d1af62d457c2178946d": { + "balance": "1000000000000000000000" + }, + "8b9fda7d981fe9d64287f85c94d83f9074849fcc": { + "balance": "14000000000000000000000" + }, + "91211712719f2b084d3b3875a85069f466363141": { + "balance": "1000000000000000000000" + }, + "4863849739265a63b0a2bf236a5913e6f959ce15": { + "balance": "1520000000000000000000" + }, + "c2d1778ef6ee5fe488c145f3586b6ebbe3fbb445": { + "balance": "1146000000000000000000" + }, + "2b77a4d88c0d56a3dbe3bae04a05f4fcd1b757e1": { + "balance": "300000000000000000000" + }, + "fe9c0fffefb803081256c0cf4d6659e6d33eb4fb": { + "balance": "1528000000000000000000" + }, + "893017ff1adad499aa065401b4236ce6e92b625a": { + "balance": "1999944000000000000000" + }, + "073c67e09b5c713c5221c8a0c7f3f74466c347b0": { + "balance": "19400000000000000000000" + }, + "93e303411afaf6c107a44101c9ac5b36e9d6538b": { + "balance": "66000000000000000000000" + }, + "0ec50aa823f465b9464b0bc0c4a57724a555f5d6": { + "balance": "59100000000000000000000" + }, + "a3e3a6ea509573e21bd0239ece0523a7b7d89b2f": { + "balance": "1970000000000000000000" + }, + "c069ef0eb34299abd2e32dabc47944b272334824": { + "balance": "120000000000000000000" + }, + "28a3da09a8194819ae199f2e6d9d1304817e28a5": { + "balance": "2000000000000000000000" + }, + "e9495ba5842728c0ed97be37d0e422b98d69202c": { + "balance": "2000000000000000000000" + }, + "bba976f1a1215f7512871892d45f7048acd356c8": { + "balance": "2000000000000000000000" + }, + "887cac41cd706f3345f2d34ac34e01752a6e5909": { + "balance": "595366000000000000000" + }, + "e0e0b2e29dde73af75987ee4446c829a189c95bc": { + "balance": "149000000000000000000" + }, + "4a5fae3b0372c230c125d6d470140337ab915656": { + "balance": "1600000000000000000000" + }, + "425177eb74ad0a9d9a5752228147ee6d6356a6e6": { + "balance": "13370000000000000000" + }, + "5db7bba1f9573f24115d8c8c62e9ce8895068e9f": { + "balance": "49984000000000000000" + }, + "fa6a37f018e97967937fc5e8617ba1d786dd5f77": { + "balance": "19999800000000000000000" + }, + "45e3a93e72144ada860cbc56ff85145ada38c6da": { + "balance": "1610000000000000000000" + }, + "67da922effa472a6b124e84ea8f86b24e0f515aa": { + "balance": "20000000000000000000" + }, + "aa9bd4589535db27fa2bc903ca17d679dd654806": { + "balance": "2000000000000000000000" + }, + "16a9e9b73ae98b864d1728798b8766dbc6ea8d12": { + "balance": "957480000000000000000" + }, + "d6580ab5ed4c7dfa506fa6fe64ad5ce129707732": { + "balance": "4000000000000000000000" + }, + "984a7985e3cc7eb5c93691f6f8cc7b8f245d01b2": { + "balance": "6000000000000000000000" + }, + "7746b6c6699c8f34ca2768a820f1ffa4c207fe05": { + "balance": "4000086000000000000000" + }, + "2fa491fb5920a6574ebd289f39c1b2430d2d9a6a": { + "balance": "2000000000000000000000" + }, + "fae76719d97eac41870428e940279d97dd57b2f6": { + "balance": "98500000000000000000000" + }, + "41b2dbd79dda9b864f6a7030275419c39d3efd3b": { + "balance": "3200000000000000000000" + }, + "dd8254121a6e942fc90828f2431f511dad7f32e6": { + "balance": "3018000000000000000000" + }, + "37fac1e6bc122e936dfb84de0c4bef6e0d60c2d7": { + "balance": "2000000000000000000000" + }, + "3a10888b7e149cae272c01302c327d0af01a0b24": { + "balance": "17000000000000000000" + }, + "401354a297952fa972ad383ca07a0a2811d74a71": { + "balance": "14000000000000000000" + }, + "51865db148881951f51251710e82b9be0d7eadb2": { + "balance": "2000000000000000000000" + }, + "bbbd6ecbb5752891b4ceb3cce73a8f477059376f": { + "balance": "36000000000000000000" + }, + "3f236108eec72289bac3a65cd283f95e041d144c": { + "balance": "999925000000000000000" + }, + "dc83b6fd0d512131204707eaf72ea0c8c9bef976": { + "balance": "2000000000000000000000" + }, + "036eeff5ba90a6879a14dff4c5043b18ca0460c9": { + "balance": "100000000000000000000" + }, + "fac5ca94758078fbfccd19db3558da7ee8a0a768": { + "balance": "1017500000000000000000" + }, + "d0d62c47ea60fb90a3639209bbfdd4d933991cc6": { + "balance": "194000000000000000000" + }, + "891cb8238c88e93a1bcf61db49bd82b47a7f4f84": { + "balance": "2680000000000000000000" + }, + "df53003346d65c5e7a646bc034f2b7d32fcbe56a": { + "balance": "2000000000000000000000" + }, + "6e89c51ea6de13e06cdc748b67c4410fe9bcab03": { + "balance": "4000000000000000000000" + }, + "a61cdbadf04b1e54c883de6005fcdf16beb8eb2f": { + "balance": "2000000000000000000000" + }, + "e3951de5aefaf0458768d774c254f7157735e505": { + "balance": "1600930000000000000000" + }, + "f2732cf2c13b8bb8e7492a988f5f89e38273ddc8": { + "balance": "600000000000000000000" + }, + "4752218e54de423f86c0501933917aea08c8fed5": { + "balance": "20000000000000000000000" + }, + "152f4e860ef3ee806a502777a1b8dbc91a907668": { + "balance": "600000000000000000000" + }, + "15b96f30c23b8664e7490651066b00c4391fbf84": { + "balance": "410650000000000000000" + }, + "8693e9b8be94425eef7969bc69f9d42f7cad671e": { + "balance": "1000090000000000000000" + }, + "f41557dfdfb1a1bdcefefe2eba1e21fe0a4a9942": { + "balance": "1970000000000000000000" + }, + "38458e0685573cb4d28f53098829904570179266": { + "balance": "40000000000000000000" + }, + "53e4d9696dcb3f4d7b3f70dcaa4eecb71782ff5c": { + "balance": "200000000000000000000" + }, + "2dca0e449ab646dbdfd393a96662960bcab5ae1e": { + "balance": "40000000000000000000000" + }, + "87d7ac0653ccc67aa9c3469eef4352193f7dbb86": { + "balance": "200000000000000000000000" + }, + "ae9f5c3fbbe0c9bcbf1af8ff74ea280b3a5d8b08": { + "balance": "1730000000000000000000" + }, + "7751f363a0a7fd0533190809ddaf9340d8d11291": { + "balance": "20000000000000000000" + }, + "708a2af425ceb01e87ffc1be54c0f532b20eacd6": { + "balance": "134159000000000000000" + }, + "ac122a03cd058c122e5fe17b872f4877f9df9572": { + "balance": "1969606000000000000000" + }, + "5da4ca88935c27f55c311048840e589e04a8a049": { + "balance": "80000000000000000000" + }, + "e67c2c1665c88338688187629f49e99b60b2d3ba": { + "balance": "200000000000000000000" + }, + "dec82373ade8ebcf2acb6f8bc2414dd7abb70d77": { + "balance": "200000000000000000000" + }, + "47c247f53b9fbeb17bba0703a00c009fdb0f6eae": { + "balance": "20000000000000000000000" + }, + "9a522e52c195bfb7cf5ffaaedb91a3ba7468161d": { + "balance": "1000000000000000000000" + }, + "3159e90c48a915904adfe292b22fa5fd5e72796b": { + "balance": "1008800000000000000000" + }, + "defddfd59b8d2c154eecf5c7c167bf0ba2905d3e": { + "balance": "93588000000000000000" + }, + "ad1d68a038fd2586067ef6d135d9628e79c2c924": { + "balance": "4686168000000000000000" + }, + "038e45eadd3d88b87fe4dab066680522f0dfc8f9": { + "balance": "10000000000000000000000" + }, + "2561ec0f379218fe5ed4e028a3f744aa41754c72": { + "balance": "13370000000000000000" + }, + "b95396daaa490df2569324fcc6623be052f132ca": { + "balance": "2000000000000000000000" + }, + "2376ada90333b1d181084c97e645e810aa5b76f1": { + "balance": "750000000000000000000" + }, + "07800d2f8068e448c79a4f69b1f15ef682aae5f6": { + "balance": "19400000000000000000000" + }, + "adeb204aa0c38e179e81a94ed8b3e7d53047c26b": { + "balance": "608000000000000000000" + }, + "0dc100b107011c7fc0a1339612a16ccec3285208": { + "balance": "2000000000000000000000" + }, + "f0b1340b996f6f0bf0d9561c849caf7f4430befa": { + "balance": "100000000000000000000" + }, + "e1443dbd95cc41237f613a48456988a04f683282": { + "balance": "4000086000000000000000" + }, + "d3c6f1e0f50ec3d2a67e6bcd193ec7ae38f1657f": { + "balance": "6618150000000000000000" + }, + "b68899e7610d4c93a23535bcc448945ba1666f1c": { + "balance": "200000000000000000000" + }, + "a7253763cf4a75df92ca1e766dc4ee8a2745147b": { + "balance": "10740000000000000000000" + }, + "75d67ce14e8d29e8c2ffe381917b930b1aff1a87": { + "balance": "3000000000000000000000" + }, + "493d48bda015a9bfcf1603936eab68024ce551e0": { + "balance": "22528000000000000000" + }, + "7ddd57165c87a2707f025dcfc2508c09834759bc": { + "balance": "1400000000000000000000" + }, + "cff7f89a4d4219a38295251331568210ffc1c134": { + "balance": "1760000000000000000000" + }, + "168d30e53fa681092b52e9bae15a0dcb41a8c9bb": { + "balance": "100000000000000000000" + }, + "99b743d1d9eff90d9a1934b4db21d519d89b4a38": { + "balance": "100000000000000000000" + }, + "a3d0b03cffbb269f796ac29d80bfb07dc7c6ad06": { + "balance": "2000000000000000000000" + }, + "816d9772cf11399116cc1e72c26c6774c9edd739": { + "balance": "200000000000000000000" + }, + "a880e2a8bf88a1a82648b4013c49c4594c433cc8": { + "balance": "4728000000000000000000" + }, + "2a44a7218fe44d65a1b4b7a7d9b1c2c52c8c3e34": { + "balance": "62221355000000000000000" + }, + "cb86edbc8bbb1f9131022be649565ebdb09e32a1": { + "balance": "2000000000000000000000" + }, + "3915eab5ab2e5977d075dec47d96b68b4b5cf515": { + "balance": "61520000000000000000000" + }, + "8165cab0eafb5a328fc41ac64dae715b2eef2c65": { + "balance": "1000000000000000000000" + }, + "416c86b72083d1f8907d84efd2d2d783dffa3efb": { + "balance": "1999944000000000000000" + }, + "c524086d46c8112b128b2faf6f7c7d8160a8386c": { + "balance": "400000000000000000000" + }, + "902d74a157f7d2b9a3378b1f56703730e03a1719": { + "balance": "4000000000000000000000" + }, + "74ef2869cbe608856045d8c2041118579f2236ea": { + "balance": "59724000000000000000" + }, + "af992dd669c0883e5515d3f3112a13f617a4c367": { + "balance": "2000000000000000000000" + }, + "4c6a248fc97d705def495ca20759169ef0d36471": { + "balance": "760000000000000000000" + }, + "974d2f17895f2902049deaaecf09c3046507402d": { + "balance": "14707000000000000000" + }, + "0239b4f21f8e05cd01512b2be7a0e18a6d974607": { + "balance": "1000000000000000000000" + }, + "b97a6733cd5fe99864b3b33460d1672434d5cafd": { + "balance": "1999579000000000000000" + }, + "f558a2b2dd26dd9593aae04531fd3c3cc3854b67": { + "balance": "198000000000000000000" + }, + "b577b6befa054e9c040461855094b002d7f57bd7": { + "balance": "114000000000000000000000" + }, + "73bfe7710f31cab949b7a2604fbf5239cee79015": { + "balance": "2000000000000000000000" + }, + "5717f2d8f18ffcc0e5fe247d3a4219037c3a649c": { + "balance": "3998000000000000000000" + }, + "20707e425d2a11d2c89f391b2b809f556c592421": { + "balance": "2000000000000000000000" + }, + "9a6708ddb8903c289f83fe889c1edcd61f854423": { + "balance": "1000000000000000000000" + }, + "fa27cc49d00b6c987336a875ae39da58fb041b2e": { + "balance": "10000000000000000000000" + }, + "d688e785c98f00f84b3aa1533355c7a258e87948": { + "balance": "500000000000000000000" + }, + "927cb7dc187036b5427bc7e200c5ec450c1d27d4": { + "balance": "216000000000000000000" + }, + "b2bfaa58b5196c5cb7f89de15f479d1838de713d": { + "balance": "21000000000000000000" + }, + "e180de9e86f57bafacd7904f9826b6b4b26337a3": { + "balance": "830400000000000000000" + }, + "a1204dad5f560728a35c0d8fc79481057bf77386": { + "balance": "1000000000000000000000" + }, + "6b0da25af267d7836c226bcae8d872d2ce52c941": { + "balance": "6000000000000000000000" + }, + "0517448dada761cc5ba4033ee881c83037036400": { + "balance": "1998000000000000000000" + }, + "7ed0a5a847bef9a9da7cba1d6411f5c316312619": { + "balance": "39842000000000000000" + }, + "5b5d517029321562111b43086d0b043591109a70": { + "balance": "2600000000000000000000" + }, + "56fc1a7bad4047237ce116146296238e078f93ad": { + "balance": "178000000000000000000" + }, + "6c5422fb4b14e6d98b6091fdec71f1f08640419d": { + "balance": "400000000000000000000" + }, + "108fe8ee2a13da487b22c6ab6d582ea71064d98c": { + "balance": "399800000000000000000" + }, + "0ad3e44d3c001fa290b393617030544108ac6eb9": { + "balance": "1969019000000000000000" + }, + "25aee68d09afb71d8817f3f184ec562f7897b734": { + "balance": "2000000000000000000000" + }, + "c2340a4ca94c9678b7494c3c852528ede5ee529f": { + "balance": "48669000000000000000" + }, + "44901e0d0e08ac3d5e95b8ec9d5e0ff5f12e0393": { + "balance": "417500000000000000000" + }, + "8775a610c502b9f1e6ad4cdadb8ce29bff75f6e4": { + "balance": "600000000000000000000" + }, + "682897bc4f8e89029120fcffb787c01a93e64184": { + "balance": "10000000000000000000000" + }, + "f7acff934b84da0969dc37a8fcf643b7d7fbed41": { + "balance": "1999944000000000000000" + }, + "f05fcd4c0d73aa167e5553c8c0d6d4f2faa39757": { + "balance": "13334000000000000000000" + }, + "c981d312d287d558871edd973abb76b979e5c35e": { + "balance": "1970000000000000000000" + }, + "9da61ccd62bf860656e0325d7157e2f160d93bb5": { + "balance": "4999980000000000000000" + }, + "d284a50382f83a616d39b8a9c0f396e0ebbfa95d": { + "balance": "1000070000000000000000" + }, + "d6cf5c1bcf9da662bcea2255905099f9d6e84dcc": { + "balance": "8349332000000000000000" + }, + "c71b2a3d7135d2a85fb5a571dcbe695e13fc43cd": { + "balance": "1000000000000000000000" + }, + "b22dadd7e1e05232a93237baed98e0df92b1869e": { + "balance": "2000000000000000000000" + }, + "b09fe6d4349b99bc37938054022d54fca366f7af": { + "balance": "200000000000000000000000" + }, + "427e4751c3babe78cff8830886febc10f9908d74": { + "balance": "1970000000000000000000" + }, + "60b358cb3dbefa37f47df2d7365840da8e3bc98c": { + "balance": "20000000000000000000" + }, + "dcd5bca2005395b675fde5035659b26bfefc49ee": { + "balance": "197000000000000000000" + }, + "81186931184137d1192ac88cd3e1e5d0fdb86a74": { + "balance": "2900000000000000000000" + }, + "de212293f8f1d231fa10e609470d512cb8ffc512": { + "balance": "2000000000000000000000" + }, + "1937c5c515057553ccbd46d5866455ce66290284": { + "balance": "1000000000000000000000000" + }, + "592777261e3bd852c48eca95b3a44c5b7f2d422c": { + "balance": "20000000000000000000000" + }, + "bbf84292d954acd9e4072fb860b1504106e077ae": { + "balance": "1500000000000000000000" + }, + "3b4100e30a73b0c734b18ffa8426d19b19312f1a": { + "balance": "55300000000000000000000" + }, + "a03a3dc7c533d1744295be955d61af3f52b51af5": { + "balance": "40000000000000000000" + }, + "4aa148c2c33401e66a2b586e6577c4b292d3f240": { + "balance": "216200000000000000000" + }, + "ff850e3be1eb6a4d726c08fa73aad358f39706da": { + "balance": "1940000000000000000000" + }, + "743651b55ef8429df50cf81938c2508de5c8870f": { + "balance": "2000000000000000000000" + }, + "3700e3027424d939dbde5d42fb78f6c4dbec1a8f": { + "balance": "40000000000000000000" + }, + "c1cbd2e2332a524cf219b10d871ccc20af1fb0fa": { + "balance": "1000000000000000000000" + }, + "e25b9f76b8ad023f057eb11ad94257a0862e4e8c": { + "balance": "2000000000000000000000" + }, + "719e891fbcc0a33e19c12dc0f02039ca05b801df": { + "balance": "6185800000000000000000" + }, + "39636b25811b176abfcfeeca64bc87452f1fdff4": { + "balance": "400000000000000000000" + }, + "631030a5b27b07288a45696f189e1114f12a81c0": { + "balance": "499970000000000000000" + }, + "bcc84597b91e73d5c5b4d69c80ecf146860f779a": { + "balance": "4380000000000000000000" + }, + "095e0174829f34c3781be1a5e38d1541ea439b7f": { + "balance": "6000000000000000000000" + }, + "2e7e05e29edda7e4ae25c5173543efd71f6d3d80": { + "balance": "6000000000000000000000" + }, + "dbb6ac484027041642bbfd8d80f9d0c1cf33c1eb": { + "balance": "2000000000000000000000" + }, + "153c08aa8b96a611ef63c0253e2a4334829e579d": { + "balance": "394000000000000000000" + }, + "10f4bff0caa5027c0a6a2dcfc952824de2940909": { + "balance": "2000000000000000000000" + }, + "2ef869f0350b57d53478d701e3fee529bc911c75": { + "balance": "50000000000000000000" + }, + "70ab34bc17b66f9c3b63f151274f2a727c539263": { + "balance": "2000000000000000000000" + }, + "3201259caf734ad7581c561051ba0bca7fd6946b": { + "balance": "180000000000000000000000" + }, + "84e9cf8166c36abfa49053b7a1ad4036202681ef": { + "balance": "2000000000000000000000" + }, + "4ebc5629f9a6a66b2cf3363ac4895c0348e8bf87": { + "balance": "1000090000000000000000" + }, + "e50b464ac9de35a5618b7cbf254674182b81b97e": { + "balance": "4100000000000000000000" + }, + "2abdf1a637ef6c42a7e2fe217773d677e804ebdd": { + "balance": "5000000000000000000000" + }, + "7a0a78a9cc393f91c3d9e39a6b8c069f075e6bf5": { + "balance": "1337000000000000000000" + }, + "2d9c5fecd2b44fbb6a1ec732ea059f4f1f9d2b5c": { + "balance": "1010694000000000000000" + }, + "7b712c7af11676006a66d2fc5c1ab4c479ce6037": { + "balance": "8000000000000000000000" + }, + "3466f67e39636c01f43b3a21a0e8529325c08624": { + "balance": "842864000000000000000" + }, + "fdd502a74e813bcfa355ceda3c176f6a6871af7f": { + "balance": "400000000000000000000" + }, + "26475419c06d5f147aa597248eb46cf7befa64a5": { + "balance": "1640000000000000000000" + }, + "9243d7762d77287b12638688b9854e88a769b271": { + "balance": "1000000000000000000000" + }, + "723d8baa2551d2addc43c21b45e8af4ca2bfb2c2": { + "balance": "1760000000000000000000" + }, + "f2fbb6d887f8b8cc3a869aba847f3d1f643c53d6": { + "balance": "3999000000000000000000" + }, + "2cdb3944650616e47cb182e060322fa1487978ce": { + "balance": "1820000000000000000000" + }, + "f0d21663d8b0176e05fde1b90ef31f8530fda95f": { + "balance": "1999944000000000000000" + }, + "77cc02f623a9cf98530997ea67d95c3b491859ae": { + "balance": "1354900000000000000000" + }, + "d1b5a454ac3405bb4179208c6c84de006bcb9be9": { + "balance": "500000000000000000000" + }, + "b9920fd0e2c735c256463caa240fb7ac86a93dfa": { + "balance": "1760000000000000000000" + }, + "ed1f1e115a0d60ce02fb25df014d289e3a0cbe7d": { + "balance": "500000000000000000000" + }, + "23e2c6a8be8e0acfa5c4df5e36058bb7cbac5a81": { + "balance": "2000000000000000000000" + }, + "f0be0faf4d7923fc444622d1980cf2d990aab307": { + "balance": "2000000000000000000000" + }, + "0829d0f7bb7c446cfbb0deadb2394d9db7249a87": { + "balance": "40110000000000000000" + }, + "2ecac504b233866eb5a4a99e7bd2901359e43b3d": { + "balance": "20000000000000000000000" + }, + "06d6cb308481c336a6e1a225a912f6e6355940a1": { + "balance": "1760000000000000000000" + }, + "d4879fd12b1f3a27f7e109761b23ca343c48e3d8": { + "balance": "666000000000000000000" + }, + "857f100b1a5930225efc7e9020d78327b41c02cb": { + "balance": "2000000000000000000000" + }, + "3aa42c21b9b31c3e27ccd17e099af679cdf56907": { + "balance": "8000000000000000000000" + }, + "764d5212263aff4a2a14f031f04ec749dc883e45": { + "balance": "1850000000000000000000" + }, + "d03a2da41e868ed3fef5745b96f5eca462ff6fda": { + "balance": "3000000000000000000000" + }, + "4f26690c992b7a312ab12e1385d94acd58288e7b": { + "balance": "14000000000000000000000" + }, + "7b122162c913e7146cad0b7ed37affc92a0bf27f": { + "balance": "1506799000000000000000" + }, + "c87352dba582ee2066b9c002a962e003134f78b1": { + "balance": "500000000000000000000" + }, + "9f4ac9c9e7e24cb2444a0454fa5b9ad9d92d3853": { + "balance": "835000000000000000000" + }, + "ccf62a663f1353ba2ef8e6521dc1ecb673ec8ef7": { + "balance": "152000000000000000000" + }, + "557f5e65e0da33998219ad4e99570545b2a9d511": { + "balance": "11024000000000000000000" + }, + "a5f0077b351f6c505cd515dfa6d2fa7f5c4cd287": { + "balance": "40000000000000000000000" + }, + "79c6002f8452ca157f1317e80a2faf24475559b7": { + "balance": "20000000000000000000" + }, + "3aa07a34a1afc8967d3d1383b96b62cf96d5fa90": { + "balance": "20000000000000000000000" + }, + "7f389c12f3c6164f6446566c77669503c2792527": { + "balance": "98500000000000000000" + }, + "ac4cc256ae74d624ace80db078b2207f57198f6b": { + "balance": "2001000000000000000000" + }, + "823ba7647238d113bce9964a43d0a098118bfe4d": { + "balance": "200000000000000000000" + }, + "f5a7676ad148ae9c1ef8b6f5e5a0c2c473be850b": { + "balance": "200000000000000000000" + }, + "7d34803569e00bd6b59fff081dfa5c0ab4197a62": { + "balance": "1712700000000000000000" + }, + "061ea4877cd08944eb64c2966e9db8dedcfec06b": { + "balance": "1000000000000000000000" + }, + "df37c22e603aedb60a627253c47d8ba866f6d972": { + "balance": "24000000000000000000000" + }, + "529aa002c6962a3a8545027fd8b05f22b5bf9564": { + "balance": "1670000000000000000000" + }, + "eb89a882670909cf377e9e78286ee97ba78d46c2": { + "balance": "802200000000000000000" + }, + "9ac85397792a69d78f286b86432a07aeceb60e64": { + "balance": "14300000000000000000" + }, + "9610592202c282ab9bd8a884518b3e0bd4758137": { + "balance": "268000000000000000000" + }, + "73932709a97f02c98e51b091312865122385ae8e": { + "balance": "1430000000000000000000" + }, + "5ef8c96186b37984cbfe04c598406e3b0ac3171f": { + "balance": "9400000000000000000000" + }, + "b6f78da4f4d041b3bc14bc5ba519a5ba0c32f128": { + "balance": "172326253000000000000000" + }, + "6f0edd23bcd85f6015f9289c28841fe04c83efeb": { + "balance": "19100000000000000000" + }, + "a8a43c009100616cb4ae4e033f1fc5d7e0b6f152": { + "balance": "3939015000000000000000" + }, + "7081fa6baad6cfb7f51b2cca16fb8970991a64ba": { + "balance": "233953000000000000000" + }, + "9de7386dde401ce4c67b71b6553f8aa34ea5a17d": { + "balance": "60000000000000000000" + }, + "54ec7300b81ac84333ed1b033cd5d7a33972e234": { + "balance": "200000000000000000000" + }, + "67a80e0190721f94390d6802729dd12c31a895ad": { + "balance": "1999964000000000000000" + }, + "3a4297da3c555e46c073669d0478fce75f2f790e": { + "balance": "1969606000000000000000" + }, + "c2e0584a71348cc314b73b2029b6230b92dbb116": { + "balance": "2000000000000000000000" + }, + "0a2ade95b2e8c66d8ae6f0ba64ca57d783be6d44": { + "balance": "4000000000000000000000" + }, + "544b5b351d1bc82e9297439948cf4861dac9ae11": { + "balance": "22000000000000000000000" + }, + "3ae62bd271a760637fad79c31c94ff62b4cd12f7": { + "balance": "2000000000000000000000" + }, + "0d8023929d917234ae40512b1aabb5e8a4512771": { + "balance": "148000000000000000000" + }, + "2858acacaf21ea81cab7598fdbd86b452e9e8e15": { + "balance": "666000000000000000000" + }, + "c033b1325a0af45472c25527853b1f1c21fa35de": { + "balance": "2000000000000000000000" + }, + "bbf85aaaa683738f073baef44ac9dc34c4c779ea": { + "balance": "2000000000000000000000" + }, + "6ae57f27917c562a132a4d1bf7ec0ac785832926": { + "balance": "6000000000000000000000" + }, + "88e6f9b247f988f6c0fc14c56f1de53ec69d43cc": { + "balance": "100000000000000000000" + }, + "b72c2a011c0df50fbb6e28b20ae1aad217886790": { + "balance": "4000000000000000000000" + }, + "161caf5a972ace8379a6d0a04ae6e163fe21df2b": { + "balance": "100000000000000000000000" + }, + "2a63590efe9986c3fee09b0a0a338b15bed91f21": { + "balance": "6458400000000000000000" + }, + "50e1c8ec98415bef442618708799437b86e6c205": { + "balance": "6000000000000000000000" + }, + "33f4a6471eb1bca6a9f85b3b4872e10755c82be1": { + "balance": "2000000000000000000000" + }, + "9c49deff47085fc09704caa2dca8c287a9a137da": { + "balance": "8000000000000000000000" + }, + "e1173a247d29d8238df0922f4df25a05f2af77c3": { + "balance": "40007051000000000000000" + }, + "51891b2ccdd2f5a44b2a8bc49a5d9bca6477251c": { + "balance": "310000000000000000000" + }, + "ecaf3350b7ce144d068b186010852c84dd0ce0f0": { + "balance": "2000000000000000000000" + }, + "72393d37b451effb9e1ff3b8552712e2a970d8c2": { + "balance": "985000000000000000000" + }, + "1bbc60bcc80e5cdc35c5416a1f0a40a83dae867b": { + "balance": "2000000000000000000000" + }, + "b8ab39805bd821184f6cbd3d2473347b12bf175c": { + "balance": "118200000000000000000" + }, + "c55a6b4761fd11e8c85f15174d74767cd8bd9a68": { + "balance": "133700000000000000000" + }, + "99d1b585965f406a42a49a1ca70f769e765a3f98": { + "balance": "16700000000000000000000" + }, + "9ab988b505cfee1dbe9cd18e9b5473b9a2d4f536": { + "balance": "320000000000000000000" + }, + "7fef8c38779fb307ec6f044bebe47f3cfae796f1": { + "balance": "168561000000000000000" + }, + "322d6f9a140d213f4c80cd051afe25c620bf4c7d": { + "balance": "20000000000000000000" + }, + "3bd9a06d1bd36c4edd27fc0d1f5b088ddae3c72a": { + "balance": "499970000000000000000" + }, + "5dcdb6b87a503c6d8a3c65c2cf9a9aa883479a1e": { + "balance": "9200000000000000000000" + }, + "6e84c2fd18d8095714a96817189ca21cca62bab1": { + "balance": "340935000000000000000" + }, + "a5bad86509fbe0e0e3c0e93f6d381f1af6e9d481": { + "balance": "6000000000000000000000" + }, + "3954bdfe0bf587c695a305d9244c3d5bdddac9bb": { + "balance": "19187461000000000000000" + }, + "63f0e5a752f79f67124eed633ad3fd2705a397d4": { + "balance": "3940000000000000000000" + }, + "33fd718f0b91b5cec88a5dc15eecf0ecefa4ef3d": { + "balance": "432500000000000000000" + }, + "68027d19558ed7339a08aee8de3559be063ec2ea": { + "balance": "2000000000000000000000" + }, + "96f0462ae6f8b96088f7e9c68c74b9d8ad34b347": { + "balance": "1790000000000000000000" + }, + "f1f391ca92808817b755a8b8f4e2ca08d1fd1108": { + "balance": "6000000000000000000000" + }, + "7fcf5ba6666f966c5448c17bf1cb0bbcd8019b06": { + "balance": "99999000000000000000" + }, + "e9b9a2747510e310241d2ece98f56b3301d757e0": { + "balance": "2000000000000000000000" + }, + "2100381d60a5b54adc09d19683a8f6d5bb4bfbcb": { + "balance": "10000000000000000000000" + }, + "7495ae78c0d90261e2140ef2063104731a60d1ed": { + "balance": "34250000000000000000" + }, + "dc911cf7dc5dd0813656670528e9338e67034786": { + "balance": "2000000000000000000000" + }, + "262aed4bc0f4a4b2c6fb35793e835a49189cdfec": { + "balance": "10000000000000000000000" + }, + "9ee93f339e6726ec65eea44f8a4bfe10da3d3282": { + "balance": "2000000000000000000000" + }, + "a3a57b0716132804d60aac281197ff2b3d237b01": { + "balance": "1400000000000000000000" + }, + "c799e34e88ff88be7de28e15e4f2a63d0b33c4cb": { + "balance": "200000000000000000000" + }, + "c7506c1019121ff08a2c8c1591a65eb4bdfb4a3f": { + "balance": "600000000000000000000" + }, + "795ebc2626fc39b0c86294e0e837dcf523553090": { + "balance": "1000000000000000000000" + }, + "441aca82631324acbfa2468bda325bbd78477bbf": { + "balance": "6000000000000000000000" + }, + "9f271d285500d73846b18f733e25dd8b4f5d4a8b": { + "balance": "722000000000000000000" + }, + "d77892e2273b235d7689e430e7aeed9cbce8a1f3": { + "balance": "2000000000000000000000" + }, + "4f8972838f70c903c9b6c6c46162e99d6216d451": { + "balance": "4610000000000000000000" + }, + "4c85ed362f24f6b9f04cdfccd022ae535147cbb9": { + "balance": "1500000000000000000000" + }, + "3807eff43aa97c76910a19752dd715ee0182d94e": { + "balance": "250190000000000000000" + }, + "3a9e5441d44b243be55b75027a1ceb9eacf50df2": { + "balance": "1000000000000000000000" + }, + "3deae43327913f62808faa1b6276a2bd6368ead9": { + "balance": "2000000000000000000000" + }, + "c270456885342b640b4cfc1b520e1a544ee0d571": { + "balance": "1820000000000000000000" + }, + "77798f201257b9c35204957057b54674aefa51df": { + "balance": "149000000000000000000" + }, + "225f9eb3fb6ff3e9e3c8447e14a66e8d4f3779f6": { + "balance": "2000000000000000000000" + }, + "78df2681d6d602e22142d54116dea15d454957aa": { + "balance": "298000000000000000000" + }, + "283396ce3cac398bcbe7227f323e78ff96d08767": { + "balance": "400000000000000000000" + }, + "747ff7943b71dc4dcdb1668078f83dd7cc4520c2": { + "balance": "60000000000000000000" + }, + "a4ed11b072d89fb136759fc69b428c48aa5d4ced": { + "balance": "262800000000000000000" + }, + "cc043c4388d345f884c6855e71142a9f41fd6935": { + "balance": "20000000000000000000" + }, + "ab14d221e33d544629198cd096ed63dfa28d9f47": { + "balance": "6000000000000000000000" + }, + "251e6838f7cec5b383c1d90146341274daf8e502": { + "balance": "147510000000000000000" + }, + "36a0e61e1be47fa87e30d32888ee0330901ca991": { + "balance": "20000000000000000000" + }, + "bcfc98e5c82b6adb180a3fcb120b9a7690c86a3f": { + "balance": "1970000000000000000000" + }, + "18a6d2fc52be73084023c91802f05bc24a4be09f": { + "balance": "2000000000000000000000" + }, + "80591a42179f34e64d9df75dcd463b28686f5574": { + "balance": "20000000000000000000000" + }, + "881230047c211d2d5b00d8de4c5139de5e3227c7": { + "balance": "10000000000000000000000" + }, + "9eb1ff71798f28d6e989fa1ea0588e27ba86cb7d": { + "balance": "140800000000000000000" + }, + "a01fd1906a908506dedae1e208128872b56ee792": { + "balance": "3000000000000000000000" + }, + "1b05ea6a6ac8af7cb6a8b911a8cce8fe1a2acfc8": { + "balance": "2000000000000000000000" + }, + "6add932193cd38494aa3f03aeccc4b7ab7fabca2": { + "balance": "89600000000000000000" + }, + "2aaa35274d742546670b7426264521032af4f4c3": { + "balance": "10000000000000000000000" + }, + "67b8a6e90fdf0a1cac441793301e8750a9fa7957": { + "balance": "895000000000000000000" + }, + "5b5be0d8c67276baabd8edb30d48ea75640b8b29": { + "balance": "824480000000000000000" + }, + "28d7e5866f1d85fd1ceb32bfbe1dfc36db434566": { + "balance": "7199000000000000000000" + }, + "98e3e90b28fccaee828779b8d40a5568c4116e21": { + "balance": "40000000000000000000" + }, + "2dd578f7407dfbd548d05e95ccc39c485429626a": { + "balance": "4200000000000000000000" + }, + "8ca6989746b06e32e2487461b1ce996a273acfd7": { + "balance": "20000000000000000000" + }, + "a6f93307f8bce03195fece872043e8a03f7bd11a": { + "balance": "2886000000000000000000" + }, + "efbd52f97da5fd3a673a46cbf330447b7e8aad5c": { + "balance": "100033000000000000000" + }, + "52bdd9af5978850bc24110718b3723759b437e59": { + "balance": "1730000000000000000000" + }, + "6e073b66d1b8c66744d88096a8dd99ec7e0228da": { + "balance": "4000000000000000000000" + }, + "a29d661a6376f66d0b74e2fe9d8f26c0247ec84c": { + "balance": "4117300000000000000000" + }, + "7d34ff59ae840a7413c6ba4c5bb2ba2c75eab018": { + "balance": "3000000000000000000000" + }, + "2eca6a3c5d9f449d0956bd43fa7b4d7be8435958": { + "balance": "2000020000000000000000" + }, + "f59f9f02bbc98efe097eabb78210979021898bfd": { + "balance": "9999800000000000000000" + }, + "90e300ac71451e401f887f6e7728851647a80e07": { + "balance": "400000000000000000000" + }, + "05ae7fd4bbcc80ca11a90a1ec7a301f7cccc83db": { + "balance": "910000000000000000000" + }, + "e54102534de8f23effb093b31242ad3b233facfd": { + "balance": "4000000000000000000000" + }, + "c127aab59065a28644a56ba3f15e2eac13da2995": { + "balance": "600000000000000000000" + }, + "ed60c4ab6e540206317e35947a63a9ca6b03e2cb": { + "balance": "57275000000000000000" + }, + "d855b03ccb029a7747b1f07303e0a664793539c8": { + "balance": "2000000000000000000000" + }, + "1178501ff94add1c5881fe886136f6dfdbe61a94": { + "balance": "158000000000000000000" + }, + "f447108b98df64b57e871033885c1ad71db1a3f9": { + "balance": "6916709000000000000000" + }, + "deee2689fa9006b59cf285237de53b3a7fd01438": { + "balance": "450034000000000000000" + }, + "7f01dc7c3747ca608f983dfc8c9b39e755a3b914": { + "balance": "206980000000000000000" + }, + "9edeac4c026b93054dc5b1d6610c6f3960f2ad73": { + "balance": "1200000000000000000000" + }, + "e3cffe239c64e7e20388e622117391301b298696": { + "balance": "500000000000000000000" + }, + "ebbb4f2c3da8be3eb62d1ffb1f950261cf98ecda": { + "balance": "2000000000000000000000" + }, + "38c10b90c859cbb7815692f99dae520ab5febf5e": { + "balance": "13169000000000000000000" + }, + "23f9ecf3e5dddca38815d3e59ed34b5b90b4a353": { + "balance": "204608000000000000000" + }, + "d7fa5ffb6048f96fb1aba09ef87b1c11dd7005e4": { + "balance": "1000000000000000000000" + }, + "9ca42ee7a0b898f6a5cc60b5a5d7b1bfa3c33231": { + "balance": "2000000000000000000000" + }, + "8b9577920053b1a00189304d888010d9ef2cb4bf": { + "balance": "500000000000000000000" + }, + "fcd0b4827cd208ffbf5e759dba8c3cc61d8c2c3c": { + "balance": "8000000000000000000000" + }, + "01ff1eb1dead50a7f2f9638fdee6eccf3a7b2ac8": { + "balance": "600000000000000000000" + }, + "abde147b2af789eaa586547e66c4fa2664d328a4": { + "balance": "247545000000000000000" + }, + "64042ba68b12d4c151651ca2813b7352bd56f08e": { + "balance": "600000000000000000000" + }, + "dccca42045ec3e16508b603fd936e7fd7de5f36a": { + "balance": "19700000000000000000" + }, + "e77a89bd45dc04eeb4e41d7b596b707e6e51e74c": { + "balance": "12000000000000000000000" + }, + "f77c7b845149efba19e261bc7c75157908afa990": { + "balance": "2000000000000000000000" + }, + "fa5201fe1342af11307b9142a041243ca92e2f09": { + "balance": "152150000000000000000000" + }, + "40df495ecf3f8b4cef2a6c189957248fe884bc2b": { + "balance": "12000000000000000000000" + }, + "3d79a853d71be0621b44e29759656ca075fdf409": { + "balance": "2000000000000000000000" + }, + "6de02f2dd67efdb7393402fa9eaacbcf589d2e56": { + "balance": "1182000000000000000000" + }, + "729aad4627744e53f5d66309aa74448b3acdf46f": { + "balance": "2000000000000000000000" + }, + "4e4318f5e13e824a54edfe30a7ed4f26cd3da504": { + "balance": "2000000000000000000000" + }, + "c6a286e065c85f3af74812ed8bd3a8ce5d25e21d": { + "balance": "18200000000000000000" + }, + "fd686de53fa97f99639e2568549720bc588c9efc": { + "balance": "1969606000000000000000" + }, + "06b0ff834073cce1cbc9ea557ea87b605963e8b4": { + "balance": "300000000000000000000" + }, + "72b5633fe477fe542e742facfd690c137854f216": { + "balance": "1670000000000000000000" + }, + "8bf373d076814cbc57e1c6d16a82c5be13c73d37": { + "balance": "200000000000000000000" + }, + "cf264e6925130906c4d7c18591aa41b2a67f6f58": { + "balance": "2000000000000000000000" + }, + "0ea2a210312b3e867ee0d1cc682ce1d666f18ed5": { + "balance": "10000000000000000000000" + }, + "d02afecf8e2ec2b62ac8ad204161fd1fae771d0e": { + "balance": "2000000000000000000000" + }, + "e6b20f980ad853ad04cbfc887ce6601c6be0b24c": { + "balance": "4000000000000000000000" + }, + "4280a58f8bb10b9440de94f42b4f592120820191": { + "balance": "2000000000000000000000" + }, + "a914cdb571bfd93d64da66a4e108ea134e50d000": { + "balance": "1430143000000000000000" + }, + "60864236930d04d8402b5dcbeb807f3caf611ea2": { + "balance": "4000000000000000000000" + }, + "f9dd239008182fb519fb30eedd2093fed1639be8": { + "balance": "500000000000000000000" + }, + "18e53243981aabc8767da10c73449f1391560eaa": { + "balance": "6000000000000000000000" + }, + "c3a9226ae275df2cab312b911040634a9c9c9ef6": { + "balance": "4000000000000000000000" + }, + "4fcc19ea9f4c57dcbce893193cfb166aa914edc5": { + "balance": "7001380000000000000000" + }, + "c1e1409ca52c25435134d006c2a6a8542dfb7273": { + "balance": "34380000000000000000" + }, + "981ddf0404e4d22dda556a0726f00b2d98ab9569": { + "balance": "999972000000000000000" + }, + "e5bcc88c3b256f6ed5fe550e4a18198b943356ad": { + "balance": "2000000000000000000000" + }, + "74a17f064b344e84db6365da9591ff1628257643": { + "balance": "20000000000000000000" + }, + "2720f9ca426ef2f2cbd2fecd39920c4f1a89e16d": { + "balance": "2000000000000000000000" + }, + "8d04a5ebfb5db409db0617c9fa5631c192861f4a": { + "balance": "970000000000000000000" + }, + "f18b14cbf6694336d0fe12ac1f25df2da0c05dbb": { + "balance": "3999800000000000000000" + }, + "56ac20d63bd803595cec036da7ed1dc66e0a9e07": { + "balance": "63927000000000000000" + }, + "92c94c2820dfcf7156e6f13088ece7958b3676fd": { + "balance": "95500000000000000000" + }, + "968dea60df3e09ae3c8d3505e9c080454be0e819": { + "balance": "6000000000000000000000" + }, + "9268d62646563611dc3b832a30aa2394c64613e3": { + "balance": "2000000000000000000000" + }, + "5a192b964afd80773e5f5eda6a56f14e25e0c6f3": { + "balance": "500000000000000000000" + }, + "df8d48b1eb07b3c217790e6c2df04dc319e7e848": { + "balance": "500000000000000000000" + }, + "7f61fa6cf5f898b440dac5abd8600d6d691fdef9": { + "balance": "280000000000000000000" + }, + "929d368eb46a2d1fbdc8ffa0607ede4ba88f59ad": { + "balance": "2000000000000000000000" + }, + "9982a5890ffb5406d3aca8d2bfc1dd70aaa80ae0": { + "balance": "2000000000000000000000" + }, + "bf2aea5a1dcf6ed3b5e8323944e983fedfd1acfb": { + "balance": "1580000000000000000000" + }, + "46aa501870677e7f0a504876b4e8801a0ad01c46": { + "balance": "800000000000000000000" + }, + "8f473d0ab876ddaa15608621d7013e6ff714b675": { + "balance": "470400000000000000000" + }, + "02290fb5f9a517f82845acdeca0fc846039be233": { + "balance": "2000000000000000000000" + }, + "8a5831282ce14a657a730dc18826f7f9b99db968": { + "balance": "4330268000000000000000" + }, + "0328510c09dbcd85194a98d67c33ac49f2f94d60": { + "balance": "11000000000000000000000" + }, + "cf883a20329667ea226a1e3c765dbb6bab32219f": { + "balance": "3038972000000000000000" + }, + "2615100ea7e25bba9bca746058afbbb4ffbe4244": { + "balance": "500000000000000000000" + }, + "b115ee3ab7641e1aa6d000e41bfc1ec7210c2f32": { + "balance": "13000000000000000000000" + }, + "5cfa8d568575658ca4c1a593ac4c5d0e44c60745": { + "balance": "291000000000000000000" + }, + "d3c24d4b3a5e0ff8a4622d518edd73f16ab28610": { + "balance": "20000000000000000000" + }, + "a639acd96b31ba53b0d08763229e1f06fd105e9d": { + "balance": "8000000000000000000000" + }, + "ffa4aff1a37f984b0a67272149273ae9bd41e3bc": { + "balance": "10000000000000000000000" + }, + "cf684dfb8304729355b58315e8019b1aa2ad1bac": { + "balance": "432500000000000000000" + }, + "5797b60fd2894ab3c2f4aede86daf2e788d745ad": { + "balance": "6000000000000000000000" + }, + "a6a0de421ae54f6d17281308f5646d2f39f7775d": { + "balance": "2000000000000000000000" + }, + "08504f05643fab5919f5eea55925d7a3ed7d807a": { + "balance": "20000000000000000000" + }, + "7a7068e1c3375c0e599db1fbe6b2ea23b8f407d2": { + "balance": "2000000000000000000000" + }, + "1078d7f61b0e56c74ee6635b2e1819ef1e3d8785": { + "balance": "1000000000000000000000" + }, + "6e12b51e225b4a4372e59ad7a2a1a13ea3d3a137": { + "balance": "14172200000000000000000" + }, + "6a2e86469a5bf37cee82e88b4c3863895d28fcaf": { + "balance": "519000000000000000000" + }, + "197672fd39d6f246ce66a790d13aa922d70ea109": { + "balance": "1000000000000000000000" + }, + "8009a7cbd192b3aed4adb983d5284552c16c7451": { + "balance": "4000000000000000000000" + }, + "f6c3c48a1ac0a34799f04db86ec7a975fe7768f3": { + "balance": "1970000000000000000000" + }, + "16be75e98a995a395222d00bd79ff4b6e638e191": { + "balance": "36000000000000000000000" + }, + "6c05e34e5ef2f42ed09deff1026cd66bcb6960bb": { + "balance": "2000000000000000000000" + }, + "5d6ae8cbd6b3393c22d16254100d0238e808147c": { + "balance": "719992000000000000000" + }, + "1a376e1b2d2f590769bb858d4575320d4e149970": { + "balance": "4841200000000000000000" + }, + "f6ead67dbf5b7eb13358e10f36189d53e643cfcf": { + "balance": "40000000000000000000000" + }, + "467d5988249a68614716659840ed0ae6f6f457bc": { + "balance": "387500000000000000000" + }, + "aa960e10c52391c54e15387cc67af827b5316dcc": { + "balance": "2000000000000000000000" + }, + "483ba99034e900e3aedf61499d3b2bce39beb7aa": { + "balance": "985000000000000000000" + }, + "86f23e9c0aafc78b9c404dcd60339a925bffa266": { + "balance": "400000000000000000000" + }, + "d05a447c911dbb275bfb2e5a37e5a703a56f9997": { + "balance": "200000000000000000000" + }, + "edb71ec41bda7dce86e766e6e8c3e9907723a69b": { + "balance": "20000000000000000000" + }, + "f86a3ea8071f7095c7db8a05ae507a8929dbb876": { + "balance": "336000000000000000000" + }, + "323b3cfe3ee62bbde2a261e53cb3ecc05810f2c6": { + "balance": "13790000000000000000000" + }, + "936f3813f5f6a13b8e4ffec83fe7f826186a71cd": { + "balance": "520000000000000000000" + }, + "6db72bfd43fef465ca5632b45aab7261404e13bf": { + "balance": "2000000000000000000000" + }, + "9bb76204186af2f63be79168601687fc9bad661f": { + "balance": "300000000000000000000" + }, + "28ab165ffb69eda0c549ae38e9826f5f7f92f853": { + "balance": "1296890000000000000000" + }, + "c73e2112282215dc0762f32b7e807dcd1a7aae3e": { + "balance": "6900000000000000000000" + }, + "f8086e42661ea929d2dda1ab6c748ce3055d111e": { + "balance": "1000000000000000000000" + }, + "4db21284bcd4f787a7556500d6d7d8f36623cf35": { + "balance": "1939806000000000000000" + }, + "c48651c1d9c16bff4c9554886c3f3f26431f6f68": { + "balance": "658000000000000000000" + }, + "9bdbdc9b973431d13c89a3f9757e9b3b6275bfc7": { + "balance": "499971000000000000000" + }, + "560da37e956d862f81a75fd580a7135c1b246352": { + "balance": "10000000000000000000000" + }, + "4b60a3e253bf38c8d5662010bb93a473c965c3e5": { + "balance": "1490000000000000000000" + }, + "64e02abb016cc23a2934f6bcddb681905021d563": { + "balance": "1000000000000000000000" + }, + "ac2c8e09d06493a63858437bd20be01962450365": { + "balance": "1910000000000000000000" + }, + "9bf9b3b2f23cf461eb591f28340bc719931c8364": { + "balance": "1000000000000000000000" + }, + "9b5c39f7e0ac168c8ed0ed340477117d1b682ee9": { + "balance": "98000000000000000000" + }, + "f75bb39c799779ebc04a336d260da63146ed98d0": { + "balance": "25000000000000000000" + }, + "a7966c489f4c748a7ae980aa27a574251767caf9": { + "balance": "3000000000000000000000" + }, + "ea53c954f4ed97fd4810111bdab69ef981ef25b9": { + "balance": "17300000000000000000000" + }, + "03a26cfc4c18316f70d59e9e1a79ee3e8b962f4c": { + "balance": "2000000000000000000000" + }, + "3e63ce3b24ca2865b4c5a687b7aea3597ef6e548": { + "balance": "2000000000000000000000" + }, + "500c902958f6421594d1b6ded712490d52ed6c44": { + "balance": "1970000000000000000000" + }, + "6f44ca09f0c6a8294cbd519cdc594ad42c67579f": { + "balance": "50000000000000000000" + }, + "3616fb46c81578c9c8eb4d3bf880451a88379d7d": { + "balance": "200000000000000000000" + }, + "57bc20e2d62b3d19663cdb4c309d5b4f2fc2db8f": { + "balance": "100000000000000000000" + }, + "1cebf0985d7f680aaa915c44cc62edb49eab269e": { + "balance": "1000000000000000000000" + }, + "c0cbf6032fa39e7c46ff778a94f7d445fe22cf30": { + "balance": "310000000000000000000" + }, + "c58b9cc61dedbb98c33f224d271f0e228b583433": { + "balance": "3880000000000000000000" + }, + "e9c6dfae97f7099fc5f4e94b784db802923a1419": { + "balance": "48800000000000000000" + }, + "9bacd3d40f3b82ac91a264d9d88d908eac8664b9": { + "balance": "20000000000000000000000" + }, + "63d80048877596e0c28489e650cd4ac180096a49": { + "balance": "280000000000000000000" + }, + "e6a6f6dd6f70a456f4ec15ef7ad5e5dbb68bd7dc": { + "balance": "200000000000000000000" + }, + "d418870bc2e4fa7b8a6121ae0872d55247b62501": { + "balance": "1580000000000000000000" + }, + "e2f9383d5810ea7b43182b8704b62b27f5925d39": { + "balance": "400000000000000000000" + }, + "bd5e473abce8f97a6932f77c2facaf9cc0a00514": { + "balance": "1117350000000000000000" + }, + "2ff1ca55fd9cec1b1fe9f0a9abb74c513c1e2aaa": { + "balance": "3000000000000000000000" + }, + "9d99b189bbd9a48fc2e16e8fcda33bb99a317bbb": { + "balance": "1126900000000000000000" + }, + "6e96faeda3054302c45f58f161324c99a3eebb62": { + "balance": "20000000000000000000" + }, + "ef93818f684db0c3675ec81332b3183ecc28a495": { + "balance": "1550000000000000000000" + }, + "2659facb1e83436553b5b42989adb8075f9953ed": { + "balance": "29356000000000000000" + }, + "c4ffadaaf2823fbea7bff702021bffc4853eb5c9": { + "balance": "42233000000000000000" + }, + "e9864c1afc8eaad37f3ba56fcb7477cc622009b7": { + "balance": "79000000000000000000" + }, + "87ef6d8b6a7cbf9b5c8c97f67ee2adc2a73b3f77": { + "balance": "200400000000000000000" + }, + "c043f2452dcb9602ef62bd360e033dd23971fe84": { + "balance": "2000000000000000000000" + }, + "0fdd65402395df9bd19fee4507ef5345f745104c": { + "balance": "5000000000000000000000" + }, + "939c4313d2280edf5e071bced846063f0a975d54": { + "balance": "120000000000000000000000" + }, + "b28245037cb192f75785cb86cbfe7c930da258b0": { + "balance": "16000000000000000000000" + }, + "a80cb1738bac08d4f9c08b4deff515545fa8584f": { + "balance": "500000000000000000000" + }, + "62971bf2634cee0be3c9890f51a56099dbb9519b": { + "balance": "656000000000000000000" + }, + "f2efe96560c9d97b72bd36447843885c1d90c231": { + "balance": "2000000000000000000000" + }, + "0e390f44053ddfcef0d608b35e4d9c2cbe9871bb": { + "balance": "1970000000000000000000" + }, + "61d101a033ee0e2ebb3100ede766df1ad0244954": { + "balance": "500000000000000000000" + }, + "6785513cf732e47e87670770b5419be10cd1fc74": { + "balance": "2000000000000000000000" + }, + "167699f48a78c615512515739958993312574f07": { + "balance": "39000000000000000000" + }, + "68ec79d5be7155716c40941c79d78d17de9ef803": { + "balance": "500600000000000000000" + }, + "a0e8ba661b48154cf843d4c2a5c0f792d528ee29": { + "balance": "400000000000000000000" + }, + "1a201b4327cea7f399046246a3c87e6e03a3cda8": { + "balance": "1000000000000000000000" + }, + "f60f62d73937953fef35169e11d872d2ea317eec": { + "balance": "5348000000000000000000" + }, + "c0c04d0106810e3ec0e54a19f2ab8597e69a573d": { + "balance": "50000000000000000000" + }, + "ef47cf073e36f271d522d7fa4e7120ad5007a0bc": { + "balance": "2500000000000000000000" + }, + "a44fe800d96fcad73b7170d0f610cb8c0682d6ce": { + "balance": "4000000000000000000000" + }, + "010f4a98dfa1d9799bf5c796fb550efbe7ecd877": { + "balance": "8023366000000000000000" + }, + "708fa11fe33d85ad1befcbae3818acb71f6a7d7e": { + "balance": "18200000000000000000" + }, + "b38c4e537b5df930d65a74d043831d6b485bbde4": { + "balance": "400000000000000000000" + }, + "250a69430776f6347703f9529783955a6197b682": { + "balance": "1940000000000000000000" + }, + "2d35a9df62757f7ffad1049afb06ca4afc464c51": { + "balance": "20000000000000000000" + }, + "6aff1466c2623675e3cb0e75e423d37a25e442eb": { + "balance": "1730000000000000000000" + }, + "fc15cb99a8d1030b12770add033a79ee0d0c908c": { + "balance": "350056000000000000000" + }, + "e784dcc873aa8c1513ec26ff36bc92eac6d4c968": { + "balance": "200000000000000000000" + }, + "b1c328fb98f2f19ab6646f0a7c8c566fda5a8540": { + "balance": "2500000000000000000000" + }, + "247a0a11c57f0383b949de540b66dee68604b0a1": { + "balance": "1069600000000000000000" + }, + "1af60343360e0b2d75255210375720df21db5c7d": { + "balance": "1000000000000000000000" + }, + "8794bf47d54540ece5c72237a1ffb511ddb74762": { + "balance": "2000000000000000000000" + }, + "e76d945aa89df1e457aa342b31028a5e9130b2ce": { + "balance": "1015200000000000000000" + }, + "a30e0acb534c9b3084e8501da090b4eb16a2c0cd": { + "balance": "2000000000000000000000" + }, + "7099d12f6ec656899b049a7657065d62996892c8": { + "balance": "400000000000000000000" + }, + "7be7f2456971883b9a8dbe4c91dec08ac34e8862": { + "balance": "3000000000000000000000" + }, + "42746aeea14f27beff0c0da64253f1e7971890a0": { + "balance": "1550000000000000000000" + }, + "736b44503dd2f6dd5469ff4c5b2db8ea4fec65d0": { + "balance": "313950000000000000000" + }, + "822edff636563a6106e52e9a2598f7e6d0ef2782": { + "balance": "36099000000000000000" + }, + "03c647a9f929b0781fe9ae01caa3e183e876777e": { + "balance": "445800000000000000000" + }, + "63612e7862c27b587cfb6daf9912cb051f030a9f": { + "balance": "43458000000000000000" + }, + "d46bae61b027e5bb422e83a3f9c93f3c8fc77d27": { + "balance": "2000000000000000000000" + }, + "5f23ba1f37a96c45bc490259538a54c28ba3b0d5": { + "balance": "1200000000000000000000" + }, + "d41d7fb49fe701baac257170426cc9b38ca3a9b2": { + "balance": "176000000000000000000" + }, + "1ebacb7844fdc322f805904fbf1962802db1537c": { + "balance": "10000000000000000000000" + }, + "9c80bc18e9f8d4968b185da8c79fa6e11ffc3e23": { + "balance": "240000000000000000000" + }, + "e4ca0a5238564dfc91e8bf22bade2901619a1cd4": { + "balance": "1000000000000000000000" + }, + "1ad72d20a76e7fcc6b764058f48d417d496fa6cd": { + "balance": "2000000000000000000000" + }, + "d3bc730937fa75d8452616ad1ef1fe7fffe0d0e7": { + "balance": "83363000000000000000" + }, + "eac1482826acb6111e19d340a45fb851576bed60": { + "balance": "32177000000000000000" + }, + "01e40521122530d9ac91113c06a0190b6d63850b": { + "balance": "1337000000000000000000" + }, + "9e20e5fd361eabcf63891f5b87b09268b8eb3793": { + "balance": "100000000000000000000" + }, + "69ff429074cb9b6c63bc914284bce5f0c8fbf7d0": { + "balance": "500000000000000000000" + }, + "0d3265d3e7bdb93d5e8e8b1ca47f210a793ecc8e": { + "balance": "200000000000000000000" + }, + "5b4ea16db6809b0352d4b6e81c3913f76a51bb32": { + "balance": "400000000000000000000" + }, + "d8fe088fffce948f5137ee23b01d959e84ac4223": { + "balance": "227942000000000000000" + }, + "7e4e9409704121d1d77997026ff06ea9b19a8b90": { + "balance": "2602600000000000000000" + }, + "96b434fe0657e42acc8212b6865139dede15979c": { + "balance": "4000000000000000000000" + }, + "22f004df8de9e6ebf523ccace457accb26f97281": { + "balance": "10000000000000000000000" + }, + "d8f9240c55cff035523c6d5bd300d370dc8f0c95": { + "balance": "285000000000000000000" + }, + "9d9e57fde30e5068c03e49848edce343b7028358": { + "balance": "1730000000000000000000" + }, + "317cf4a23cb191cdc56312c29d15e210b3b9b784": { + "balance": "144000000000000000000" + }, + "79f08e01ce0988e63c7f8f2908fade43c7f9f5c9": { + "balance": "18200000000000000000" + }, + "04e5f5bc7c923fd1e31735e72ef968fd67110c6e": { + "balance": "1611000000000000000000" + }, + "1ec4ec4b77bf19d091a868e6f49154180541f90e": { + "balance": "2000000000000000000000" + }, + "8737dae671823a8d5917e0157ace9c43468d946b": { + "balance": "1999944000000000000000" + }, + "f998ca3411730a6cd10e7455b0410fb0f6d3ff80": { + "balance": "2000000000000000000000" + }, + "6e2eab85dc89fe29dc0aa1853247dab43a523d56": { + "balance": "80000000000000000000" + }, + "72c083beadbdc227c5fb43881597e32e83c26056": { + "balance": "20000000000000000000000" + }, + "5902e44af769a87246a21e079c08bf36b06efeb3": { + "balance": "1000000000000000000000" + }, + "cc2d04f0a4017189b340ca77198641dcf6456b91": { + "balance": "3940000000000000000000" + }, + "bde4c73f969b89e9ceae66a2b51844480e038e9a": { + "balance": "1000000000000000000000" + }, + "adff0d1d0b97471e76d789d2e49c8a74f9bd54ff": { + "balance": "1880000000000000000000" + }, + "397cdb8c80c67950b18d654229610e93bfa6ee1a": { + "balance": "1172938000000000000000" + }, + "a3e051fb744aa3410c3b88f899f5d57f168df12d": { + "balance": "2955000000000000000000" + }, + "810db25675f45ea4c7f3177f37ce29e22d67999c": { + "balance": "200000000000000000000" + }, + "1e13ec51142cebb7a26083412c3ce35144ba56a1": { + "balance": "5000000000000000000000" + }, + "25bdfa3ee26f3849617b230062588a97e3cae701": { + "balance": "1000008000000000000000" + }, + "ae538c73c5b38d8d584d7ebdadefb15cabe48357": { + "balance": "999000000000000000000" + }, + "a2ecce2c49f72a0995a0bda57aacf1e9f001e22a": { + "balance": "4000000000000000000000" + }, + "7e24fbdad290175eb2df6d180a19b9a9f41370be": { + "balance": "1000000000000000000000" + }, + "e8cc43bc4f8acf39bff04ebfbf42aac06a328470": { + "balance": "400000000000000000000" + }, + "c2779771f0536d79a8708f6931abc44b3035e999": { + "balance": "20002000000000000000000" + }, + "ab27ba78c8e5e3daef31ad05aef0ff0325721e08": { + "balance": "468000000000000000000" + }, + "563cb8803c1d32a25b27b64114852bd04d9c20cd": { + "balance": "204400000000000000000" + }, + "08d4267feb15da9700f7ccc3c84a8918bf17cfde": { + "balance": "1790000000000000000000" + }, + "d1778c13fbd968bc083cb7d1024ffe1f49d02caa": { + "balance": "4020000000000000000000" + }, + "1796bcc97b8abc717f4b4a7c6b1036ea2182639f": { + "balance": "355242000000000000000" + }, + "beecd6af900c8b064afcc6073f2d85d59af11956": { + "balance": "2000000000000000000000" + }, + "045ed7f6d9ee9f252e073268db022c6326adfc5b": { + "balance": "100000000000000000000" + }, + "b88a37c27f78a617d5c091b7d5b73a3761e65f2a": { + "balance": "2000000000000000000000" + }, + "72fb49c29d23a18950c4b2dc0ddf410f532d6f53": { + "balance": "2000000000000000000000" + }, + "6ecaefa6fc3ee534626db02c6f85a0c395571e77": { + "balance": "600000000000000000000" + }, + "d1811c55976980f083901d8a0db269222dfb5cfe": { + "balance": "1550000000000000000000" + }, + "98855c7dfbee335344904a12c40c731795b13a54": { + "balance": "1069600000000000000000" + }, + "92a898d46f19719c38126a8a3c27867ae2cee596": { + "balance": "2000000000000000000000" + }, + "ca428863a5ca30369892d612183ef9fb1a04bcea": { + "balance": "1520000000000000000000" + }, + "797427e3dbf0feae7a2506f12df1dc40326e8505": { + "balance": "1000000000000000000000" + }, + "3d574fcf00fae1d98cc8bf9ddfa1b3953b9741bc": { + "balance": "1970000000000000000000" + }, + "28818e18b610001321b31df6fe7d2815cdadc9f5": { + "balance": "1000000000000000000000" + }, + "5f3e1e6739b0c62200e00a003691d9efb238d89f": { + "balance": "3000000000000000000000" + }, + "d9d370fec63576ab15b318bf9e58364dc2a3552a": { + "balance": "100000000000000000000" + }, + "b223bf1fbf80485ca2b5567d98db7bc3534dd669": { + "balance": "4000000000000000000000" + }, + "7b27d0d1f3dd3c140294d0488b783ebf4015277d": { + "balance": "400000000000000000000" + }, + "7930c2d9cbfa87f510f8f98777ff8a8448ca5629": { + "balance": "199955000000000000000" + }, + "820c19291196505b65059d9914b7090be1db87de": { + "balance": "140000000000000000000" + }, + "e545ee84ea48e564161e9482d59bcf406a602ca2": { + "balance": "1850000000000000000000" + }, + "af4cf41785161f571d0ca69c94f8021f41294eca": { + "balance": "9850000000000000000000" + }, + "7a4f9b850690c7c94600dbee0ca4b0a411e9c221": { + "balance": "1910000000000000000000" + }, + "ddab6b51a9030b40fb95cf0b748a059c2417bec7": { + "balance": "2000000000000000000000" + }, + "315ef2da620fd330d12ee55de5f329a696e0a968": { + "balance": "150000000000000000000" + }, + "4db1c43a0f834d7d0478b8960767ec1ac44c9aeb": { + "balance": "872870000000000000000" + }, + "2fef81478a4b2e8098db5ff387ba2153f4e22b79": { + "balance": "999000000000000000000" + }, + "6c6aa0d30b64721990b9504a863fa0bfb5e57da7": { + "balance": "2700000000000000000000" + }, + "33380c6fff5acd2651309629db9a71bf3f20c5ba": { + "balance": "16100000000000000000000" + }, + "4eebf1205d0cc20cee6c7f8ff3115f56d48fba26": { + "balance": "19400000000000000000" + }, + "03cc9d2d21f86b84ac8ceaf971dba78a90e62570": { + "balance": "1610000000000000000000" + }, + "728f9ab080157db3073156dbca1a169ef3179407": { + "balance": "500000000000000000000" + }, + "30ed11b77bc17e5e6694c8bc5b6e4798f68d9ca7": { + "balance": "143731500000000000000000" + }, + "f617b967b9bd485f7695d2ef51fb7792d898f500": { + "balance": "500000000000000000000" + }, + "c0cbad3ccdf654da22cbcf5c786597ca1955c115": { + "balance": "2000000000000000000000" + }, + "80522ddf944ec52e27d724ed4c93e1f7be6083d6": { + "balance": "200000000000000000000" + }, + "4e90ccb13258acaa9f4febc0a34292f95991e230": { + "balance": "15800000000000000000" + }, + "ff207308ced238a6c01ad0213ca9eb4465d42590": { + "balance": "1999944000000000000000" + }, + "35f2949cf78bc219bb4f01907cf3b4b3d3865482": { + "balance": "289800000000000000000" + }, + "68f525921dc11c329b754fbf3e529fc723c834cd": { + "balance": "1610000000000000000000" + }, + "81139bfdcca656c430203f72958c543b6580d40c": { + "balance": "2000000000000000000000" + }, + "9d511543b3d9dc60d47f09d49d01b6c498d82078": { + "balance": "11245000000000000000000" + }, + "084d103254759b343cb2b9c2d8ff9e1ac5f14596": { + "balance": "7600000000000000000000" + }, + "b323dcbf2eddc5382ee4bbbb201ca3931be8b438": { + "balance": "2000000000000000000000" + }, + "349d2c918fd09e2807318e66ce432909176bd50b": { + "balance": "1120000000000000000000" + }, + "b535f8db879fc67fec58824a5cbe6e5498aba692": { + "balance": "1910000000000000000000" + }, + "824074312806da4748434266ee002140e3819ac2": { + "balance": "1507000000000000000000" + }, + "e8ef100d7ce0895832f2678df72d4acf8c28b8e3": { + "balance": "500038000000000000000" + }, + "84af1b157342d54368260d17876230a534b54b0e": { + "balance": "985000000000000000000" + }, + "419a71a36c11d105e0f2aef5a3e598078e85c80b": { + "balance": "5000000000000000000000" + }, + "55af092f94ba6a79918b0cf939eab3f01b3f51c7": { + "balance": "149940000000000000000" + }, + "35a549e8fd6c368d6dcca6d2e7d18e4db95f5284": { + "balance": "499938000000000000000" + }, + "f0e2649c7e6a3f2c5dfe33bbfbd927ca3c350a58": { + "balance": "2000000000000000000000" + }, + "f4b759cc8a1c75f80849ebbcda878dc8f0d66de4": { + "balance": "400000000000000000000" + }, + "21846f2fdf5a41ed8df36e5ed8544df75988ece3": { + "balance": "1999944000000000000000" + }, + "229ff80bf5708009a9f739e0f8b560914016d5a6": { + "balance": "333333000000000000000" + }, + "da505537537ffb33c415fec64e69bae090c5f60f": { + "balance": "160000000000000000000" + }, + "b91d9e916cd40d193db60e79202778a0087716fc": { + "balance": "404800000000000000000" + }, + "bb6823a1bd819f13515538264a2de052b4442208": { + "balance": "25610000000000000000" + }, + "459393d63a063ef3721e16bd9fde45ee9dbd77fb": { + "balance": "1968818000000000000000" + }, + "95f62d0243ede61dad9a3165f53905270d54e242": { + "balance": "1610000000000000000000" + }, + "b0bb29a861ea1d424d45acd4bfc492fb8ed809b7": { + "balance": "80000000000000000000" + }, + "5e74ed80e9655788e1bb269752319667fe754e5a": { + "balance": "56000000000000000000" + }, + "a276b058cb98d88beedb67e543506c9a0d9470d8": { + "balance": "2668652000000000000000" + }, + "8ae9ef8c8a8adfa6ab798ab2cdc405082a1bbb70": { + "balance": "2000000000000000000000" + }, + "e5102c3b711b810344197419b1cd8a7059f13e32": { + "balance": "299999000000000000000" + }, + "c32038ca52aee19745be5c31fcdc54148bb2c4d0": { + "balance": "49984000000000000000" + }, + "13e321728c9c57628058e93fc866a032dd0bda90": { + "balance": "714580000000000000000" + }, + "c2bae4a233c2d85724f0dabebda0249d833e37d3": { + "balance": "5000000000000000000000" + }, + "10d32416722ca4e648630548ead91edd79c06aff": { + "balance": "100000000000000000000" + }, + "d5f07552b5c693c20067b378b809cee853b8f136": { + "balance": "505540000000000000000" + }, + "8668af868a1e98885f937f2615ded6751804eb2d": { + "balance": "20000000000000000000" + }, + "139d3531c9922ad56269f6309aa789fb2485f98c": { + "balance": "4000000000000000000000" + }, + "1d29c7aab42b2048d2b25225d498dba67a03fbb2": { + "balance": "200000000000000000000" + }, + "d35075ca61fe59d123969c36a82d1ab2d918aa38": { + "balance": "2674000000000000000000" + }, + "d6fc0446c6a8d40ae3551db7e701d1fa876e4a49": { + "balance": "2000000000000000000000" + }, + "fccd0d1ecee27addea95f6857aeec8c7a04b28ee": { + "balance": "10000000000000000000000" + }, + "c12cfb7b3df70fceca0ede263500e27873f8ed16": { + "balance": "1000000000000000000000" + }, + "d0db456178206f5c4430fe005063903c3d7a49a7": { + "balance": "706245000000000000000" + }, + "73cf80ae9688e1580e68e782cd0811f7aa494d2c": { + "balance": "7760000000000000000000" + }, + "d60651e393783423e5cc1bc5f889e44ef7ea243e": { + "balance": "398800000000000000000" + }, + "048a8970ea4145c64d5517b8de5b46d0595aad06": { + "balance": "20000000000000000000000" + }, + "dd9b485a3b1cd33a6a9c62f1e5bee92701856d25": { + "balance": "225073000000000000000" + }, + "5b287c7e734299e727626f93fb1187a60d5057fe": { + "balance": "101230000000000000000" + }, + "635c00fdf035bca15fa3610df3384e0fb79068b1": { + "balance": "9000000000000000000000" + }, + "630a913a9031c9492abd4c41dbb15054cfec4416": { + "balance": "5688000000000000000000" + }, + "af3614dcb68a36e45a4e911e62796247222d595b": { + "balance": "2259800000000000000000" + }, + "335e22025b7a77c3a074c78b8e3dfe071341946e": { + "balance": "10178744000000000000000" + }, + "f0e1dfa42adeac2f17f6fdf584c94862fd563393": { + "balance": "500000000000000000000" + }, + "1a9e702f385dcd105e8b9fa428eea21c57ff528a": { + "balance": "1400000000000000000000" + }, + "8ce4949d8a16542d423c17984e6739fa72ceb177": { + "balance": "24999975000000000000000" + }, + "5f29c9de765dde25852af07d33f2ce468fd20982": { + "balance": "2000000000000000000000" + }, + "dbf5f061a0f48e5e69618739a77d2ec19768d201": { + "balance": "152000000000000000000" + }, + "b247cf9c72ec482af3eaa759658f793d670a570c": { + "balance": "912000000000000000000" + }, + "99f4147ccc6bcb80cc842e69f6d00e30fa4133d9": { + "balance": "400000000000000000000" + }, + "ba6d31b9a261d640b5dea51ef2162c3109f1eba8": { + "balance": "5000000000000000000000" + }, + "f05ba8d7b68539d933300bc9289c3d9474d0419e": { + "balance": "126400000000000000000" + }, + "682e96276f518d31d7e56e30dfb009c1218201bd": { + "balance": "20000000000000000000" + }, + "0927220492194b2eda9fc4bbe38f25d681dfd36c": { + "balance": "6000000000000000000000" + }, + "a3c33afc8cb4704e23153de2049d35ae71332472": { + "balance": "799600000000000000000" + }, + "05c736d365aa37b5c0be9c12c8ad5cd903c32cf9": { + "balance": "6002000000000000000000" + }, + "d8eef4cf4beb01ee20d111748b61cb4d3f641a01": { + "balance": "2740000000000000000000" + }, + "16c1bf5b7dc9c83c179efacbcf2eb174e3561cb3": { + "balance": "1000000000000000000000" + }, + "d79db5ab43621a7a3da795e58929f3dd25af67d9": { + "balance": "1999944000000000000000" + }, + "28efae6356509edface89fc61a7fdcdb39eea8e5": { + "balance": "5348000000000000000000" + }, + "c55005a6c37e8ca7e543ce259973a3cace961a4a": { + "balance": "2000000000000000000000" + }, + "ab3d86bc82927e0cd421d146e07f919327cdf6f9": { + "balance": "1910000000000000000000" + }, + "b74ed2666001c16333cf7af59e4a3d4860363b9c": { + "balance": "193600000000000000000" + }, + "1899f69f653b05a5a6e81f480711d09bbf97588c": { + "balance": "1955000000000000000000" + }, + "27fc85a49cff90dbcfdadc9ddd40d6b9a2210a6c": { + "balance": "100000000000000000000" + }, + "cd1ed263fbf6f6f7b48aef8f733d329d4382c7c7": { + "balance": "18500000000000000000" + }, + "d97fe6f53f2a58f6d76d752adf74a8a2c18e9074": { + "balance": "309990000000000000000" + }, + "80da2fdda29a9e27f9e115975e69ae9cfbf3f27e": { + "balance": "200000000000000000000" + }, + "09146ea3885176f07782e1fe30dce3ce24c49e1f": { + "balance": "20000000000000000000" + }, + "393ff4255e5c658f2e7f10ecbd292572671bc2d2": { + "balance": "2000000000000000000000" + }, + "a390ca122b8501ee3e5e07a8ca4b419f7e4dae15": { + "balance": "100000000000000000000" + }, + "6d9193996b194617211106d1635eb26cc4b66c6c": { + "balance": "399640000000000000000" + }, + "999c49c174ca13bc836c1e0a92bff48b271543ca": { + "balance": "3280000000000000000000" + }, + "7421ce5be381738ddc83f02621974ff0686c79b8": { + "balance": "1632000000000000000000" + }, + "6be9030ee6e2fbc491aca3de4022d301772b7b7d": { + "balance": "26740000000000000000" + }, + "81bd75abd865e0c3f04a0b4fdbcb74d34082fbb7": { + "balance": "4000000000000000000000" + }, + "8bc1ff8714828bf286ff7e8a7709106548ed1b18": { + "balance": "10000000000000000000000" + }, + "a0aadbd9509722705f6d2358a5c79f37970f00f6": { + "balance": "200000000000000000000" + }, + "3d881433f04a7d0d27f84944e08a512da3555287": { + "balance": "1200000000000000000000" + }, + "cc1d6ead01aada3e8dc7b95dca25df26eefa639d": { + "balance": "2000000000000000000000" + }, + "35106ba94e8563d4b3cb3c5c692c10e604b7ced8": { + "balance": "2000000000000000000000" + }, + "4d8697af0fbf2ca36e8768f4af22133570685a60": { + "balance": "20000000000000000000" + }, + "1afcc585896cd0ede129ee2de5c19ea811540b64": { + "balance": "3231259000000000000000" + }, + "e5215631b14248d45a255296bed1fbfa0330ff35": { + "balance": "1310000000000000000000" + }, + "e3878f91ca86053fced5444686a330e09cc388fb": { + "balance": "194000000000000000000" + }, + "555df19390c16d01298772bae8bc3a1152199cbd": { + "balance": "200000000000000000000" + }, + "dc3dae59ed0fe18b58511e6fe2fb69b219689423": { + "balance": "100000000000000000000" + }, + "74648caac748dd135cd91ea14c28e1bd4d7ff6ae": { + "balance": "3100000000000000000000" + }, + "cf2e2ad635e9861ae95cb9bafcca036b5281f5ce": { + "balance": "35200000000000000000000" + }, + "14eec09bf03e352bd6ff1b1e876be664ceffd0cf": { + "balance": "20094000000000000000" + }, + "856e5ab3f64c9ab56b009393b01664fc0324050e": { + "balance": "1790000000000000000000" + }, + "632b9149d70178a7333634275e82d5953f27967b": { + "balance": "700000000000000000000" + }, + "2a39190a4fde83dfb3ddcb4c5fbb83ac6c49755c": { + "balance": "1000000000000000000000" + }, + "369ef761195f3a373e24ece6cd22520fe0b9e86e": { + "balance": "534933000000000000000" + }, + "16afa787fc9f94bdff6976b1a42f430a8bf6fb0f": { + "balance": "2000000000000000000000" + }, + "1b0b31afff4b6df3653a94d7c87978ae35f34aae": { + "balance": "354600000000000000000" + }, + "b4d82f2e69943f7de0f5f7743879406fac2e9cec": { + "balance": "40000000000000000000" + }, + "09d6cefd75b0c4b3f8f1d687a522c96123f1f539": { + "balance": "6000000000000000000000" + }, + "01577afd4e50890247c9b10d44af73229aec884f": { + "balance": "680000000000000000000" + }, + "a35606d51220ee7f2146d411582ee4ee4a45596e": { + "balance": "3996800000000000000000" + }, + "352e77c861696ef96ad54934f894aa8ea35151dd": { + "balance": "1000000000000000000000" + }, + "b87f5376c2de0b6cc3c179c06087aa473d6b4674": { + "balance": "1337000000000000000000" + }, + "5b49afcd75447838f6e7ceda8d21777d4fc1c3c0": { + "balance": "4000000000000000000000" + }, + "b884add88d83dc564ab8e0e02cbdb63919aea844": { + "balance": "2000000000000000000000" + }, + "5c312a56c784b122099b764d059c21ece95e84ca": { + "balance": "95000000000000000000" + }, + "4697baaf9ccb603fd30430689d435445e9c98bf5": { + "balance": "199600000000000000000" + }, + "c625f8c98d27a09a1bcabd5128b1c2a94856af30": { + "balance": "200000000000000000000" + }, + "19f5caf4c40e6908813c0745b0aea9586d9dd931": { + "balance": "664000000000000000000" + }, + "1e596a81b357c6f24970cc313df6dbdaabd0d09e": { + "balance": "2000000000000000000000" + }, + "c1631228efbf2a2e3a4092ee8900c639ed34fbc8": { + "balance": "955000000000000000000" + }, + "6f6cf20649a9e973177ac67dbadee4ebe5c7bdda": { + "balance": "5080000000000000000000" + }, + "5fa7bfe043886127d4011d8356a47e947963aca8": { + "balance": "1820000000000000000000" + }, + "6af8e55969682c715f48ad4fc0fbb67eb59795a3": { + "balance": "2000000000000000000000" + }, + "122f56122549d168a5c5e267f52662e5c5cce5c8": { + "balance": "185000000000000000000" + }, + "7713ab8037411c09ba687f6f9364f0d3239fac28": { + "balance": "10000000000000000000000" + }, + "31ccc616b3118268e75d9ab8996c8858ebd7f3c3": { + "balance": "399924000000000000000" + }, + "09c88f917e4d6ad473fa12e98ea3c4472a5ed6da": { + "balance": "10000000000000000000000" + }, + "e796fd4e839b4c95d7510fb7c5c72b83c6c3e3c7": { + "balance": "512200000000000000000" + }, + "a8285539869d88f8a961533755717d7eb65576ae": { + "balance": "200000000000000000000" + }, + "d929c65d69d5bbaea59762662ef418bc21ad924a": { + "balance": "1000000000000000000000" + }, + "f7418aa0e713d248228776b2e7434222ae75e3a5": { + "balance": "2000000000000000000000" + }, + "7f0b90a1fdd48f27b268feb38382e55ddb50ef0f": { + "balance": "940000000000000000000" + }, + "34a0431fff5ead927f3c69649616dc6e97945f6f": { + "balance": "400000000000000000000" + }, + "1b3cb81e51011b549d78bf720b0d924ac763a7c2": { + "balance": "560000000000000000000000" + }, + "155b3779bb6d56342e2fda817b5b2d81c7f41327": { + "balance": "50200000000000000000" + }, + "ecd486fc196791b92cf612d348614f9156488b7e": { + "balance": "12000000000000000000000" + }, + "82a8cbbfdff02b2e38ae4bbfca15f1f0e83b1aea": { + "balance": "84999000000000000000" + }, + "06b0c1e37f5a5ec4bbf50840548f9d3ac0288897": { + "balance": "4000098000000000000000" + }, + "e6d49f86c228f47367a35e886caacb271e539429": { + "balance": "412656000000000000000" + }, + "704a6eb41ba34f13addde7d2db7df04915c7a221": { + "balance": "1820000000000000000000" + }, + "745ccf2d819edbbddea8117b5c49ed3c2a066e93": { + "balance": "4000000000000000000000" + }, + "6d3b7836a2b9d899721a4d237b522385dce8dfcd": { + "balance": "1000070000000000000000" + }, + "856aa23c82d7215bec8d57f60ad75ef14fa35f44": { + "balance": "20000000000000000000000" + }, + "ea79057dabef5e64e7b44f7f18648e7e533718d2": { + "balance": "200000000000000000000" + }, + "9df057cd03a4e27e8e032f857985fd7f01adc8d7": { + "balance": "2000000000000000000000" + }, + "5f2f07d2d697e8c567fcfdfe020f49f360be2139": { + "balance": "2000000000000000000000" + }, + "5efbdfe5389999633c26605a5bfc2c1bb5959393": { + "balance": "69200000000000000000" + }, + "047e87c8f7d1fce3b01353a85862a948ac049f3e": { + "balance": "1490000000000000000000" + }, + "265383d68b52d034161bfab01ae1b047942fbc32": { + "balance": "21000600000000000000000" + }, + "760ff3354e0fde938d0fb5b82cef5ba15c3d2916": { + "balance": "10000000000000000000000" + }, + "bc46d537cf2edd403565bde733b2e34b215001bd": { + "balance": "20000000000000000000000" + }, + "ee58fb3db29070d0130188ce472be0a172b89055": { + "balance": "10021400000000000000000" + }, + "75abe5270f3a78ce007cf37f8fbc045d489b7bb1": { + "balance": "1999944000000000000000" + }, + "5fc6c11426b4a1eae7e51dd512ad1090c6f1a85b": { + "balance": "2730000000000000000000" + }, + "26cfffd052152bb3f957b478d5f98b233a7c2b92": { + "balance": "4000000000000000000000" + }, + "0a4a011995c681bc999fdd79754e9a324ae3b379": { + "balance": "41350300000000000000000" + }, + "6fa60df818a5446418b1bbd62826e0b9825e1318": { + "balance": "13200000000000000000000" + }, + "63d55ad99b9137fd1b20cc2b4f03d42cbaddf334": { + "balance": "400000000000000000000" + }, + "679b9a109930517e8999099ccf2a914c4c8dd934": { + "balance": "60000000000000000000" + }, + "3e83544f0082552572c782bee5d218f1ef064a9d": { + "balance": "100076000000000000000" + }, + "968b14648f018333687cd213fa640aec04ce6323": { + "balance": "1000000000000000000000" + }, + "427b462ab84e5091f48a46eb0cdc92ddcb26e078": { + "balance": "2000000000000000000000" + }, + "df8510793eee811c2dab1c93c6f4473f30fbef5b": { + "balance": "1000000000000000000000" + }, + "362fbcb10662370a068fc2652602a2577937cce6": { + "balance": "200000000000000000000" + }, + "5d83b21bd2712360436b67a597ee3378db3e7ae4": { + "balance": "2000000000000000000000" + }, + "5777441c83e03f0be8dd340bde636850847c620b": { + "balance": "10000000000000000000000" + }, + "c94a585203da7bbafd93e15884e660d4b1ead854": { + "balance": "7000000000000000000000" + }, + "35a08081799173e001cc5bd46a02406dc95d1787": { + "balance": "10000000000000000000000" + }, + "21d13f0c4024e967d9470791b50f22de3afecf1b": { + "balance": "4452210000000000000000" + }, + "fdfd6134c04a8ab7eb16f00643f8fed7daaaecb2": { + "balance": "400000000000000000000" + }, + "fd812bc69fb170ef57e2327e80affd14f8e4b6d2": { + "balance": "2000000000000000000000" + }, + "7148aef33261d8031fac3f7182ff35928daf54d9": { + "balance": "4100000000000000000000" + }, + "0b06390f2437b20ec4a3d3431b3279c6583e5ed7": { + "balance": "194000000000000000000" + }, + "4909b31998ead414b8fb0e846bd5cbde393935be": { + "balance": "4000000000000000000000" + }, + "b70dba9391682b4a364e77fe99256301a6c0bf1f": { + "balance": "200000000000000000000" + }, + "6b83bae7b565244558555bcf4ba8da2011891c17": { + "balance": "2000000000000000000000" + }, + "70a03549aa6168e97e88a508330a5a0bea74711a": { + "balance": "1337000000000000000000" + }, + "0fc9a0e34145fbfdd2c9d2a499b617d7a02969b9": { + "balance": "180000000000000000000" + }, + "2ddf40905769bcc426cb2c2938ffe077e1e89d98": { + "balance": "3000000000000000000000" + }, + "794b51c39e53d9e762b0613b829a44b472f4fff3": { + "balance": "667965000000000000000" + }, + "d062588171cf99bbeb58f126b870f9a3728d61ec": { + "balance": "4500000000000000000000" + }, + "8db185fe1b70a94a6a080e7e23a8bedc4acbf34b": { + "balance": "1400000000000000000000" + }, + "e73bfeada6f0fd016fbc843ebcf6e370a65be70c": { + "balance": "1970000000000000000000" + }, + "79ed10cf1f6db48206b50919b9b697081fbdaaf3": { + "balance": "2000000000000000000000" + }, + "276b0521b0e68b277df0bb32f3fd48326350bfb2": { + "balance": "50000000000000000000" + }, + "2e439348df8a4277b22a768457d1158e97c40904": { + "balance": "776970000000000000000" + }, + "6c25327f8dcbb2f45e561e86e35d8850e53ab059": { + "balance": "1103200000000000000000" + }, + "04d73896cf6593a691972a13a6e4871ff2c42b13": { + "balance": "2000000000000000000000" + }, + "b10fd2a647102f881f74c9fbc37da632949f2375": { + "balance": "40000000000000000000" + }, + "615f82365c5101f071e7d2cb6af14f7aad2c16c6": { + "balance": "20000000000000000000" + }, + "93aa8f92ebfff991fc055e906e651ac768d32bc8": { + "balance": "940000000000000000000" + }, + "0cbf8770f0d1082e5c20c5aead34e5fca9ae7ae2": { + "balance": "1000000000000000000000" + }, + "ffc9cc3094b041ad0e076f968a0de3b167255866": { + "balance": "432400000000000000000" + }, + "46531e8b1bde097fdf849d6d119885608a008df7": { + "balance": "200000000000000000000" + }, + "23cd2598a20e149ead2ad69379576ecedb60e38e": { + "balance": "2000000000000000000000" + }, + "85ca8bc6da2803d0725f5e1a456c89f9bc774e2f": { + "balance": "600000000000000000000" + }, + "c0725ec2bdc33a1d826071dea29d62d4385a8c25": { + "balance": "40740000000000000000000" + }, + "0e4765790352656bc656682c24fc5ef3e76a23c7": { + "balance": "46610000000000000000" + }, + "2ef9e465716acacfb8c8252fa8e7bc7969ebf6e4": { + "balance": "2760000000000000000000" + }, + "0ec5308b31282e218fc9e759d4fec5db3708cec4": { + "balance": "1001000000000000000000" + }, + "bf7701fc6225d5a17815438a8941d21ebc5d059d": { + "balance": "1880000000000000000000" + }, + "c489c83ffbb0252ac0dbe3521217630e0f491f14": { + "balance": "4000000000000000000000" + }, + "8eb51774af206b966b8909c45aa6722748802c0c": { + "balance": "500000000000000000000" + }, + "7b9226d46fe751940bc416a798b69ccf0dfab667": { + "balance": "4200000000000000000000" + }, + "8f660f8b2e4c7cc2b4ac9c47ed28508d5f8f8650": { + "balance": "20000000000000000000000" + }, + "9f19fac8a32437d80ac6837a0bb7841729f4972e": { + "balance": "650100000000000000000" + }, + "201864a8f784c2277b0b7c9ee734f7b377eab648": { + "balance": "4467000000000000000000" + }, + "a6101c961e8e1c15798ffcd0e3201d7786ec373a": { + "balance": "6000000000000000000000" + }, + "d4ff46203efa23064b1caf00516e28704a82a4f8": { + "balance": "1337000000000000000000" + }, + "aa136b47962bb8b4fb540db4ccf5fdd042ffb8cf": { + "balance": "500038000000000000000" + }, + "704ae21d762d6e1dde28c235d13104597236db1a": { + "balance": "2000000000000000000000" + }, + "f17a92e0361dbacecdc5de0d1894955af6a9b606": { + "balance": "2000000000000000000000" + }, + "8b48e19d39dd35b66e6e1bb6b9c657cb2cf59d04": { + "balance": "17844175000000000000000" + }, + "9ad47fdcf9cd942d28effd5b84115b31a658a13e": { + "balance": "3290000000000000000000" + }, + "df0d08617bd252a911df8bd41a39b83ddf809673": { + "balance": "10000000000000000000000" + }, + "4c666b86f1c5ee8ca41285f5bde4f79052081406": { + "balance": "500000000000000000000" + }, + "88dec5bd3f4eba2d18b8aacefa7b721548c319ba": { + "balance": "1370000000000000000000" + }, + "9f9fe0c95f10fee87af1af207236c8f3614ef02f": { + "balance": "6000000000000000000000" + }, + "f7d0d310acea18406138baaabbfe0571e80de85f": { + "balance": "1337000000000000000000" + }, + "9569c63a9284a805626db3a32e9d236393476151": { + "balance": "1970000000000000000000" + }, + "5d5c2c1099bbeefb267e74b58880b444d94449e0": { + "balance": "253574000000000000000" + }, + "8c6ae7a05a1de57582ae2768204276c0ff47ed03": { + "balance": "208000000000000000000000" + }, + "432d884bd69db1acc0d89c64ade4cb4fc3a88b7a": { + "balance": "2483000000000000000000" + }, + "672cbca8440a8577097b19aff593a2ad9d28a756": { + "balance": "80000000000000000000" + }, + "19df9445a81c1b3d804aeaeb6f6e204e4236663f": { + "balance": "37387000000000000000" + }, + "1cb5f33b4d488936d13e3161da33a1da7df70d1b": { + "balance": "200000000000000000000" + }, + "df60f18c812a11ed4e2776e7a80ecf5e5305b3d6": { + "balance": "900000000000000000000" + }, + "c99a9cd6c9c1be3534eecd92ecc22f5c38e9515b": { + "balance": "4821030000000000000000" + }, + "00c40fe2095423509b9fd9b754323158af2310f3": { + "balance": "0" + }, + "da4a5f557f3bab390a92f49b9b900af30c46ae80": { + "balance": "10000000000000000000000" + }, + "f36df02fbd89607347afce2969b9c4236a58a506": { + "balance": "2000000000000000000000" + }, + "c549df83c6f65eec0f1dc9a0934a5c5f3a50fd88": { + "balance": "2910000000000000000000" + }, + "9f662e95274121f177566e636d23964cf1fd686f": { + "balance": "2000000000000000000000" + }, + "5a267331facb262daaecd9dd63a9700c5f5259df": { + "balance": "100000000000000000000" + }, + "117d9aa3c4d13bee12c7500f09f5dd1c66c46504": { + "balance": "206000000000000000000" + }, + "1b4d07acd38183a61bb2783d2b7b178dd502ac8d": { + "balance": "200000000000000000000" + }, + "3c0c3defac9cea7acc319a96c30b8e1fedab4574": { + "balance": "1940000000000000000000" + }, + "e4dc22ed595bf0a337c01e03cc6be744255fc9e8": { + "balance": "191000000000000000000" + }, + "8f067c7c1bbd57780b7b9eeb9ec0032f90d0dcf9": { + "balance": "20000000000000000000000" + }, + "40e2440ae142c880366a12c6d4102f4b8434b62a": { + "balance": "1000000000000000000000" + }, + "f9ece022bccd2c92346911e79dd50303c01e0188": { + "balance": "1000000000000000000000" + }, + "f70328ef97625fe745faa49ee0f9d4aa3b0dfb69": { + "balance": "1000000000000000000000" + }, + "b6aacb8cb30bab2ae4a2424626e6e12b02d04605": { + "balance": "8000000000000000000000" + }, + "154459fa2f21318e3434449789d826cdc1570ce5": { + "balance": "2000000000000000000000" + }, + "684a44c069339d08e19a75668bdba303be855332": { + "balance": "70000000000000000000000" + }, + "9fe501aa57ead79278937cd6308c5cfa7a5629fe": { + "balance": "50003000000000000000" + }, + "3e45bd55db9060eced923bb9cb733cb3573fb531": { + "balance": "1640000000000000000000" + }, + "9c9f3b8a811b21f3ff3fe20fe970051ce66a824f": { + "balance": "1157740000000000000000" + }, + "e99aece90541cae224b87da673965e0aeb296afd": { + "balance": "920000000000000000000" + }, + "2f6dce1330c59ef921602154572d4d4bacbd048a": { + "balance": "1000000000000000000000" + }, + "6a6353b971589f18f2955cba28abe8acce6a5761": { + "balance": "3000000000000000000000" + }, + "98c10ebf2c4f97cba5a1ab3f2aafe1cac423f8cb": { + "balance": "300000000000000000000" + }, + "8077c3e4c445586e094ce102937fa05b737b568c": { + "balance": "100000000000000000000" + }, + "13371f92a56ea8381e43059a95128bdc4d43c5a6": { + "balance": "1000000000000000000000" + }, + "35a6885083c899dabbf530ed6c12f4dd3a204cf5": { + "balance": "200000000000000000000" + }, + "36b2c85e3aeeebb70d63c4a4730ce2e8e88a3624": { + "balance": "10000000000000000000000" + }, + "5ce44068b8f4a3fe799e6a8311dbfdeda29dee0e": { + "balance": "2000000000000000000000" + }, + "6fa6388d402b30afe59934c3b9e13d1186476018": { + "balance": "670000000000000000000" + }, + "8251358ca4e060ddb559ca58bc0bddbeb4070203": { + "balance": "2000000000000000000000" + }, + "17e86f3b5b30c0ba59f2b2e858425ba89f0a10b0": { + "balance": "2000000000000000000000" + }, + "298ec76b440d8807b3f78b5f90979bee42ed43db": { + "balance": "30000000000000000000000" + }, + "ce4b065dbcb23047203262fb48c1188364977470": { + "balance": "500000000000000000000" + }, + "c8e2adeb545e499d982c0c117363ceb489c5b11f": { + "balance": "985000000000000000000" + }, + "9928ff715afc3a2b60f8eb4cc4ba4ee8dab6e59d": { + "balance": "440000000000000000000" + }, + "c76130c73cb9210238025c9df95d0be54ac67fbe": { + "balance": "1500000000000000000000" + }, + "72d03d4dfab3500cf89b86866f15d4528e14a195": { + "balance": "4488000000000000000000" + }, + "d193e583d6070563e7b862b9614a47e99489f3e5": { + "balance": "999972000000000000000" + }, + "4df140ba796585dd5489315bca4bba680adbb818": { + "balance": "2674000000000000000000" + }, + "009eef0a0886056e3f69211853b9b7457f3782e4": { + "balance": "3000512000000000000000" + }, + "6e255b700ae7138a4bacf22888a9e2c00a285eec": { + "balance": "4000000000000000000000" + }, + "aa47a4ffc979363232c99b99fada0f2734b0aeee": { + "balance": "8121800000000000000000" + }, + "9d069197d1de50045a186f5ec744ac40e8af91c6": { + "balance": "2000000000000000000000" + }, + "b514882c979bb642a80dd38754d5b8c8296d9a07": { + "balance": "955000000000000000000" + }, + "17c0478657e1d3d17aaa331dd429cecf91f8ae5d": { + "balance": "999942000000000000000" + }, + "5f9616c47b4a67f406b95a14fe6fc268396f1721": { + "balance": "200000000000000000000" + }, + "f70a998a717b338d1dd99854409b1a338deea4b0": { + "balance": "2000000000000000000000" + }, + "d1ee905957fe7cc70ec8f2868b43fe47b13febff": { + "balance": "44000000000000000000" + }, + "fc018a690ad6746dbe3acf9712ddca52b6250039": { + "balance": "10000000000000000000000" + }, + "5118557d600d05c2fcbf3806ffbd93d02025d730": { + "balance": "11360000000000000000000" + }, + "1ef5c9c73650cfbbde5c885531d427c7c3fe5544": { + "balance": "6000000000000000000000" + }, + "d1a396dcdab2c7494130b3fd307820340dfd8c1f": { + "balance": "17952000000000000000" + }, + "2d8e061892a5dcce21966ae1bb0788fd3e8ba059": { + "balance": "250066000000000000000" + }, + "8834b2453471f324fb26be5b25166b5b5726025d": { + "balance": "573000000000000000000" + }, + "14f221159518783bc4a706676fc4f3c5ee405829": { + "balance": "200000000000000000000" + }, + "c056d4bd6bf3cbacac65f8f5a0e3980b852740ae": { + "balance": "100000000000000000000" + }, + "560536794a9e2b0049d10233c41adc5f418a264a": { + "balance": "1000000000000000000000" + }, + "bc9e0ec6788f7df4c7fc210aacd220c27e45c910": { + "balance": "500000000000000000000" + }, + "54bcb8e7f73cda3d73f4d38b2d0847e600ba0df8": { + "balance": "1078000000000000000000" + }, + "4361d4846fafb377b6c0ee49a596a78ddf3516a3": { + "balance": "3580000000000000000000" + }, + "41c3c2367534d13ba2b33f185cdbe6ac43c2fa31": { + "balance": "4000000000000000000000" + }, + "5dc6f45fef26b06e3302313f884daf48e2746fb9": { + "balance": "500000000000000000000" + }, + "ad414d29cb7ee973fec54e22a388491786cf5402": { + "balance": "14000000000000000000000" + }, + "802dc3c4ff2d7d925ee2859f4a06d7ba60f1308c": { + "balance": "98040000000000000000" + }, + "2aed2ce531c056b0097efc3c6de10c4762004ed9": { + "balance": "10430000000000000000000" + }, + "39782ffe06ac78822a3c3a8afe305e50a56188ce": { + "balance": "10000000000000000000000" + }, + "ec73833de4b810bb027810fc8f69f544e83c12d1": { + "balance": "1000000000000000000000" + }, + "8d51a4cc62011322c696fd725b9fb8f53feaaa07": { + "balance": "1000000000000000000000" + }, + "29298ccbdff689f87fe41aa6e98fdfb53deaf37a": { + "balance": "19800000000000000000000" + }, + "827531a6c5817ae35f82b00b9754fcf74c55e232": { + "balance": "3600000000000000000000" + }, + "9c581a60b61028d934167929b22d70b313c34fd0": { + "balance": "50000000000000000000000" + }, + "0a077db13ffeb09484c217709d5886b8bf9c5a8b": { + "balance": "4000000000000000000000" + }, + "07b7a57033f8f11330e4665e185d234e83ec140b": { + "balance": "4325683000000000000000" + }, + "17f523f117bc9fe978aa481eb4f5561711371bc8": { + "balance": "1999884000000000000000" + }, + "de42fcd24ce4239383304367595f068f0c610740": { + "balance": "45120000000000000000" + }, + "2a46d353777176ff8e83ffa8001f4f70f9733aa5": { + "balance": "106000000000000000000" + }, + "92e4392816e5f2ef5fb65837cec2c2325cc64922": { + "balance": "10000000000000000000000" + }, + "9a3da65023a13020d22145cfc18bab10bd19ce4e": { + "balance": "456516000000000000000" + }, + "1a085d43ec92414ea27b914fe767b6d46b1eef44": { + "balance": "29550000000000000000000" + }, + "3b2367f8494b5fe18d683c055d89999c9f3d1b34": { + "balance": "10000000000000000000000" + }, + "84244fc95a6957ed7c1504e49f30b8c35eca4b79": { + "balance": "2000000000000000000000" + }, + "5e031b0a724471d476f3bcd2eb078338bf67fbef": { + "balance": "18200000000000000000" + }, + "97e5cc6127c4f885be02f44b42d1c8b0ac91e493": { + "balance": "200000000000000000000" + }, + "eb1cea7b45d1bd4d0e2a007bd3bfb354759e2c16": { + "balance": "198000000000000000000" + }, + "72feaf124579523954645b7fafff0378d1c8242e": { + "balance": "1000000000000000000000" + }, + "8d07d42d831c2d7c838aa1872b3ad5d277176823": { + "balance": "349200000000000000000" + }, + "9637dc12723d9c78588542eab082664f3f038d9d": { + "balance": "1000000000000000000000" + }, + "e84b55b525f1039e744b918cb3332492e45eca7a": { + "balance": "200000000000000000000" + }, + "b1d6b01b94d854fe8b374aa65e895cf22aa2560e": { + "balance": "940000000000000000000" + }, + "8161d940c3760100b9080529f8a60325030f6edc": { + "balance": "300000000000000000000" + }, + "d30ee9a12b4d68abace6baca9ad7bf5cd1faf91c": { + "balance": "1499936000000000000000" + }, + "057949e1ca0570469e4ce3c690ae613a6b01c559": { + "balance": "200000000000000000000" + }, + "4bf8e26f4c2790da6533a2ac9abac3c69a199433": { + "balance": "200000000000000000000" + }, + "36fec62c2c425e219b18448ad757009d8c54026f": { + "balance": "400000000000000000000" + }, + "77bfe93ccda750847e41a1affee6b2da96e7214e": { + "balance": "300000000000000000000" + }, + "cc48414d2ac4d42a5962f29eee4497092f431352": { + "balance": "161000000000000000000" + }, + "ddbddd1bbd38ffade0305d30f02028d92e9f3aa8": { + "balance": "2000000000000000000000" + }, + "30c01142907acb1565f70438b9980ae731818738": { + "balance": "2000000000000000000000" + }, + "cffc49c1787eebb2b56cabe92404b636147d4558": { + "balance": "5679305000000000000000" + }, + "f99eeece39fa7ef5076d855061384009792cf2e0": { + "balance": "500000000000000000000" + }, + "e9b6a790009bc16642c8d820b7cde0e9fd16d8f5": { + "balance": "3640000000000000000000" + }, + "03b41b51f41df20dd279bae18c12775f77ad771c": { + "balance": "1000000000000000000000" + }, + "787d313fd36b053eeeaedbce74b9fb0678333289": { + "balance": "27160000000000000000000" + }, + "35d2970f49dcc81ea9ee707e9c8a0ab2a8bb7463": { + "balance": "1440000000000000000000" + }, + "4c0aca508b3caf5ee028bc707dd1e800b838f453": { + "balance": "18200000000000000000" + }, + "514632efbd642c04de6ca342315d40dd90a2dba6": { + "balance": "2674000000000000000000" + }, + "36810ff9d213a271eda2b8aa798be654fa4bbe06": { + "balance": "2000000000000000000000" + }, + "0c088006c64b30c4ddafbc36cb5f05469eb62834": { + "balance": "2000000000000000000000" + }, + "568df31856699bb5acfc1fe1d680df9960ca4359": { + "balance": "1379999000000000000000" + }, + "d48e3f9357e303513841b3f84bda83fc89727587": { + "balance": "1000000000000000000000" + }, + "953ef652e7b769f53d6e786a58952fa93ee6abe7": { + "balance": "2860000000000000000000" + }, + "7c60a05f7a4a5f8cf2784391362e755a8341ef59": { + "balance": "1892300000000000000000" + }, + "7a6b26f438d9a352449155b8876cbd17c9d99b64": { + "balance": "6000000000000000000000" + }, + "68f719ae342bd7fef18a05cbb02f705ad38ed5b2": { + "balance": "1050000000000000000000" + }, + "45ca8d956608f9e00a2f9974028640888465668f": { + "balance": "2000000000000000000000" + }, + "3eaf316b87615d88f7adc77c58e712ed4d77966b": { + "balance": "100141000000000000000" + }, + "1f0412bfedcd964e837d092c71a5fcbaf30126e2": { + "balance": "20000000000000000000" + }, + "7471f72eeb300624eb282eab4d03723c649b1b58": { + "balance": "8000000000000000000000" + }, + "9bf71f7fb537ac54f4e514947fa7ff6728f16d2f": { + "balance": "33400000000000000000" + }, + "1098c774c20ca1daac5ddb620365316d353f109c": { + "balance": "100000000000000000000" + }, + "7dd8d7a1a34fa1f8e73ccb005fc2a03a15b8229c": { + "balance": "200000000000000000000" + }, + "0151fa5d17a2dce2d7f1eb39ef7fe2ad213d5d89": { + "balance": "4000000000000000000000" + }, + "ad6628352ed3390bafa86d923e56014cfcb360f4": { + "balance": "2000000000000000000000" + }, + "02af2459a93d0b3f4d062636236cd4b29e3bcecf": { + "balance": "1910000000000000000000" + }, + "ace2abb63b0604409fbde3e716d2876d44e8e5dd": { + "balance": "152000000000000000000" + }, + "e710dcd09b8101f9437bd97db90a73ef993d0bf4": { + "balance": "386100000000000000000" + }, + "d43ee438d83de9a37562bb4e286cb1bd19f4964d": { + "balance": "1000000000000000000000" + }, + "ea3779d14a13f6c78566bcde403591413a6239db": { + "balance": "197000000000000000000000" + }, + "6704f169e0d0b36b57bbc39f3c45437b5ee3d28d": { + "balance": "394000000000000000000" + }, + "5584423050e3c2051f0bbd8f44bd6dbc27ecb62c": { + "balance": "3000000000000000000000" + }, + "2f315d9016e8ee5f536681202f9084b032544d4d": { + "balance": "1037400000000000000000" + }, + "e1b63201fae1f129f95c7a116bd9dde5159c6cda": { + "balance": "22837462000000000000000" + }, + "2bbe62eac80ca7f4d6fdee7e7d8e28b63acf770e": { + "balance": "2396000000000000000000" + }, + "38da1ba2de9e2c954b092dd9d81204fd016ba016": { + "balance": "10156000000000000000000" + }, + "8a86e4a51c013b1fb4c76bcf30667c78d52eedef": { + "balance": "2000000000000000000000" + }, + "8f717ec1552f4c440084fba1154a81dc003ebdc0": { + "balance": "10000000000000000000000" + }, + "c760971bbc181c6a7cf77441f24247d19ce9b4cf": { + "balance": "2000000000000000000000" + }, + "7f150afb1a77c2b45928c268c1e9bdb4641d47d8": { + "balance": "2000000000000000000000" + }, + "1ea334b5750807ea74aac5ab8694ec5f28aa77cf": { + "balance": "492500000000000000000" + }, + "2afb058c3d31032b353bf24f09ae20d54de57dbe": { + "balance": "1100000000000000000000" + }, + "caef027b1ab504c73f41f2a10979b474f97e309f": { + "balance": "200000000000000000000" + }, + "5dd112f368c0e6ceff77a9df02a5481651a02fb7": { + "balance": "169800000000000000000" + }, + "bd93e550403e2a06113ed4c3fba1a8913b19407e": { + "balance": "2000000000000000000000" + }, + "500c16352e901d48ba8d04e2c767121772790b02": { + "balance": "30239000000000000000" + }, + "d2a80327cbe55c4c7bd51ff9dde4ca648f9eb3f8": { + "balance": "50000000000000000000" + }, + "355ccfe0e77d557b971be1a558bc02df9eee0594": { + "balance": "1759120000000000000000" + }, + "5aed0e6cfe95f9d680c76472a81a2b680a7f93e2": { + "balance": "197000000000000000000" + }, + "f56442f60e21691395d0bffaa9194dcaff12e2b7": { + "balance": "260000000000000000000" + }, + "7db9eacc52e429dc83b461c5f4d86010e5383a28": { + "balance": "1000000000000000000000" + }, + "4b984ef26c576e815a2eaed2f5177f07dbb1c476": { + "balance": "1560000000000000000000" + }, + "9846648836a307a057184fd51f628a5f8c12427c": { + "balance": "19100000000000000000000" + }, + "4af0db077bb9ba5e443e21e148e59f379105c592": { + "balance": "600000000000000000000" + }, + "e96e2d3813efd1165f12f602f97f4a62909d3c66": { + "balance": "2300000000000000000000" + }, + "30e789b3d2465e946e6210fa5b35de4e8c93085f": { + "balance": "2000000000000000000000" + }, + "97f99b6ba31346cd98a9fe4c308f87c5a58c5151": { + "balance": "6000000000000000000000" + }, + "595e23d788a2d4bb85a15df7136d264a635511b3": { + "balance": "3940000000000000000000" + }, + "2f61efa5819d705f2b1e4ee754aeb8a819506a75": { + "balance": "1460000000000000000000" + }, + "3554947b7b947b0040da52ca180925c6d3b88ffe": { + "balance": "66850000000000000000" + }, + "8feffadb387a1547fb284da9b8147f3e7c6dc6da": { + "balance": "837200000000000000000" + }, + "258939bbf00c9de9af5338f5d714abf6d0c1c671": { + "balance": "1550000000000000000000" + }, + "5b333696e04cca1692e71986579c920d6b2916f9": { + "balance": "500000000000000000000" + }, + "5381448503c0c702542b1de7cc5fb5f6ab1cf6a5": { + "balance": "8000000000000000000000" + }, + "7e81f6449a03374191f3b7cb05d938b72e090dff": { + "balance": "100000000000000000000" + }, + "4ef1c214633ad9c0703b4e2374a2e33e3e429291": { + "balance": "1337000000000000000000" + }, + "fed8476d10d584b38bfa6737600ef19d35c41ed8": { + "balance": "1820000000000000000000" + }, + "1a95c9b7546b5d1786c3858fb1236446bc0ca4ce": { + "balance": "1970000000000000000000" + }, + "3b07db5a357f5af2484cbc9d77d73b1fd0519fc7": { + "balance": "500000000000000000000" + }, + "5f68a24c7eb4117667737b33393fb3c2148a53b6": { + "balance": "51800000000000000000" + }, + "d8f665fd8cd5c2bcc6ddc0a8ae521e4dc6aa6060": { + "balance": "1700000000000000000000" + }, + "d66acc0d11b689cea6d9ea5ff4014c224a5dc7c4": { + "balance": "18200000000000000000" + }, + "6e72b2a1186a8e2916543b1cb36a68870ea5d197": { + "balance": "186000000000000000000" + }, + "5102a4a42077e11c58df4773e3ac944623a66d9f": { + "balance": "2000325000000000000000" + }, + "72480bede81ad96423f2228b5c61be44fb523100": { + "balance": "6400000000000000000000" + }, + "e076db30ab486f79194ebbc45d8fab9a9242f654": { + "balance": "4840000000000000000000" + }, + "8ceea15eec3bdad8023f98ecf25b2b8fef27db29": { + "balance": "2000000000000000000000" + }, + "40652360d6716dc55cf9aab21f3482f816cc2cbd": { + "balance": "10000000000000000000000" + }, + "13e02fb448d6c84ae17db310ad286d056160da95": { + "balance": "2000000000000000000000" + }, + "d6598b1386e93c5ccb9602ff4bbbecdbd3701dc4": { + "balance": "224096000000000000000" + }, + "d5ea472cb9466018110af00c37495b5c2c713112": { + "balance": "4997800000000000000000" + }, + "bb75cb5051a0b0944b4673ca752a97037f7c8c15": { + "balance": "200000000000000000000" + }, + "8af626a5f327d7506589eeb7010ff9c9446020d2": { + "balance": "1400000000000000000000" + }, + "318c76ecfd8af68d70555352e1f601e35988042d": { + "balance": "501600000000000000000" + }, + "5c3d19441d196cb443662020fcad7fbb79b29e78": { + "balance": "14300000000000000000" + }, + "27101a0f56d39a88c5a84f9b324cdde33e5cb68c": { + "balance": "2000000000000000000000" + }, + "e229e746a83f2ce253b0b03eb1472411b57e5700": { + "balance": "5730000000000000000000" + }, + "604cdf18628dbfa8329194d478dd5201eecc4be7": { + "balance": "23000000000000000000" + }, + "657473774f63ac3d6279fd0743d5790c4f161503": { + "balance": "200000000000000000000" + }, + "1ddefefd35ab8f658b2471e54790bc17af98dea4": { + "balance": "1000000000000000000000" + }, + "ac3900298dd14d7cc96d4abb428da1bae213ffed": { + "balance": "24730250000000000000000" + }, + "944f07b96f90c5f0d7c0c580533149f3f585a078": { + "balance": "74000000000000000000" + }, + "232c6d03b5b6e6711efff190e49c28eef36c82b0": { + "balance": "1337000000000000000000" + }, + "c87c77e3c24adecdcd1038a38b56e18dead3b702": { + "balance": "8800000000000000000000" + }, + "c4b6e5f09cc1b90df07803ce3d4d13766a9c46f4": { + "balance": "6000000000000000000000" + }, + "d44334b4e23a169a0c16bd21e866bba52d970587": { + "balance": "2600000000000000000000" + }, + "7757a4b9cc3d0247ccaaeb9909a0e56e1dd6dcc2": { + "balance": "20000000000000000000" + }, + "cf694081c76d18c64ca71382be5cd63b3cb476f8": { + "balance": "1000000000000000000000" + }, + "133e4f15e1e39c53435930aaedf3e0fe56fde843": { + "balance": "20000000000000000000" + }, + "f067fb10dfb293e998abe564c055e3348f9fbf1e": { + "balance": "2000000000000000000000" + }, + "94449c01b32a7fa55af8104f42cdd844aa8cbc40": { + "balance": "16548000000000000000000" + }, + "0e2094ac1654a46ba1c4d3a40bb8c17da7f39688": { + "balance": "358000000000000000000" + }, + "738ca94db7ce8be1c3056cd6988eb376359f3353": { + "balance": "25500000000000000000000" + }, + "0cfb172335b16c87d519cd1475530d20577f5e0e": { + "balance": "100000000000000000000000" + }, + "3cb561ce86424b359891e364ec925ffeff277df7": { + "balance": "200000000000000000000" + }, + "5f981039fcf50225e2adf762752112d1cc26b6e3": { + "balance": "499954000000000000000" + }, + "b43657a50eecbc3077e005d8f8d94f377876bad4": { + "balance": "35460000000000000000" + }, + "d07e511864b1cf9969e3560602829e32fc4e71f5": { + "balance": "50000000000000000000" + }, + "11306c7d57588637780fc9fde8e98ecb008f0164": { + "balance": "1999944000000000000000" + }, + "45ca9862003b4e40a3171fb5cafa9028cac8de19": { + "balance": "13790000000000000000000" + }, + "231d94155dbcfe2a93a319b6171f63b20bd2b6fa": { + "balance": "3819952000000000000000" + }, + "e7533e270cc61fa164ac1553455c105d04887e14": { + "balance": "121550000000000000000" + }, + "070d5d364cb7bbf822fc2ca91a35bdd441b215d5": { + "balance": "2000000000000000000000" + }, + "d475477fa56390d33017518d6711027f05f28dbf": { + "balance": "1975032000000000000000" + }, + "cea34a4dd93dd9aefd399002a97d997a1b4b89cd": { + "balance": "1500000000000000000000" + }, + "560becdf52b71f3d8827d927610f1a980f33716f": { + "balance": "429413000000000000000" + }, + "f632adff490da4b72d1236d04b510f74d2faa3cd": { + "balance": "1400000000000000000000" + }, + "2fdd9b79df8df530ad63c20e62af431ae99216b8": { + "balance": "21000000000000000000" + }, + "535201a0a1d73422801f55ded4dfaee4fbaa6e3b": { + "balance": "39641000000000000000" + }, + "409d5a962edeeebea178018c0f38b9cdb213f289": { + "balance": "20000000000000000000" + }, + "9d911f3682f32fe0792e9fb6ff3cfc47f589fca5": { + "balance": "4000000000000000000000" + }, + "9f7a0392f857732e3004a375e6b1068d49d83031": { + "balance": "2000000000000000000000" + }, + "6a04f5d53fc0f515be942b8f12a9cb7ab0f39778": { + "balance": "3129800000000000000000" + }, + "be478e8e3dde6bd403bb2d1c657c4310ee192723": { + "balance": "492500000000000000000" + }, + "007622d84a234bb8b078230fcf84b67ae9a8acae": { + "balance": "698800000000000000000" + }, + "9475c510ec9a26979247744c3d8c3b0e0b5f44d3": { + "balance": "10000000000000000000000" + }, + "df47a8ef95f2f49f8e6f58184154145d11f72797": { + "balance": "1910000000000000000000" + }, + "13ce332dff65a6ab933897588aa23e000980fa82": { + "balance": "258400000000000000000" + }, + "9c4bbcd5f1644a6f075824ddfe85c571d6abf69c": { + "balance": "1800000000000000000000" + }, + "d42b20bd0311608b66f8a6d15b2a95e6de27c5bf": { + "balance": "2000000000000000000000" + }, + "a4dd59ab5e517d398e49fa537f899fed4c15e95d": { + "balance": "20000000000000000000000" + }, + "1a8a5ce414de9cd172937e37f2d59cff71ce57a0": { + "balance": "10000000000000000000000" + }, + "55c564664166a1edf3913e0169f1cd451fdb5d0c": { + "balance": "2399800000000000000000" + }, + "58ae2ddc5f4c8ada97e06c0086171767c423f5d7": { + "balance": "1610000000000000000000" + }, + "fb79abdb925c55b9f98efeef64cfc9eb61f51bb1": { + "balance": "1794000000000000000000" + }, + "e7a42f59fee074e4fb13ea9e57ecf1cc48282249": { + "balance": "20000000000000000000000" + }, + "07e2b4cdeed9d087b12e556d9e770c13c099615f": { + "balance": "668500000000000000000" + }, + "68473b7a7d965904bedba556dfbc17136cd5d434": { + "balance": "100000000000000000000" + }, + "6c5c3a54cda7c2f118edba434ed81e6ebb11dd7a": { + "balance": "200000000000000000000" + }, + "24c117d1d2b3a97ab11a4679c99a774a9eade8d1": { + "balance": "1000000000000000000000" + }, + "f68c5e33fa97139df5b2e63886ce34ebf3e4979c": { + "balance": "3320000000000000000000" + }, + "bd7419dc2a090a46e2873d7de6eaaad59e19c479": { + "balance": "6802000000000000000000" + }, + "1a0a1ddfb031e5c8cc1d46cf05842d50fddc7130": { + "balance": "1000000000000000000000" + }, + "2b3a68db6b0cae8a7c7a476bdfcfbd6205e10687": { + "balance": "2400000000000000000000" + }, + "426d15f407a01135b13a6b72f8f2520b3531e302": { + "balance": "20000000000000000000" + }, + "0394b90fadb8604f86f43fc1e35d3124b32a5989": { + "balance": "764000000000000000000" + }, + "7412c9bc30b4df439f023100e63924066afd53af": { + "balance": "500000000000000000000" + }, + "80e7b3205230a566a1f061d922819bb4d4d2a0e1": { + "balance": "14000000000000000000000" + }, + "ff4fc66069046c525658c337a917f2d4b832b409": { + "balance": "2000000000000000000000" + }, + "f5061ee2e5ee26b815503677130e1de07a52db07": { + "balance": "100000000000000000000" + }, + "49793463e1681083d6abd6e725d5bba745dccde8": { + "balance": "545974000000000000000" + }, + "23551f56975fe92b31fa469c49ea66ee6662f41e": { + "balance": "1910000000000000000000" + }, + "fad96ab6ac768ad5099452ac4777bd1a47edc48f": { + "balance": "100000000000000000000" + }, + "2a746cd44027af3ebd37c378c85ef7f754ab5f28": { + "balance": "394000000000000000000" + }, + "b8d389e624a3a7aebce4d3e5dbdf6cdc29932aed": { + "balance": "200000000000000000000" + }, + "7b761feb7fcfa7ded1f0eb058f4a600bf3a708cb": { + "balance": "4600000000000000000000" + }, + "5435c6c1793317d32ce13bba4c4ffeb973b78adc": { + "balance": "250070000000000000000" + }, + "dd04eee74e0bf30c3f8d6c2c7f52e0519210df93": { + "balance": "80000000000000000000" + }, + "4331ab3747d35720a9d8ca25165cd285acd4bda8": { + "balance": "2000000000000000000000" + }, + "b84c8b9fd33ece00af9199f3cf5fe0cce28cd14a": { + "balance": "3820000000000000000000" + }, + "393f783b5cdb86221bf0294fb714959c7b45899c": { + "balance": "5910000000000000000000" + }, + "259ec4d265f3ab536b7c70fa97aca142692c13fc": { + "balance": "20400000000000000000" + }, + "5d2f7f0b04ba4be161e19cb6f112ce7a5e7d7fe4": { + "balance": "35200000000000000000" + }, + "d54ba2d85681dc130e5b9b02c4e8c851391fd9b9": { + "balance": "3940000000000000000000" + }, + "5cd8af60de65f24dc3ce5730ba92653022dc5963": { + "balance": "1790000000000000000000" + }, + "3b42a66d979f582834747a8b60428e9b4eeccd23": { + "balance": "620400000000000000000" + }, + "4b19eb0c354bc1393960eb06063b83926f0d67b2": { + "balance": "29000000000000000000" + }, + "8cf3546fd1cda33d58845fc8fcfecabca7c5642a": { + "balance": "574027000000000000000" + }, + "113612bc3ba0ee4898b49dd20233905f2f458f62": { + "balance": "14000000000000000000000" + }, + "1f2afc0aed11bfc71e77a907657b36ea76e3fb99": { + "balance": "4000000000000000000000" + }, + "03714b41d2a6f751008ef8dd4d2b29aecab8f36e": { + "balance": "6000000000000000000000" + }, + "25721c87b0dc21377c7200e524b14a22f0af69fb": { + "balance": "4000000000000000000000" + }, + "335858f749f169cabcfe52b796e3c11ec47ea3c2": { + "balance": "200000000000000000000" + }, + "52fb46ac5d00c3518b2c3a1c177d442f8165555f": { + "balance": "1500000000000000000000" + }, + "7a8c89c014509d56d7b68130668ff6a3ecec7370": { + "balance": "300000000000000000000" + }, + "7d5d2f73949dadda0856b206989df0078d51a1e5": { + "balance": "10560000000000000000000" + }, + "be538246dd4e6f0c20bf5ad1373c3b463a131e86": { + "balance": "200000000000000000000" + }, + "62680a15f8ccb8bdc02f7360c25ad8cfb57b8ccd": { + "balance": "1000000000000000000000" + }, + "aa0ca3737337178a0caac3099c584b056c56301c": { + "balance": "880000000000000000000" + }, + "1d341fa5a3a1bd051f7db807b6db2fc7ba4f9b45": { + "balance": "18200000000000000000" + }, + "6463f715d594a1a4ace4bb9c3b288a74decf294d": { + "balance": "1970000000000000000000" + }, + "e00d153b10369143f97f54b8d4ca229eb3e8f324": { + "balance": "152000000000000000000" + }, + "8d0b9ea53fd263415eac11391f7ce9123c447062": { + "balance": "2000000000000000000000" + }, + "cacb675e0996235404efafbb2ecb8152271b55e0": { + "balance": "700000000000000000000" + }, + "b615e940143eb57f875893bc98a61b3d618c1e8c": { + "balance": "20000000000000000000" + }, + "606f177121f7855c21a5062330c8762264a97b31": { + "balance": "4000000000000000000000" + }, + "e3925509c8d0b2a6738c5f6a72f35314491248ce": { + "balance": "1012961000000000000000" + }, + "3f08d9ad894f813e8e2148c160d24b353a8e74b0": { + "balance": "60000000000000000000000" + }, + "40f4f4c06c732cd35b119b893b127e7d9d0771e4": { + "balance": "10000000000000000000000" + }, + "1406854d149e081ac09cb4ca560da463f3123059": { + "balance": "1337000000000000000000" + }, + "ecf05d07ea026e7ebf4941002335baf2fed0f002": { + "balance": "200000000000000000000" + }, + "9a990b8aeb588d7ee7ec2ed8c2e64f7382a9fee2": { + "balance": "33518000000000000000" + }, + "a2e0683a805de6a05edb2ffbb5e96f0570b637c3": { + "balance": "20000000000000000000" + }, + "fba5486d53c6e240494241abf87e43c7600d413a": { + "balance": "1987592000000000000000" + }, + "d81bd54ba2c44a6f6beb1561d68b80b5444e6dc6": { + "balance": "1163806000000000000000" + }, + "5298ab182a19359ffcecafd7d1b5fa212dede6dd": { + "balance": "20000000000000000000" + }, + "d1acb5adc1183973258d6b8524ffa28ffeb23de3": { + "balance": "4000000000000000000000" + }, + "4e7aa67e12183ef9d7468ea28ad239c2eef71b76": { + "balance": "4925000000000000000000" + }, + "509a20bc48e72be1cdaf9569c711e8648d957334": { + "balance": "2000000000000000000000" + }, + "949f84f0b1d7c4a7cf49ee7f8b2c4a134de32878": { + "balance": "685000000000000000000" + }, + "edbac9527b54d6df7ae2e000cca3613ba015cae3": { + "balance": "1970000000000000000000" + }, + "c697b70477cab42e2b8b266681f4ae7375bb2541": { + "balance": "5577200000000000000000" + }, + "86c934e38e53be3b33f274d0539cfca159a4d0d1": { + "balance": "970000000000000000000" + }, + "0877eeaeab78d5c00e83c32b2d98fa79ad51482f": { + "balance": "439420000000000000000" + }, + "5e11ecf69d551d7f4f84df128046b3a13240a328": { + "balance": "20000000000000000000" + }, + "43ff8853e98ed8406b95000ada848362d6a0392a": { + "balance": "22100000000000000000000" + }, + "f11cf5d363746fee6864d3ca336dd80679bb87ae": { + "balance": "40000000000000000000000" + }, + "fb223c1e22eac1269b32ee156a5385922ed36fb8": { + "balance": "2000000000000000000000" + }, + "4e6600806289454acda330a2a3556010dfacade6": { + "balance": "6000000000000000000000" + }, + "cfe2caaf3cec97061d0939748739bffe684ae91f": { + "balance": "10000000000000000000000" + }, + "adeb52b604e5f77faaac88275b8d6b49e9f9f97f": { + "balance": "2089268000000000000000" + }, + "d53c567f0c3ff2e08b7d59e2b5c73485437fc58d": { + "balance": "600000000000000000000" + }, + "fbf75933e01b75b154ef0669076be87f62dffae1": { + "balance": "78000000000000000000000" + }, + "7dfd2962b575bcbeee97f49142d63c30ab009f66": { + "balance": "4000000000000000000000" + }, + "df6485c4297ac152b289b19dde32c77ec417f47d": { + "balance": "1000000000000000000000" + }, + "ffb974673367f5c07be5fd270dc4b7138b074d57": { + "balance": "2470407000000000000000" + }, + "f7d7af204c56f31fd94398e40df1964bd8bf123c": { + "balance": "150011000000000000000" + }, + "4506fe19fa4b006baa3984529d8516db2b2b50ab": { + "balance": "2000000000000000000000" + }, + "f4dc7ba85480bbb3f535c09568aaa3af6f3721c6": { + "balance": "7214962000000000000000" + }, + "d171c3f2258aef35e599c7da1aa07300234da9a6": { + "balance": "2000000000000000000000" + }, + "33581cee233088c0860d944e0cf1ceabb8261c2e": { + "balance": "13370000000000000000" + }, + "1c2e3607e127caca0fbd5c5948adad7dd830b285": { + "balance": "19700000000000000000000" + }, + "fd7ede8f5240a06541eb699d782c2f9afb2170f6": { + "balance": "1337000000000000000000" + }, + "368c5414b56b8455171fbf076220c1cba4b5ca31": { + "balance": "557940000000000000000" + }, + "3e8745ba322f5fd6cb50124ec46688c7a69a7fae": { + "balance": "4925000000000000000000" + }, + "76506eb4a780c951c74a06b03d3b8362f0999d71": { + "balance": "500000000000000000000" + }, + "96d62dfd46087f62409d93dd606188e70e381257": { + "balance": "2000000000000000000000" + }, + "37eada93c475ded2f7e15e7787d400470fa52062": { + "balance": "200000000000000000000" + }, + "26babf42b267fdcf3861fdd4236a5e474848b358": { + "balance": "1000000000000000000000" + }, + "3526eece1a6bdc3ee7b400fe935b48463f31bed7": { + "balance": "82400000000000000000" + }, + "27b62816e1e3b8d19b79d1513d5dfa855b0c3a2a": { + "balance": "99941000000000000000" + }, + "b3e3c439069880156600c2892e448d4136c92d9b": { + "balance": "850000000000000000000" + }, + "574ad9355390e4889ef42acd138b2a27e78c00ae": { + "balance": "1557000000000000000000" + }, + "f0b9d683cea12ba600baace219b0b3c97e8c00e4": { + "balance": "100000000000000000000" + }, + "a437fe6ec103ca8d158f63b334224eccac5b3ea3": { + "balance": "8000000000000000000000" + }, + "7a48d877b63a8f8f9383e9d01e53e80c528e955f": { + "balance": "8000000000000000000000" + }, + "e965daa34039f7f0df62375a37e5ab8a72b301e7": { + "balance": "4796000000000000000000" + }, + "72cd048a110574482983492dfb1bd27942a696ba": { + "balance": "2000000000000000000000" + }, + "6611ce59a98b072ae959dc49ad511daaaaa19d6b": { + "balance": "200000000000000000000" + }, + "0d92582fdba05eabc3e51538c56db8813785b328": { + "balance": "191000000000000000000" + }, + "e87e9bbfbbb71c1a740c74c723426df55d063dd9": { + "balance": "7998000000000000000000" + }, + "9c99a1da91d5920bc14e0cb914fdf62b94cb8358": { + "balance": "20000000000000000000000" + }, + "fe8e6e3665570dff7a1bda697aa589c0b4e9024a": { + "balance": "2000000000000000000000" + }, + "811461a2b0ca90badac06a9ea16e787b33b196cc": { + "balance": "164000000000000000000" + }, + "d211b21f1b12b5096181590de07ef81a89537ead": { + "balance": "2000000000000000000000" + }, + "01155057002f6b0d18acb9388d3bc8129f8f7a20": { + "balance": "1340000000000000000000" + }, + "8ce22f9fa372449a420610b47ae0c8d565481232": { + "balance": "2000000000000000000000" + }, + "e02b74a47628be315b1f76b315054ad44ae9716f": { + "balance": "4000000000000000000000" + }, + "92a7c5a64362e9f842a23deca21035857f889800": { + "balance": "1999944000000000000000" + }, + "5213f459e078ad3ab95a0920239fcf1633dc04ca": { + "balance": "2599989000000000000000" + }, + "c9957ba94c1b29e5277ec36622704904c63dc023": { + "balance": "1923000000000000000000" + }, + "6ac40f532dfee5118117d2ad352da77d4f6da2c8": { + "balance": "400000000000000000000" + }, + "ea1efb3ce789bedec3d67c3e1b3bc0e9aa227f90": { + "balance": "734000000000000000000" + }, + "b01e389b28a31d8e4995bdd7d7c81beeab1e4119": { + "balance": "1000000000000000000000" + }, + "ee97aa8ac69edf7a987d6d70979f8ec1fbca7a94": { + "balance": "376000000000000000000" + }, + "0fad05507cdc8f24b2be4cb7fa5d927ddb911b88": { + "balance": "3004447000000000000000" + }, + "b6e8afd93dfa9af27f39b4df06076710bee3dfab": { + "balance": "25000000000000000000" + }, + "7d0b255efb57e10f7008aa22d40e9752dfcf0378": { + "balance": "29944000000000000000" + }, + "aef5b12258a18dec07d5ec2e316574919d79d6d6": { + "balance": "2000000000000000000000" + }, + "63666755bd41b5986997783c13043008242b3cb5": { + "balance": "500000000000000000000" + }, + "921f5261f4f612760706892625c75e7bce96b708": { + "balance": "2000000000000000000000" + }, + "10e1e3377885c42d7df218522ee7766887c05e6a": { + "balance": "300031000000000000000" + }, + "134163be9fbbe1c5696ee255e90b13254395c318": { + "balance": "200000000000000000000" + }, + "870f15e5df8b0eabd02569537a8ef93b56785c42": { + "balance": "388000000000000000000" + }, + "68eec1e288ac31b6eaba7e1fbd4f04ad579a6b5d": { + "balance": "2000000000000000000000" + }, + "1a2694ec07cf5e4d68ba40f3e7a14c53f3038c6e": { + "balance": "1000073000000000000000" + }, + "cd9b4cef73390c83a8fd71d7b540a7f9cf8b8c92": { + "balance": "90000000000000000000" + }, + "c8de7a564c7f4012a6f6d10fd08f47890fbf07d4": { + "balance": "300000000000000000000" + }, + "c0345b33f49ce27fe82cf7c84d141c68f590ce76": { + "balance": "1000000000000000000000" + }, + "fe53b94989d89964da2061539526bbe979dd2ea9": { + "balance": "1930600000000000000000" + }, + "14410fb310711be074a80883c635d0ef6afb2539": { + "balance": "2000000000000000000000" + }, + "1d344e962567cb27e44db9f2fac7b68df1c1e6f7": { + "balance": "1940000000000000000000" + }, + "fe016ec17ec5f10e3bb98ff4a1eda045157682ab": { + "balance": "375804000000000000000" + }, + "e89da96e06beaf6bd880b378f0680c43fd2e9d30": { + "balance": "601400000000000000000" + }, + "0fee81ac331efd8f81161c57382bb4507bb9ebec": { + "balance": "400030000000000000000" + }, + "40cf90ef5b768c5da585002ccbe6617650d8e837": { + "balance": "999800000000000000000" + }, + "256fa150cc87b5056a07d004efc84524739e62b5": { + "balance": "200000000000000000000" + }, + "1b9b2dc2960e4cb9408f7405827c9b59071612fd": { + "balance": "1000000000000000000000" + }, + "0efd1789eb1244a3dede0f5de582d8963cb1f39f": { + "balance": "1500000000000000000000" + }, + "049c5d4bc6f25d4e456c697b52a07811ccd19fb1": { + "balance": "300048000000000000000" + }, + "02b7b1d6b34ce053a40eb65cd4a4f7dddd0e9f30": { + "balance": "685000000000000000000" + }, + "c1827686c0169485ec15b3a7c8c01517a2874de1": { + "balance": "40000000000000000000" + }, + "d8e5c9675ef4deed266b86956fc4590ea7d4a27d": { + "balance": "1000000000000000000000" + }, + "48f883e567b436a27bb5a3124dbc84dec775a800": { + "balance": "771840000000000000000" + }, + "a34076f84bd917f20f8342c98ba79e6fb08ecd31": { + "balance": "4200000000000000000000" + }, + "21ce6d5b9018cec04ad6967944bea39e8030b6b8": { + "balance": "20000000000000000000" + }, + "0596a27dc3ee115fce2f94b481bc207a9e261525": { + "balance": "1000000000000000000000" + }, + "717cf9beab3638308ded7e195e0c86132d163fed": { + "balance": "15097428000000000000000" + }, + "d5ce55d1b62f59433c2126bcec09bafc9dfaa514": { + "balance": "197000000000000000000" + }, + "7dd46da677e161825e12e80dc446f58276e1127c": { + "balance": "820000000000000000000" + }, + "98c5494a03ac91a768dffc0ea1dde0acbf889019": { + "balance": "200000000000000000000000" + }, + "617ff2cc803e31c9082233b825d025be3f7b1056": { + "balance": "1970000000000000000000" + }, + "1091176be19b9964a8f72e0ece6bf8e3cfad6e9c": { + "balance": "10020000000000000000000" + }, + "4ea56e1112641c038d0565a9c296c463afefc17e": { + "balance": "182000000000000000000" + }, + "e303167f3d4960fe881b32800a2b4aeff1b088d4": { + "balance": "2000000000000000000000" + }, + "773141127d8cf318aebf88365add3d5527d85b6a": { + "balance": "1000076000000000000000" + }, + "b916b1a01cdc4e56e7657715ea37e2a0f087d106": { + "balance": "2406017000000000000000" + }, + "46a430a2d4a894a0d8aa3feac615361415c3f81f": { + "balance": "2000000000000000000000" + }, + "e6a3010f0201bc94ff67a2f699dfc206f9e76742": { + "balance": "879088000000000000000" + }, + "d7ad09c6d32657685355b5c6ec8e9f57b4ebb982": { + "balance": "1970000000000000000000" + }, + "95e80a82c20cbe3d2060242cb92d735810d034a2": { + "balance": "32511000000000000000" + }, + "9a390162535e398877e416787d6239e0754e937c": { + "balance": "1000000000000000000000" + }, + "d85fdeaf2a61f95db902f9b5a53c9b8f9266c3ac": { + "balance": "2010000000000000000000" + }, + "c3e20c96df8d4e38f50b265a98a906d61bc51a71": { + "balance": "2000000000000000000000" + }, + "2949fd1def5c76a286b3872424809a07db3966f3": { + "balance": "5236067000000000000000" + }, + "86cdb7e51ac44772be3690f61d0e59766e8bfc18": { + "balance": "4000000000000000000000" + }, + "749a4a768b5f237248938a12c623847bd4e688dc": { + "balance": "72000000000000000000" + }, + "3524a000234ebaaf0789a134a2a417383ce5282a": { + "balance": "5635000000000000000000" + }, + "7b43c7eea8d62355b0a8a81da081c6446b33e9e0": { + "balance": "4000000000000000000000" + }, + "0eb189ef2c2d5762a963d6b7bdf9698ea8e7b48a": { + "balance": "1337000000000000000000" + }, + "767fd7797d5169a05f7364321c19843a8c348e1e": { + "balance": "18800000000000000000" + }, + "1b2639588b55c344b023e8de5fd4087b1f040361": { + "balance": "1500000000000000000000" + }, + "1e33d1c2fb5e084f2f1d54bc5267727fec3f985d": { + "balance": "500000000000000000000" + }, + "06b106649aa8c421ddcd1b8c32cd0418cf30da1f": { + "balance": "40000000000000000000000" + }, + "3c5a241459c6abbf630239c98a30d20b8b3ac561": { + "balance": "157600000000000000000" + }, + "0f4f94b9191bb7bb556aaad7c74ddb288417a50b": { + "balance": "1400000000000000000000" + }, + "d6f4a7d04e8faf20e8c6eb859cf7f78dd23d7a15": { + "balance": "131784000000000000000" + }, + "61adf5929a5e2981684ea243baa01f7d1f5e148a": { + "balance": "110302000000000000000" + }, + "8f58d8348fc1dc4e0dd8343b6543c857045ee940": { + "balance": "13632400000000000000000" + }, + "a6e3baa38e104a1e27a4d82869afb1c0ae6eff8d": { + "balance": "19690000000000000000" + }, + "67350b5331926f5e28f3c1e986f96443809c8b8c": { + "balance": "352000000000000000000" + }, + "0b5d66b13c87b392e94d91d5f76c0d450a552843": { + "balance": "2000000000000000000000" + }, + "562a8dcbbeeef7b360685d27303bd69e094accf6": { + "balance": "10000000000000000000000" + }, + "b5d9934d7b292bcf603b2880741eb760288383a0": { + "balance": "16700000000000000000" + }, + "6fc53662371dca587b59850de78606e2359df383": { + "balance": "180000000000000000000" + }, + "e069c0173352b10bf6834719db5bed01adf97bbc": { + "balance": "18894000000000000000" + }, + "10a93457496f1108cd98e140a1ecdbae5e6de171": { + "balance": "399600000000000000000" + }, + "69ff8901b541763f817c5f2998f02dcfc1df2997": { + "balance": "40000000000000000000" + }, + "00c27d63fde24b92ee8a1e7ed5d26d8dc5c83b03": { + "balance": "2000000000000000000000" + }, + "77f81b1b26fc84d6de97ef8b9fbd72a33130cc4a": { + "balance": "1000000000000000000000" + }, + "6d20ef9704670a500bb269b5832e859802049f01": { + "balance": "130000000000000000000" + }, + "186afdc085f2a3dce4615edffbadf71a11780f50": { + "balance": "200000000000000000000" + }, + "7ff0c63f70241bece19b737e5341b12b109031d8": { + "balance": "346000000000000000000" + }, + "9d4174aa6af28476e229dadb46180808c67505c1": { + "balance": "1219430000000000000000" + }, + "5fec49c665e64ee89dd441ee74056e1f01e92870": { + "balance": "6320000000000000000000" + }, + "6cd228dc712169307fe27ceb7477b48cfc8272e5": { + "balance": "77600000000000000000" + }, + "fd918536a8efa6f6cefe1fa1153995fef5e33d3b": { + "balance": "500000000000000000000" + }, + "2fbb504a5dc527d3e3eb0085e2fc3c7dd538cb7a": { + "balance": "1249961000000000000000" + }, + "6ab323ae5056ed0a453072c5abe2e42fcf5d7139": { + "balance": "880000000000000000000" + }, + "67d682a282ef73fb8d6e9071e2614f47ab1d0f5e": { + "balance": "1000000000000000000000" + }, + "1858cf11aea79f5398ad2bb22267b5a3c952ea74": { + "balance": "9850000000000000000000" + }, + "39d6caca22bccd6a72f87ee7d6b59e0bde21d719": { + "balance": "2002000000000000000000" + }, + "daa63cbda45dd487a3f1cd4a746a01bb5e060b90": { + "balance": "4797800000000000000000" + }, + "a90476e2efdfee4f387b0f32a50678b0efb573b5": { + "balance": "10000000000000000000000" + }, + "ae5aa1e6c2b60f6fd3efe721bb4a719cbe3d6f5d": { + "balance": "795860000000000000000" + }, + "ac2e766dac3f648f637ac6713fddb068e4a4f04d": { + "balance": "197000000000000000000" + }, + "6191ddc9b64a8e0890b4323709d7a07c48b92a64": { + "balance": "775000000000000000000" + }, + "cc4f0ff2aeb67d54ce3bc8c6510b9ae83e9d328b": { + "balance": "400000000000000000000" + }, + "ca23f62dff0d6460036c62e840aec5577e0befd2": { + "balance": "140800000000000000000" + }, + "97dc26ec670a31e0221d2a75bc5dc9f90c1f6fd4": { + "balance": "50000000000000000000" + }, + "848c994a79003fe7b7c26cc63212e1fc2f9c19eb": { + "balance": "2000000000000000000000" + }, + "20c284ba10a20830fc3d699ec97d2dfa27e1b95e": { + "balance": "2000000000000000000000" + }, + "4fa3f32ef4086448b344d5f0a9890d1ce4d617c3": { + "balance": "1500000000000000000000" + }, + "255abc8d08a096a88f3d6ab55fbc7352bddcb9ce": { + "balance": "82161000000000000000" + }, + "7c60e51f0be228e4d56fdd2992c814da7740c6bc": { + "balance": "200000000000000000000" + }, + "1c356cfdb95febb714633b28d5c132dd84a9b436": { + "balance": "25000000000000000000" + }, + "5062e5134c612f12694dbd0e131d4ce197d1b6a4": { + "balance": "1000000000000000000000" + }, + "ed862616fcbfb3becb7406f73c5cbff00c940755": { + "balance": "1700000000000000000000" + }, + "62c9b271ffd5b770a5eee4edc9787b5cdc709714": { + "balance": "2000000000000000000000" + }, + "3c925619c9b33144463f0537d896358706c520b0": { + "balance": "2000000000000000000000" + }, + "ffe2e28c3fb74749d7e780dc8a5d422538e6e451": { + "balance": "253319000000000000000" + }, + "37195a635dcc62f56a718049d47e8f9f96832891": { + "balance": "1970000000000000000000" + }, + "90e9a9a82edaa814c284d232b6e9ba90701d4952": { + "balance": "100007000000000000000" + }, + "e0c4ab9072b4e6e3654a49f8a8db026a4b3386a9": { + "balance": "2000000000000000000000" + }, + "439dee3f7679ff1030733f9340c096686b49390b": { + "balance": "2000000000000000000000" + }, + "548558d08cfcb101181dac1eb6094b4e1a896fa6": { + "balance": "1999944000000000000000" + }, + "3090f8130ec44466afadb36ed3c926133963677b": { + "balance": "4000000000000000000000" + }, + "d1648503b1ccc5b8be03fa1ec4f3ee267e6adf7b": { + "balance": "5828000000000000000000" + }, + "65b42faecc1edfb14283ca979af545f63b30e60c": { + "balance": "18200000000000000000" + }, + "6420f8bcc8164a6152a99d6b99693005ccf7e053": { + "balance": "999972000000000000000" + }, + "84b4b74e6623ba9d1583e0cfbe49643f16384149": { + "balance": "20000000000000000000" + }, + "b8310a16cc6abc465007694b930f978ece1930bd": { + "balance": "740000000000000000000" + }, + "16019a4dafab43f4d9bf4163fae0847d848afca2": { + "balance": "25060000000000000000" + }, + "479298a9de147e63a1c7d6d2fce089c7e64083bd": { + "balance": "9999999000000000000000" + }, + "030973807b2f426914ad00181270acd27b8ff61f": { + "balance": "5348000000000000000000" + }, + "b07bcf1cc5d4462e5124c965ecf0d70dc27aca75": { + "balance": "1600000000000000000000" + }, + "a2f798e077b07d86124e1407df32890dbb4b6379": { + "balance": "200000000000000000000" + }, + "0cbd921dbe121563b98a6871fecb14f1cc7e88d7": { + "balance": "200000000000000000000" + }, + "6042276df2983fe2bc4759dc1943e18fdbc34f77": { + "balance": "1970000000000000000000" + }, + "be2b2280523768ea8ac35cd9e888d60a719300d4": { + "balance": "2000000000000000000000" + }, + "2f4da753430fc09e73acbccdcde9da647f2b5d37": { + "balance": "200000000000000000000" + }, + "734223d27ff23e5906caed22595701bb34830ca1": { + "balance": "2000000000000000000000" + }, + "5b430d779696a3653fc60e74fbcbacf6b9c2baf1": { + "balance": "14000000000000000000000" + }, + "84232107932b12e03186583525ce023a703ef8d9": { + "balance": "2000000000000000000000" + }, + "4ed14d81b60b23fb25054d8925dfa573dcae6168": { + "balance": "340000000000000000000" + }, + "8b338411f26ccf37658cc75521d77629099e467d": { + "balance": "2000000000000000000000" + }, + "a37622ac9bbdc4d82b75015d745b9f8de65a28ec": { + "balance": "2910000000000000000000" + }, + "1dd77441844afe9cc18f15d8c77bccfb655ee034": { + "balance": "4850000000000000000000" + }, + "65849be1af20100eb8a3ba5a5be4d3ae8db5a70e": { + "balance": "400000000000000000000" + }, + "d5586da4e59583c8d86cccf71a86197f17996749": { + "balance": "2000000000000000000000" + }, + "4b53ae59c784b6b5c43616b9a0809558e684e10c": { + "balance": "1200000000000000000000" + }, + "55d42eb495bf46a634997b5f2ea362814918e2b0": { + "balance": "106128000000000000000" + }, + "959ff17f1d51b473b44010052755a7fa8c75bd54": { + "balance": "1970000000000000000000" + }, + "5a2daab25c31a61a92a4c82c9925a1d2ef58585e": { + "balance": "225400000000000000000" + }, + "24c0c88b54a3544709828ab4ab06840559f6c5e2": { + "balance": "2674000000000000000000" + }, + "7e8649e690fc8c1bfda1b5e186581f649b50fe33": { + "balance": "98500000000000000000" + }, + "4acfa9d94eda6625c9dfa5f9f4f5d107c4031fdf": { + "balance": "39400000000000000000" + }, + "5778ffdc9b94c5a59e224eb965b6de90f222d170": { + "balance": "335320000000000000000" + }, + "825a7f4e10949cb6f8964268f1fa5f57e712b4c4": { + "balance": "20000000000000000000" + }, + "6f39cc37caaa2ddc9b610f6131e0619fae772a3c": { + "balance": "500000000000000000000" + }, + "5b437365ae3a9a2ff97c68e6f90a7620188c7d19": { + "balance": "2002000000000000000000" + }, + "6710c2c03c65992b2e774be52d3ab4a6ba217ef7": { + "balance": "11600000000000000000000" + }, + "896e335ca47af57962fa0f4dbf3e45e688cba584": { + "balance": "1368500000000000000000" + }, + "b57549bfbc9bdd18f736b22650e48a73601fa65c": { + "balance": "446000000000000000000" + }, + "85ca1e727e9d1a87991cc2c41840ebb9edf21d1b": { + "balance": "13370000000000000000" + }, + "cf4166746e1d3bc1f8d0714b01f17e8a62df1464": { + "balance": "1004700000000000000000" + }, + "4a75c3d4fa6fccbd5dd5a703c15379a1e783e9b7": { + "balance": "1820000000000000000000" + }, + "9e5811b40be1e2a1e1d28c3b0774acde0a09603d": { + "balance": "3000000000000000000000" + }, + "763886e333c56feff85be3951ab0b889ce262e95": { + "balance": "2000000000000000000000" + }, + "2b101e822cd962962a06800a2c08d3b15d82b735": { + "balance": "152000000000000000000" + }, + "a01e9476df84431825c836e8803a97e22fa5a0cd": { + "balance": "6000000000000000000000" + }, + "be4e7d983f2e2a636b1102ec7039efebc842e98d": { + "balance": "66000000000000000000" + }, + "9e427272516b3e67d4fcbf82f59390d04c8e28e5": { + "balance": "4000000000000000000000" + }, + "e0d231e144ec9107386c7c9b02f1702ceaa4f700": { + "balance": "5000057000000000000000" + }, + "6a0f056066c2d56628850273d7ecb7f8e6e9129e": { + "balance": "5000016000000000000000" + }, + "d1538e9a87e59ca9ec8e5826a5b793f99f96c4c3": { + "balance": "1000000000000000000000" + }, + "f85bab1cb3710fc05fa19ffac22e67521a0ba21d": { + "balance": "2003000000000000000000" + }, + "f7cbdba6be6cfe68dbc23c2b0ff530ee05226f84": { + "balance": "20000000000000000000" + }, + "4eb87ba8788eba0df87e5b9bd50a8e45368091c1": { + "balance": "20000000000000000000" + }, + "1479a9ec7480b74b5db8fc499be352da7f84ee9c": { + "balance": "1000000000000000000000" + }, + "d311bcd7aa4e9b4f383ff3d0d6b6e07e21e3705d": { + "balance": "200000000000000000000" + }, + "425c1816868f7777cc2ba6c6d28c9e1e796c52b3": { + "balance": "10000000000000000000000" + }, + "8510ee934f0cbc900e1007eb38a21e2a5101b8b2": { + "balance": "106000000000000000000" + }, + "01e864d354741b423e6f42851724468c74f5aa9c": { + "balance": "20000000000000000000000" + }, + "a543a066fb32a8668aa0736a0c9cd40d78098727": { + "balance": "1000000000000000000000" + }, + "f3eb1948b951e22df1617829bf3b8d8680ec6b68": { + "balance": "4000000000000000000000" + }, + "f6b782f4dcd745a6c0e2e030600e04a24b25e542": { + "balance": "400000000000000000000" + }, + "229f4f1a2a4f540774505b4707a81de44410255b": { + "balance": "2000000000000000000000" + }, + "cff8d06b00e3f50c191099ad56ba6ae26571cd88": { + "balance": "1000000000000000000000" + }, + "910b7d577a7e39aa23acf62ad7f1ef342934b968": { + "balance": "10000000000000000000000" + }, + "392433d2ce83d3fb4a7602cca3faca4ec140a4b0": { + "balance": "51000000000000000000" + }, + "8ff46045687723dc33e4d099a06904f1ebb584dc": { + "balance": "2000000000000000000000" + }, + "9ca0429f874f8dcee2e9c062a9020a842a587ab9": { + "balance": "2000000000000000000000" + }, + "160ceb6f980e04315f53c4fc988b2bf69e284d7d": { + "balance": "19100000000000000000" + }, + "c340f9b91c26728c31d121d5d6fc3bb56d3d8624": { + "balance": "2000000000000000000000" + }, + "afa1d5ad38fed44759c05b8993c1aa0dace19f40": { + "balance": "80000000000000000000" + }, + "3969b4f71bb8751ede43c016363a7a614f76118e": { + "balance": "2000000000000000000000" + }, + "2bb6f578adfbe7b2a116b3554facf9969813c319": { + "balance": "7400000000000000000000" + }, + "8334764b7b397a4e578f50364d60ce44899bff94": { + "balance": "92500000000000000000" + }, + "9dd2196624a1ddf14a9d375e5f07152baf22afa2": { + "balance": "1211747000000000000000" + }, + "f242da845d42d4bf779a00f295b40750fe49ea13": { + "balance": "1000000000000000000000" + }, + "c6234657a807384126f8968ca1708bb07baa493c": { + "balance": "20000000000000000000" + }, + "94c055e858357aaa30cf2041fa9059ce164a1f91": { + "balance": "19999000000000000000000" + }, + "74c73c90528a157336f1e7ea20620ae53fd24728": { + "balance": "8969310000000000000000" + }, + "19e7f3eb7bf67f3599209ebe08b62ad3327f8cde": { + "balance": "2000000000000000000000" + }, + "b2b516fdd19e7f3864b6d2cf1b252a4156f1b03b": { + "balance": "53720000000000000000" + }, + "8164e78314ae16b28926cc553d2ccb16f356270d": { + "balance": "8450000000000000000000" + }, + "4d828894752f6f25175daf2177094487954b6f9f": { + "balance": "1459683000000000000000" + }, + "ab84a0f147ad265400002b85029a41fc9ce57f85": { + "balance": "1000000000000000000000" + }, + "f3fe51fde34413c73318b9c85437fe7e820f561a": { + "balance": "1003200000000000000000" + }, + "16c7b31e8c376282ac2271728c31c95e35d952c3": { + "balance": "2000000000000000000000" + }, + "80d5c40c59c7f54ea3a55fcfd175471ea35099b3": { + "balance": "1000000000000000000000" + }, + "7abb10f5bd9bc33b8ec1a82d64b55b6b18777541": { + "balance": "20000000000000000000000" + }, + "095b0ea2b218d82e0aea7c2889238a39c9bf9077": { + "balance": "20000000000000000000000" + }, + "5d5cdbe25b2a044b7b9be383bcaa5807b06d3c6b": { + "balance": "2000000000000000000000" + }, + "323749a3b971959e46c8b4822dcafaf7aaf9bd6e": { + "balance": "20064000000000000000" + }, + "e0272213e8d2fd3e96bd6217b24b4ba01b617079": { + "balance": "20000000000000000000" + }, + "00acbfb2f25a5485c739ef70a44eeeeb7c65a66f": { + "balance": "100000000000000000000" + }, + "52f15423323c24f19ae2ab673717229d3f747d9b": { + "balance": "1026115000000000000000" + }, + "cb4abfc282aed76e5d57affda542c1f382fcacf4": { + "balance": "8136100000000000000000" + }, + "f71b4534f286e43093b1e15efea749e7597b8b57": { + "balance": "104410000000000000000000" + }, + "44cd77535a893fa7c4d5eb3a240e79d099a72d2d": { + "balance": "820000000000000000000" + }, + "eb3ce7fc381c51db7d5fbd692f8f9e058a4c703d": { + "balance": "200000000000000000000" + }, + "f1c8c4a941b4628c0d6c30fda56452d99c7e1b64": { + "balance": "1449000000000000000000" + }, + "277677aba1e52c3b53bfa2071d4e859a0af7e8e1": { + "balance": "1000000000000000000000" + }, + "a5f075fd401335577b6683c281e6d101432dc6e0": { + "balance": "2680000000000000000000" + }, + "e28dbc8efd5e416a762ec0e018864bb9aa83287b": { + "balance": "24533161000000000000000" + }, + "2b717cd432a323a4659039848d3b87de26fc9546": { + "balance": "500000000000000000000000" + }, + "b358e97c70b605b1d7d729dfb640b43c5eafd1e7": { + "balance": "20000000000000000000000" + }, + "293c2306df3604ae4fda0d207aba736f67de0792": { + "balance": "200000000000000000000" + }, + "74d366b07b2f56477d7c7077ac6fe497e0eb6559": { + "balance": "5000000000000000000000" + }, + "490145afa8b54522bb21f352f06da5a788fa8f1d": { + "balance": "9231182000000000000000" + }, + "862569211e8c6327b5415e3a67e5738b15baaf6e": { + "balance": "140000000000000000000" + }, + "5a74ba62e7c81a3474e27d894fed33dd24ad95fe": { + "balance": "18200000000000000000" + }, + "536e4d8029b73f5579dca33e70b24eba89e11d7e": { + "balance": "1970000000000000000000" + }, + "25c6e74ff1d928df98137af4df8430df24f07cd7": { + "balance": "390000000000000000000" + }, + "19b36b0c87ea664ed80318dc77b688dde87d95a5": { + "balance": "1948386000000000000000" + }, + "abc4caeb474d4627cb6eb456ecba0ecd08ed8ae1": { + "balance": "3940000000000000000000" + }, + "8ea656e71ec651bfa17c5a5759d86031cc359977": { + "balance": "100000000000000000000" + }, + "8d620bde17228f6cbba74df6be87264d985cc179": { + "balance": "100000000000000000000" + }, + "b2aa2f1f8e93e79713d92cea9ffce9a40af9c82d": { + "balance": "2000000000000000000000" + }, + "198ef1ec325a96cc354c7266a038be8b5c558f67": { + "balance": "608334724000000000000000" + }, + "6a13d5e32c1fd26d7e91ff6e053160a89b2c8aad": { + "balance": "53480000000000000000" + }, + "e056bf3ff41c26256fef51716612b9d39ade999c": { + "balance": "100009000000000000000" + }, + "2c128c95d957215101f043dd8fc582456d41016d": { + "balance": "835000000000000000000" + }, + "2560b09b89a4ae6849ed5a3c9958426631714466": { + "balance": "1700000000000000000000" + }, + "d3d6e9fb82542fd29ed9ea3609891e151396b6f7": { + "balance": "54000000000000000000000" + }, + "a7607b42573bb6f6b4d4f23c7e2a26b3a0f6b6f0": { + "balance": "1610000000000000000000" + }, + "020362c3ade878ca90d6b2d889a4cc5510eed5f3": { + "balance": "1042883000000000000000" + }, + "14830704e99aaad5c55e1f502b27b22c12c91933": { + "balance": "620000000000000000000" + }, + "8030b111c6983f0485ddaca76224c6180634789f": { + "balance": "80000000000000000000" + }, + "2c5b7d7b195a371bf9abddb42fe04f2f1d9a9910": { + "balance": "200000000000000000000" + }, + "77d43fa7b481dbf3db530cfbf5fdced0e6571831": { + "balance": "2000000000000000000000" + }, + "2d90b415a38e2e19cdd02ff3ad81a97af7cbf672": { + "balance": "109800000000000000000" + }, + "2fc82ef076932341264f617a0c80dd571e6ae939": { + "balance": "7160000000000000000000" + }, + "dfe549fe8430e552c6d07cc3b92ccd43b12fb50f": { + "balance": "83620000000000000000" + }, + "1e8e689b02917cdc29245d0c9c68b094b41a9ed6": { + "balance": "2000000000000000000000" + }, + "21c3a8bba267c8cca27b1a9afabad86f607af708": { + "balance": "8940000000000000000000" + }, + "143c639752caeecf6a997d39709fc8f19878c7e8": { + "balance": "1970000000000000000000" + }, + "02603d7a3bb297c67c877e5d34fbd5b913d4c63a": { + "balance": "20000000000000000000" + }, + "a166f911c644ac3213d29e0e1ae010f794d5ad26": { + "balance": "2000000000000000000000" + }, + "6eb3819617404058268f0c3cff3596bfe9148c1c": { + "balance": "1670000000000000000000" + }, + "7a67dd043a504fc2f2fc7194e9becf484cecb1fb": { + "balance": "250000000000000000000" + }, + "f824ee331e4ac3cc587693395b57ecf625a6c0c2": { + "balance": "1600930000000000000000" + }, + "1179c60dbd068b150b074da4be23033b20c68558": { + "balance": "680000000000000000000" + }, + "d2a479404347c5543aab292ae1bb4a6f158357fa": { + "balance": "4000000000000000000000" + }, + "b0d32bd7e4e695b7b01aa3d0416f80557dba9903": { + "balance": "16300000000000000000000" + }, + "f734ec03724ddee5bb5279aa1afcf61b0cb448a1": { + "balance": "4238080000000000000000" + }, + "c04069dfb18b096c7867f8bee77a6dc7477ad062": { + "balance": "2674000000000000000000" + }, + "80c53ee7e3357f94ce0d7868009c208b4a130125": { + "balance": "2000000000000000000000" + }, + "0f32d9cb4d0fdaa0150656bb608dcc43ed7d9301": { + "balance": "753978000000000000000" + }, + "6ddb6092779d5842ead378e21e8120fd4c6bc132": { + "balance": "2000000000000000000000" + }, + "82ea01e3bf2e83836e71704e22a2719377efd9c3": { + "balance": "3040000000000000000000" + }, + "44c1110b18870ec81178d93d215838c551d48e64": { + "balance": "199958000000000000000" + }, + "7727af101f0aaba4d23a1cafe17c6eb5dab1c6dc": { + "balance": "2000000000000000000000" + }, + "a11a03c4bb26d21eff677d5d555c80b25453ee7a": { + "balance": "69979000000000000000" + }, + "19e5dea3370a2c746aae34a37c531f41da264e83": { + "balance": "200000000000000000000" + }, + "c325c352801ba883b3226c5feb0df9eae2d6e653": { + "balance": "3940000000000000000000" + }, + "ae5055814cb8be0c117bb8b1c8d2b63b4698b728": { + "balance": "32035000000000000000" + }, + "deb1bc34d86d4a4dde2580d8beaf074eb0e1a244": { + "balance": "1580000000000000000000" + }, + "558360206883dd1b6d4a59639e5629d0f0c675d0": { + "balance": "2000000000000000000000" + }, + "a9d6f871ca781a759a20ac3adb972cf12829a208": { + "balance": "925000000000000000000" + }, + "b0ac4eff6680ee14169cdadbffdb30804f6d25f5": { + "balance": "2000000000000000000000" + }, + "f1b58faffa8794f50af8e88309c7a6265455d51a": { + "balance": "999800000000000000000" + }, + "a61a54df784a44d71b771b87317509211381f200": { + "balance": "1000000000000000000000" + }, + "baa4b64c2b15b79f5f204246fd70bcbd86e4a92a": { + "balance": "500000000000000000000" + }, + "a20d8ff60caae31d02e0b665fa435d76f77c9442": { + "balance": "489600000000000000000" + }, + "f3e74f470c7d3a3f0033780f76a89f3ef691e6cb": { + "balance": "3021800000000000000000" + }, + "d330728131fe8e3a15487a34573c93457e2afe95": { + "balance": "4000000000000000000000" + }, + "9af9dbe47422d177f945bdead7e6d82930356230": { + "balance": "3940000000000000000000" + }, + "0eb5b662a1c718608fd52f0c25f9378830178519": { + "balance": "6091400000000000000000" + }, + "fda6810ea5ac985d6ffbf1c511f1c142edcfddf7": { + "balance": "4000000000000000000000" + }, + "832c54176bdf43d2c9bcd7b808b89556b89cbf31": { + "balance": "200000000000000000000" + }, + "704d5de4846d39b53cd21d1c49f096db5c19ba29": { + "balance": "152000000000000000000" + }, + "344a8db086faed4efc37131b3a22b0782dad7095": { + "balance": "500000000000000000000" + }, + "8c7fa5cae82fedb69ab189d3ff27ae209293fb93": { + "balance": "400030000000000000000" + }, + "ad660dec825522a9f62fcec3c5b731980dc286ea": { + "balance": "3000000000000000000000" + }, + "13b9b10715714c09cfd610cf9c9846051cb1d513": { + "balance": "1970000000000000000000" + }, + "40467d80e74c35407b7db51789234615fea66818": { + "balance": "388000000000000000000" + }, + "30e9d5a0088f1ddb2fd380e2a049192266c51cbf": { + "balance": "196910000000000000000" + }, + "b2d1e99af91231858e7065dd1918330dc4c747d5": { + "balance": "16700000000000000000000" + }, + "9f21302ca5096bea7402b91b0fd506254f999a3d": { + "balance": "1246832000000000000000" + }, + "d24b6644f439c8051dfc64d381b8c86c75c17538": { + "balance": "2000000000000000000000" + }, + "8228ebc087480fd64547ca281f5eace3041453b9": { + "balance": "1970000000000000000000" + }, + "29da3e35b23bb1f72f8e2258cf7f553359d24bac": { + "balance": "20000000000000000000000" + }, + "c8e558a3c5697e6fb23a2594c880b7a1b68f9860": { + "balance": "10000000000000000000000" + }, + "6b951a43274eeafc8a0903b0af2ec92bf1efc839": { + "balance": "100000000000000000000" + }, + "d015f6fcb84df7bb410e8c8f04894a881dcac237": { + "balance": "1038000000000000000000" + }, + "6ccb03acf7f53ce87aadcc21a9932de915f89804": { + "balance": "8000000000000000000000" + }, + "388c85a9b9207d8146033fe38143f6d34b595c47": { + "balance": "200000000000000000000" + }, + "429c06b487e8546abdfc958a25a3f0fba53f6f00": { + "balance": "13503000000000000000" + }, + "771507aeee6a255dc2cd9df55154062d0897b297": { + "balance": "334250000000000000000" + }, + "5a2b1c853aeb28c45539af76a00ac2d8a8242896": { + "balance": "25000000000000000000" + }, + "f4d67a9044b435b66e8977ff39a28dc4bd53729a": { + "balance": "200000000000000000000" + }, + "063759dd1c4e362eb19398951ff9f8fad1d31068": { + "balance": "10000000000000000000000" + }, + "cb58990bcd90cfbf6d8f0986f6fa600276b94e2d": { + "balance": "999925000000000000000" + }, + "6df5c84f7b909aab3e61fe0ecb1b3bf260222ad2": { + "balance": "4000000000000000000000" + }, + "deb2495d6aca7b2a6a2d138b6e1a42e2dc311fdd": { + "balance": "2000000000000000000000" + }, + "59203cc37599b648312a7cc9e06dacb589a9ae6a": { + "balance": "148689000000000000000" + }, + "fc9b347464b2f9929d807e039dae48d3d98de379": { + "balance": "14000000000000000000000" + }, + "48d2434b7a7dbbff08223b6387b05da2e5093126": { + "balance": "18000000000000000000000" + }, + "c9d76446d5aadff80b68b91b08cd9bc8f5551ac1": { + "balance": "714000000000000000000" + }, + "3d31587b5fd5869845788725a663290a49d3678c": { + "balance": "500000000000000000000" + }, + "d8715ef9176f850b2e30eb8e382707f777a6fbe9": { + "balance": "2000000000000000000000" + }, + "2c2147947ae33fb098b489a5c16bfff9abcd4e2a": { + "balance": "200000000000000000000" + }, + "d6c0d0bc93a62e257174700e10f024c8b23f1f87": { + "balance": "2000000000000000000000" + }, + "d1978f2e34407fab1dc2183d95cfda6260b35982": { + "balance": "788000000000000000000" + }, + "1bf974d9904f45ce81a845e11ef4cbcf27af719e": { + "balance": "100000000000000000000" + }, + "6e761eaa0f345f777b5441b73a0fa5b56b85f22d": { + "balance": "2000000000000000000000" + }, + "ea60436912de6bf187d3a472ff8f5333a0f7ed06": { + "balance": "19700000000000000000" + }, + "94f8f057db7e60e675ad940f155885d1a477348e": { + "balance": "401100000000000000000" + }, + "8933491760c8f0b4df8caac78ed835caee21046d": { + "balance": "20000000000000000000000" + }, + "a7775e4af6a23afa201fb78b915e51a515b7a728": { + "balance": "120000000000000000000" + }, + "d8d64384249b776794063b569878d5e3b530a4b2": { + "balance": "177569000000000000000" + }, + "be633a3737f68439bac7c90a52142058ee8e8a6f": { + "balance": "960000000000000000000" + }, + "90bd62a050845261fa4a9f7cf241ea630b05efb8": { + "balance": "500000000000000000000" + }, + "552987f0651b915b2e1e5328c121960d4bdd6af4": { + "balance": "1790000000000000000000" + }, + "0baf6ecdb91acb3606a8357c0bc4f45cfd2d7e6f": { + "balance": "1000000000000000000000" + }, + "9e5a311d9f69898a7c6a9d6360680438e67a7b2f": { + "balance": "1490000000000000000000" + }, + "78859c5b548b700d9284cee4b6633c2f52e529c2": { + "balance": "2955000000000000000000" + }, + "d572309169b1402ec8131a17a6aac3222f89e6eb": { + "balance": "13800000000000000000000" + }, + "8e6d7485cbe990acc1ad0ee9e8ccf39c0c93440e": { + "balance": "955000000000000000000" + }, + "75c11d024d12ae486c1095b7a7b9c4af3e8edeb9": { + "balance": "20000000000000000000" + }, + "903413878aea3bc1086309a3fe768b65559e8cab": { + "balance": "8000000000000000000000" + }, + "6d0569e5558fc7df2766f2ba15dc8aeffc5beb75": { + "balance": "4001070000000000000000" + }, + "3815b0743f94fc8cc8654fd9d597ed7d8b77c57e": { + "balance": "738578000000000000000" + }, + "0f26480a150961b8e30750713a94ee6f2e47fc00": { + "balance": "1000000000000000000000" + }, + "ede5de7c7fb7eee0f36e64530a41440edfbefacf": { + "balance": "617200000000000000000" + }, + "763a7cbab70d7a64d0a7e52980f681472593490c": { + "balance": "600000000000000000000" + }, + "6e270ad529f1f0b8d9cb6d2427ec1b7e2dc64a74": { + "balance": "200000000000000000000" + }, + "eb3bdd59dcdda5a9bb2ac1641fd02180f5f36560": { + "balance": "6600000000000000000000" + }, + "f4ebf50bc7e54f82e9b9bd24baef29438e259ce6": { + "balance": "10000000000000000000000" + }, + "882c8f81872c79fed521cb5f950d8b032322ea69": { + "balance": "40000000000000000000000" + }, + "394132600f4155e07f4d45bc3eb8d9fb72dcd784": { + "balance": "2941000000000000000000" + }, + "0be2b94ad950a2a62640c35bfccd6c67dae450f6": { + "balance": "1940000000000000000000" + }, + "d4c6ac742e7c857d4a05a04c33d4d05c1467571d": { + "balance": "200000000000000000000" + }, + "1fddd85fc98be9c4045961f40f93805ecc4549e5": { + "balance": "164000000000000000000" + }, + "534065361cb854fac42bfb5c9fcde0604ac919da": { + "balance": "2000000000000000000000" + }, + "9a6ff5f6a7af7b7ae0ed9c20ecec5023d281b786": { + "balance": "2547000000000000000000" + }, + "4f3a4854911145ea01c644044bdb2e5a960a982f": { + "balance": "4000000000000000000000" + }, + "00497e92cdc0e0b963d752b2296acb87da828b24": { + "balance": "194800000000000000000" + }, + "4ff67fb87f6efba9279930cfbd1b7a343c79fade": { + "balance": "400000000000000000000" + }, + "62f2e5ccecd52cc4b95e0597df27cc079715608c": { + "balance": "143000000000000000000" + }, + "1eda084e796500ba14c5121c0d90846f66e4be62": { + "balance": "534800000000000000000" + }, + "9836b4d30473641ab56aeee19242761d72725178": { + "balance": "2000000000000000000000" + }, + "de55de0458f850b37e4d78a641dd2eb2dd8f38ce": { + "balance": "4000000000000000000000" + }, + "140ca28ff33b9f66d7f1fc0078f8c1eef69a1bc0": { + "balance": "1600000000000000000000" + }, + "2014261f01089f53795630ba9dd24f9a34c2d942": { + "balance": "1337000000000000000000" + }, + "11415fab61e0dfd4b90676141a557a869ba0bde9": { + "balance": "2048000000000000000000" + }, + "88344909644c7ad4930fd873ca1c0da2d434c07f": { + "balance": "131970000000000000000" + }, + "88b217ccb786a254cf4dc57f5d9ac3c455a30483": { + "balance": "925000000000000000000" + }, + "dfdbcec1014b96da2158ca513e9c8d3b9af1c3d0": { + "balance": "2000000000000000000000" + }, + "1ba9f7997e5387b6b2aa0135ac2452fe36b4c20d": { + "balance": "850000000000000000000" + }, + "d70ad2c4e9eebfa637ef56bd486ad2a1e5bce093": { + "balance": "200000000000000000000" + }, + "9ce27f245e02d1c312c1d500788c9def7690453b": { + "balance": "200000000000000000000" + }, + "8234f463d18485501f8f85ace4972c9b632dbccc": { + "balance": "2000000000000000000000" + }, + "994152fc95d5c1ca8b88113abbad4d710e40def6": { + "balance": "500000000000000000000" + }, + "e5b980d28eece2c06fca6c9473068b37d4a6d6e9": { + "balance": "695200000000000000000" + }, + "2d426912d059fad9740b2e390a2eeac0546ff01b": { + "balance": "1400000000000000000000" + }, + "6d9997509882027ea947231424bedede2965d0ba": { + "balance": "2001600000000000000000" + }, + "167ce7de65e84708595a525497a3eb5e5a665073": { + "balance": "575400000000000000000" + }, + "e430c0024fdbf73a82e21fccf8cbd09138421c21": { + "balance": "4000000000000000000000" + }, + "2e52912bc10ea39d54e293f7aed6b99a0f4c73be": { + "balance": "400000000000000000000" + }, + "12cf8b0e465213211a5b53dfb0dd271a282c12c9": { + "balance": "15200000000000000000" + }, + "06964e2d17e9189f88a8203936b40ac96e533c06": { + "balance": "18200000000000000000" + }, + "66b1a63da4dcd9f81fe54f5e3fcb4055ef7ec54f": { + "balance": "201412000000000000000" + }, + "0a77e7f72b437b574f00128b21f2ac265133528c": { + "balance": "2000000000000000000000" + }, + "78f5c74785c5668a838072048bf8b453594ddaab": { + "balance": "400000000000000000000" + }, + "58e554af3d87629620da61d538c7f5b4b54c4afe": { + "balance": "1297081000000000000000" + }, + "37a10451f36166cf643dd2de6c1cbba8a011cfa3": { + "balance": "380000000000000000000" + }, + "fe9ad12ef05d6d90261f96c8340a0381974df477": { + "balance": "2000000000000000000000" + }, + "057f7f81cd7a406fc45994408b5049912c566463": { + "balance": "1700000000000000000000" + }, + "55a3df57b7aaec16a162fd5316f35bec082821cf": { + "balance": "1970000000000000000000" + }, + "c0e0b903088e0c63f53dd069575452aff52410c3": { + "balance": "3000000000000000000000" + }, + "63e88e2e539ffb450386b4e46789b223f5476c45": { + "balance": "6292000000000000000000" + }, + "3727341f26c12001e378405ee38b2d8464ec7140": { + "balance": "2000000000000000000000" + }, + "c96751656c0a8ef4357b7344322134b983504aca": { + "balance": "2000000000000000000000" + }, + "1e060dc6c5f1cb8cc7e1452e02ee167508b56542": { + "balance": "12715500000000000000000" + }, + "18136c9df167aa17b6f18e22a702c88f4bc28245": { + "balance": "4000000000000000000000" + }, + "116108c12084612eeda7a93ddcf8d2602e279e5c": { + "balance": "2000000000000000000000" + }, + "bbb643d2187b364afc10a6fd368d7d55f50d1a3c": { + "balance": "1000000000000000000000" + }, + "ec83e798c396b7a55e2a2224abcd834b27ea459c": { + "balance": "12000000000000000000000" + }, + "973f4e361fe5decd989d4c8f7d7cc97990385daf": { + "balance": "388500000000000000000" + }, + "c0f29ed0076611b5e55e130547e68a48e26df5e4": { + "balance": "3000000000000000000000" + }, + "fd4b551f6fdbcda6c511b5bb372250a6b783e534": { + "balance": "20600000000000000000" + }, + "144b19f1f66cbe318347e48d84b14039466c5909": { + "balance": "2000000000000000000000" + }, + "bf183641edb886ce60b8190261e14f42d93cce01": { + "balance": "25019000000000000000" + }, + "94db807873860aac3d5aea1e885e52bff2869954": { + "balance": "3220000000000000000000" + }, + "7a74cee4fa0f6370a7894f116cd00c1147b83e59": { + "balance": "800000000000000000000" + }, + "cd32a4a8a27f1cc63954aa634f7857057334c7a3": { + "balance": "1085000000000000000000" + }, + "7cbeb99932e97e6e02058cfc62d0b26bc7cca52b": { + "balance": "2000000000000000000000" + }, + "8cde8b732e6023878eb23ed16229124b5f7afbec": { + "balance": "133700000000000000000" + }, + "45c4ecb4ee891ea984a7c5cefd8dfb00310b2850": { + "balance": "1980000000000000000000" + }, + "8b393fb0813ee101db1e14ecc7d322c72b8c0473": { + "balance": "455578000000000000000" + }, + "7b66126879844dfa34fe65c9f288117fefb449ad": { + "balance": "6000000000000000000000" + }, + "162ba503276214b509f97586bd842110d103d517": { + "balance": "9002000000000000000000" + }, + "7dece6998ae1900dd3770cf4b93812bad84f0322": { + "balance": "100000000000000000000" + }, + "ec0927bac7dc36669c28354ab1be83d7eec30934": { + "balance": "2000000000000000000000" + }, + "8d7f3e61299c2db9b9c0487cf627519ed00a9123": { + "balance": "1742400000000000000000" + }, + "4fc46c396e674869ad9481638f0013630c87caac": { + "balance": "1000000000000000000000" + }, + "bf68d28aaf1eeefef646b65e8cc8d190f6c6da9c": { + "balance": "2000000000000000000000" + }, + "00969747f7a5b30645fe00e44901435ace24cc37": { + "balance": "1700000000000000000000" + }, + "494dec4d5ee88a2771a815f1ee7264942fb58b28": { + "balance": "2000000000000000000000" + }, + "ffeac0305ede3a915295ec8e61c7f881006f4474": { + "balance": "98500000000000000000" + }, + "b39139576194a0866195151f33f2140ad1cc86cf": { + "balance": "100000000000000000000000" + }, + "fead1803e5e737a68e18472d9ac715f0994cc2be": { + "balance": "500000000000000000000" + }, + "698ab9a2f33381e07c0c47433d0d21d6f336b127": { + "balance": "20000000000000000000" + }, + "e5edc73e626f5d3441a45539b5f7a398c593edf6": { + "balance": "865000000000000000000" + }, + "dd4f5fa2111db68f6bde3589b63029395b69a92d": { + "balance": "158400000000000000000" + }, + "8c93c3c6db9d37717de165c3a1b4fe51952c08de": { + "balance": "400000000000000000000" + }, + "f87bb07b289df7301e54c0efda6a2cf291e89200": { + "balance": "1400000000000000000000" + }, + "e7a4560c84b20e0fb54c49670c2903b0a96c42a4": { + "balance": "598000000000000000000" + }, + "00a5797f52c9d58f189f36b1d45d1bf6041f2f6b": { + "balance": "5456900000000000000000" + }, + "9da3302240af0511c6fd1857e6ddb7394f77ab6b": { + "balance": "3100000000000000000000" + }, + "2c2d15ff39561c1b72eda1cc027ffef23743a144": { + "balance": "3920000000000000000000" + }, + "9b4c2715780ca4e99e60ebf219f1590c8cad500a": { + "balance": "1600000000000000000000" + }, + "ff5e7ee7d5114821e159dca5e81f18f1bfffbff9": { + "balance": "2000000000000000000000" + }, + "0169c1c210eae845e56840412e1f65993ea90fb4": { + "balance": "2000000000000000000000" + }, + "abc45f84db7382dde54c5f7d8938c42f4f3a3bc4": { + "balance": "200000000000000000000" + }, + "d9383d4b6d17b3f9cd426e10fb944015c0d44bfb": { + "balance": "800000000000000000000" + }, + "c090fe23dcd86b358c32e48d2af91024259f6566": { + "balance": "200000000000000000000" + }, + "9ffedcc36b7cc312ad2a9ede431a514fccb49ba3": { + "balance": "669800000000000000000" + }, + "2ffe93ec1a5636e9ee34af70dff52682e6ff7079": { + "balance": "2000000000000000000000" + }, + "6e01e4ad569c95d007ada30d5e2db12888492294": { + "balance": "4000000000000000000000" + }, + "d4d92c62b280e00f626d8657f1b86166cb1f740f": { + "balance": "200028000000000000000" + }, + "1d36683063b7e9eb99462dabd569bddce71686f2": { + "balance": "1000000000000000000000" + }, + "3a48e0a7098b06a905802b87545731118e89f439": { + "balance": "2000000000000000000000" + }, + "bd9e56e902f4be1fc8768d8038bac63e2acbbf8e": { + "balance": "999972000000000000000" + }, + "4d67f2ab8599fef5fc413999aa01fd7fce70b43d": { + "balance": "10000000000000000000000" + }, + "8e74e0d1b77ebc823aca03f119854cb12027f6d7": { + "balance": "107200000000000000000000" + }, + "7e5b19ae1be94ff4dee635492a1b012d14db0213": { + "balance": "100000000000000000000" + }, + "5de9e7d5d1b667d095dd34099c85b0421a0bc681": { + "balance": "20000000000000000000" + }, + "316eb4e47df71b42e16d6fe46825b7327baf3124": { + "balance": "4000000000000000000000" + }, + "772c297f0ad194482ee8c3f036bdeb01c201d5cc": { + "balance": "200000000000000000000" + }, + "d7052519756af42590f15391b723a03fa564a951": { + "balance": "4615591000000000000000" + }, + "2c6846a1aa999a2246a287056000ba4dcba8e63d": { + "balance": "10020000000000000000000" + }, + "de5b005fe8daae8d1f05de3eda042066c6c4691c": { + "balance": "1100000000000000000000" + }, + "254c1ecc630c2877de8095f0a8dba1e8bf1f550c": { + "balance": "1700000000000000000000" + }, + "f8f226142a428434ab17a1864a2597f64aab2f06": { + "balance": "172473000000000000000" + }, + "a6c910ce4d494a919ccdaaa1fc3b82aa74ba06cf": { + "balance": "8000000000000000000000" + }, + "e587b16abc8a74081e3613e14342c03375bf0847": { + "balance": "2000000000000000000000" + }, + "6f176065e88e3c6fe626267d18a088aaa4db80bc": { + "balance": "3520000000000000000000" + }, + "50dcbc27bcad984093a212a9b4178eabe9017561": { + "balance": "145512000000000000000" + }, + "e1953c6e975814c571311c34c0f6a99cdf48ab82": { + "balance": "50000000000000000000" + }, + "be0a2f385f09dbfce96732e12bb40ac349871ba8": { + "balance": "1610348000000000000000" + }, + "4712540265cbeec3847022c59f1b318d43400a9e": { + "balance": "3500000000000000000000" + }, + "29bdc4f28de0180f433c2694eb74f5504ce94337": { + "balance": "2000000000000000000000" + }, + "2f66bfbf2262efcc8d2bd0444fc5b0696298ff1e": { + "balance": "9940000000000000000000" + }, + "506411fd79003480f6f2b6aac26b7ba792f094b2": { + "balance": "500000000000000000000" + }, + "23ea669e3564819a83b0c26c00a16d9e826f6c46": { + "balance": "1430590000000000000000" + }, + "e3ffb02cb7d9ea5243701689afd5d417d7ed2ece": { + "balance": "78000000000000000000" + }, + "38e7dba8fd4f1f850dbc2649d8e84f0952e3eb3c": { + "balance": "50000000000000000000" + }, + "8644cc281be332ccced36da483fb2a0746d9ba2e": { + "balance": "400000000000000000000" + }, + "e8a91da6cf1b9d65c74a02ec1f96eecb6dd241f3": { + "balance": "1940000000000000000000" + }, + "0631dc40d74e5095e3729eddf49544ecd4396f67": { + "balance": "160000000000000000000" + }, + "83c897a84b695eebe46679f7da19d776621c2694": { + "balance": "500000000000000000000" + }, + "db73460b59d8e85045d5e752e62559875e42502e": { + "balance": "999800000000000000000" + }, + "0dd4e674bbadb1b0dc824498713dce3b5156da29": { + "balance": "170000000000000000000" + }, + "e3933d61b77dcdc716407f8250bc91e4ffaeb09d": { + "balance": "86600000000000000000000" + }, + "58c90754d2f20a1cb1dd330625e04b45fa619d5c": { + "balance": "2000000000000000000000" + }, + "895ec5545644e0b78330fffab8ddeac9e833156c": { + "balance": "600000000000000000000" + }, + "7e1e29721d6cb91057f6c4042d8a0bbc644afe73": { + "balance": "159800000000000000000" + }, + "72b90a4dc097239492c5b9777dcd1e52ba2be2c2": { + "balance": "6000000000000000000000" + }, + "64241a7844290e0ab855f1d4aa75b55345032224": { + "balance": "1600000000000000000000" + }, + "6fd4e0f3f32bee6d3767fdbc9d353a6d3aab7899": { + "balance": "695240000000000000000" + }, + "3a035594c747476d42d1ee966c36224cdd224993": { + "balance": "355890000000000000000" + }, + "de97f4330700b48c496d437c91ca1de9c4b01ba4": { + "balance": "2910840000000000000000" + }, + "716ad3c33a9b9a0a18967357969b94ee7d2abc10": { + "balance": "482000000000000000000" + }, + "bfbe05e88c9cbbcc0e92a405fac1d85de248ee24": { + "balance": "100000000000000000000" + }, + "cfc4e6f7f8b011414bfba42f23adfaa78d4ecc5e": { + "balance": "1850000000000000000000" + }, + "d931ac2668ba6a84481ab139735aec14b7bfbabf": { + "balance": "2000000000000000000000" + }, + "e3263ce8af6db3e467584502ed7109125eae22a5": { + "balance": "2000000000000000000000" + }, + "f78258c12481bcdddbb72a8ca0c043097261c6c5": { + "balance": "20000000000000000000" + }, + "4493123c021ece3b33b1a452c9268de14007f9d3": { + "balance": "6685000000000000000000" + }, + "431f2c19e316b044a4b3e61a0c6ff8c104a1a12f": { + "balance": "1000000000000000000000" + }, + "e63e787414b9048478a50733359ecdd7e3647aa6": { + "balance": "1580000000000000000000" + }, + "e4715956f52f15306ee9506bf82bccc406b3895e": { + "balance": "274944000000000000000" + }, + "f7f91e7acb5b8129a306877ce3168e6f438b66a1": { + "balance": "176000000000000000000" + }, + "dcdbbd4e2604e40e1710cc6730289dccfad3892d": { + "balance": "4600000000000000000000" + }, + "2b5f4b3f1e11707a227aa5e69fa49dded33fb321": { + "balance": "6000000000000000000000" + }, + "01488ad3da603c4cdd6cb0b7a1e30d2a30c8fc38": { + "balance": "200000000000000000000" + }, + "841145b44840c946e21dbc190264b8e0d5029369": { + "balance": "300000000000000000000000" + }, + "bf05070c2c34219311c4548b2614a438810ded6d": { + "balance": "2000000000000000000000" + }, + "38f387e1a4ed4a73106ef2b462e474e2e3143ad0": { + "balance": "6000000000000000000000" + }, + "f116b0b4680f53ab72c968ba802e10aa1be11dc8": { + "balance": "20000000000000000000" + }, + "bea0afc93aae2108a3fac059623bf86fa582a75e": { + "balance": "1700000000000000000000" + }, + "4c997992036c5b433ac33d25a8ea1dc3d4e4e6d8": { + "balance": "29200000000000000000" + }, + "ab7e0b83ed9a424c6d1e6a6f87a4dbf06409c7d6": { + "balance": "2400000000000000000000" + }, + "d71fb130f0150c565269e00efb43902b52a455a6": { + "balance": "200000000000000000000" + }, + "99b018932bcad355b6792b255db6702dec8ce5dd": { + "balance": "4000086000000000000000" + }, + "4b904e934bd0cc8b20705f879e905b93ea0ccc30": { + "balance": "2000000000000000000000" + }, + "672ec42faa8cd69aaa71b32cc7b404881d52ff91": { + "balance": "10000000000000000000000" + }, + "acbc2d19e06c3babbb5b6f052b6bf7fc37e07229": { + "balance": "200000000000000000000" + }, + "cea8743341533cb2f0b9c6efb8fda80d77162825": { + "balance": "100000000000000000000" + }, + "9568b7de755628af359a84543de23504e15e41e6": { + "balance": "40000000000000000000000" + }, + "6ec96d13bdb24dc7a557293f029e02dd74b97a55": { + "balance": "4000000000000000000000" + }, + "d95c90ffbe5484864780b867494a83c89256d6e4": { + "balance": "1640000000000000000000" + }, + "ade6f8163bf7c7bb4abe8e9893bd0cc112fe8872": { + "balance": "327600000000000000000" + }, + "250eb7c66f869ddf49da85f3393e980c029aa434": { + "balance": "4000000000000000000000" + }, + "a35c19132cac1935576abfed6c0495fb07881ba0": { + "balance": "2000000000000000000000" + }, + "d5550caaf743b037c56fd2558a1c8ed235130750": { + "balance": "5347598000000000000000" + }, + "03097923ba155e16d82f3ad3f6b815540884b92c": { + "balance": "1820000000000000000000" + }, + "d6d9e30f0842012a7176a917d9d2048ca0738759": { + "balance": "4000000000000000000000" + }, + "ab9ad36e5c74ce2e96399f57839431d0e79f96ab": { + "balance": "164000000000000000000" + }, + "75be8ff65e5788aec6b2a52d5fa7b1e7a03ba675": { + "balance": "67720000000000000000" + }, + "4f6d4737d7a940382487264886697cf7637f8015": { + "balance": "1670000000000000000000" + }, + "5f7b3bbac16dab831a4a0fc53b0c549dc36c31ca": { + "balance": "1940000000000000000000" + }, + "d843ee0863ce933e22f89c802d31287b9671e81c": { + "balance": "13370000000000000000" + }, + "361f3ba9ed956b770f257d3672fe1ff9f7b0240c": { + "balance": "600000000000000000000" + }, + "6c0ae9f043c834d44271f13406593dfe094f389f": { + "balance": "1517545000000000000000" + }, + "db34745ede8576b499db01beb7c1ecda85cf4abe": { + "balance": "80000000000000000000" + }, + "7be8ccb4f11b66ca6e1d57c0b5396221a31ba53a": { + "balance": "20000000000000000000" + }, + "128b908fe743a434203de294c441c7e20a86ea67": { + "balance": "713304000000000000000" + }, + "df236bf6abf4f3293795bf0c28718f93e3b1b36b": { + "balance": "1337000000000000000000" + }, + "14254ea126b52d0142da0a7e188ce255d8c47178": { + "balance": "775000000000000000000" + }, + "ceed47ca5b899fd1623f21e9bd4db65a10e5b09d": { + "balance": "133196000000000000000" + }, + "30acd858875fa24eef0d572fc7d62aad0ebddc35": { + "balance": "400000000000000000000" + }, + "47a281dff64167197855bf6e705eb9f2cef632ea": { + "balance": "1000072000000000000000" + }, + "297d5dbe222f2fb52531acbd0b013dc446ac7368": { + "balance": "20000000000000000000000" + }, + "adf85203c8376a5fde9815384a350c3879c4cb93": { + "balance": "1147300000000000000000" + }, + "c3e0471c64ff35fa5232cc3121d1d38d1a0fb7de": { + "balance": "2000000000000000000000" + }, + "fdecc82ddfc56192e26f563c3d68cb544a96bfed": { + "balance": "440000000000000000000" + }, + "2614f42d5da844377578e6b448dc24305bef2b03": { + "balance": "2000000000000000000000" + }, + "1d96bcd58457bbf1d3c2a46ffaf16dbf7d836859": { + "balance": "171313000000000000000" + }, + "bd66ffedb530ea0b2e856dd12ac2296c31fe29e0": { + "balance": "200000000000000000000" + }, + "6e84876dbb95c40b6656e42ba9aea08a993b54dc": { + "balance": "1101932000000000000000" + }, + "a1c4f45a82e1c478d845082eb18875c4ea6539ab": { + "balance": "200000000000000000000000" + }, + "2c964849b1f69cc7cea4442538ed87fdf16cfc8f": { + "balance": "2000000000000000000000" + }, + "45b47105fe42c4712dce6e2a21c05bffd5ea47a9": { + "balance": "2000000000000000000000" + }, + "31e9c00f0c206a4e4e7e0522170dc81e88f3eb70": { + "balance": "2685000000000000000000" + }, + "5fe77703808f823e6c399352108bdb2c527cb87c": { + "balance": "1960000000000000000000" + }, + "2272186ef27dcbe2f5fc373050fdae7f2ace2316": { + "balance": "16100000000000000000000" + }, + "b7576e9d314df41ec5506494293afb1bd5d3f65d": { + "balance": "20000000000000000000" + }, + "ac9fff68c61b011efbecf038ed72db97bb9e7281": { + "balance": "9550000000000000000000" + }, + "cd9529492b5c29e475acb941402b3d3ba50686b0": { + "balance": "1970000000000000000000" + }, + "f19b39389d47b11b8a2c3f1da9124decffbefaf7": { + "balance": "2000000000000000000000" + }, + "9e951f6dc5e352afb8d04299d2478a451259bf56": { + "balance": "72004000000000000000" + }, + "8eb1fbe4e5d3019cd7d30dae9c0d5b4c76fb6331": { + "balance": "2000000000000000000000" + }, + "29cc804d922be91f5909f348b0aaa5d21b607830": { + "balance": "4000000000000000000000" + }, + "5c7b9ec7a2438d1e3c7698b545b9c3fd77b7cd55": { + "balance": "1000000000000000000000" + }, + "a16160851d2b9c349b92e46f829abfb210943595": { + "balance": "1790000000000000000000" + }, + "eac6b98842542ea10bb74f26d7c7488f698b6452": { + "balance": "20000000000000000000000" + }, + "57825aeb09076caa477887fbc9ae37e8b27cc962": { + "balance": "100000000000000000000" + }, + "b35e8a1c0dac7e0e66dbac736a592abd44012561": { + "balance": "14974000000000000000" + }, + "756b84eb85fcc1f4fcdcc2b08db6a86e135fbc25": { + "balance": "3220000000000000000000" + }, + "e13b3d2bbfdcbc8772a23315724c1425167c5688": { + "balance": "1032115000000000000000" + }, + "0a2dcb7a671701dbb8f495728088265873356c8e": { + "balance": "152120000000000000000" + }, + "03cb4c4f4516c4ff79a1b6244fbf572e1c7fea79": { + "balance": "2740000000000000000000" + }, + "98ba4e9ca72fddc20c69b4396f76f8183f7a2a4e": { + "balance": "12800000000000000000000" + }, + "f8087786b42da04ed6d1e0fe26f6c0eefe1e9f5a": { + "balance": "10000000000000000000000" + }, + "02f7f67209b16a17550c694c72583819c80b54ad": { + "balance": "98400000000000000000" + }, + "32bb2e9693e4e085344d2f0dbd46a283e3a087fd": { + "balance": "400000000000000000000" + }, + "9c78963fbc263c09bd72e4f8def74a9475f7055c": { + "balance": "13790000000000000000000" + }, + "27144ca9a7771a836ad50f803f64d869b2ae2b20": { + "balance": "4000000000000000000000" + }, + "cc758d071d25a6320af68c5dc9c4f6955ba94520": { + "balance": "6000000000000000000000" + }, + "cb42b44eb5fd60b5837e4f9eb47267523d1a229c": { + "balance": "865000000000000000000" + }, + "aaf5b207b88b0de4ac40d747cee06e172df6e745": { + "balance": "31428000000000000000000" + }, + "52d380511df19d5ec2807bbcb676581b67fd37a3": { + "balance": "13400000000000000000" + }, + "aa1b3768c16d821f580e76c8e4c8e86d7dc78853": { + "balance": "400000000000000000000" + }, + "41098a81452317c19e3eef0bd123bbe178e9e9ca": { + "balance": "2800000000000000000000" + }, + "267148fd72c54f620a592fb92799319cc4532b5c": { + "balance": "410000000000000000000" + }, + "d7cdbd41fff20df727c70b6255c1ba7606055468": { + "balance": "200000000000000000000" + }, + "0e33fcbbc003510be35785b52a9c5d216bc005f4": { + "balance": "1880000000000000000000" + }, + "6727daf5b9d68efcab489fedec96d7f7325dd423": { + "balance": "2000000000000000000000" + }, + "cd0a161bc367ae0927a92aac9cf6e5086714efca": { + "balance": "2000000000000000000000" + }, + "612667f172135b950b2cd1de10afdece6857b873": { + "balance": "1000000000000000000000" + }, + "900194c4b1074305d19de405b0ac78280ecaf967": { + "balance": "1000000000000000000000" + }, + "51f55ef47e6456a418ab32b9221ed27dba6608ee": { + "balance": "4200000000000000000000" + }, + "0da532c910e3ac0dfb14db61cd739a93353fd05f": { + "balance": "1336866000000000000000" + }, + "21df2dcdaf74b2bf803404dd4de6a35eabec1bbd": { + "balance": "6920000000000000000000" + }, + "f0e7fb9e420a5340d536f40408344feaefc06aef": { + "balance": "1000000000000000000000" + }, + "6742a2cfce8d79a2c4a51b77747498912245cd6a": { + "balance": "258064000000000000000" + }, + "8663a241a0a89e70e182c845e2105c8ad7264bcf": { + "balance": "14825507000000000000000" + }, + "18e113d8177c691a61be785852fa5bb47aeebdaf": { + "balance": "1337000000000000000000" + }, + "1bec4d02ce85fc48feb62489841d85b170586a9b": { + "balance": "2400000000000000000000" + }, + "287cf9d0902ef819a7a5f149445bf1775ee8c47c": { + "balance": "16000000000000000000000" + }, + "28967280214e218a120c5dda37041b111ea36d74": { + "balance": "200000000000000000000" + }, + "a0b771951ce1deee363ae2b771b73e07c4b5e800": { + "balance": "1400000000000000000000" + }, + "29f8fba4c30772b057edbbe62ae7420c390572e1": { + "balance": "1000000000000000000000" + }, + "ee34c7e7995db9f187cff156918cfb6f13f6e003": { + "balance": "1960000000000000000000" + }, + "916bf7e3c545921d3206d900c24f14127cbd5e70": { + "balance": "18020000000000000000000" + }, + "93235f340d2863e18d2f4c52996516138d220267": { + "balance": "73800000000000000000" + }, + "7efec0c6253caf397f71287c1c07f6c9582b5b86": { + "balance": "482839000000000000000" + }, + "8d2e31b08803b2c5f13d398ecad88528209f6057": { + "balance": "9993000000000000000000" + }, + "964eab4b276b4cd8983e15ca72b106900fe41fce": { + "balance": "500000000000000000000" + }, + "eea1e97988de75d821cd28ad6822b22cce988b31": { + "balance": "520000000000000000000" + }, + "278c0bde630ec393b1e7267fc9d7d97019e4145b": { + "balance": "2000000000000000000000" + }, + "82e4461eb9d849f0041c1404219e4272c4900ab4": { + "balance": "2000000000000000000000" + }, + "4a73389298031b8816cca946421c199e18b343d6": { + "balance": "631254000000000000000" + }, + "9a5af31c7e06339ac8b4628d7c4db0ce0f45c8a4": { + "balance": "500000000000000000000" + }, + "cb9b5103e4ce89af4f64916150bff9eecb9faa5c": { + "balance": "500000000000000000000" + }, + "740f641614779dcfa88ed1d425d60db42a060ca6": { + "balance": "998630000000000000000" + }, + "a4e623451e7e94e7e89ba5ed95c8a83a62ffc4ea": { + "balance": "20000000000000000000" + }, + "25a500eeec7a662a841552b5168b707b0de21e9e": { + "balance": "10020000000000000000000" + }, + "185a7fc4ace368d233e620b2a45935661292bdf2": { + "balance": "20000000000000000000000" + }, + "9b68f67416a63bf4451a31164c92f672a68759e9": { + "balance": "60000000000000000000000" + }, + "a38b5bd81a9db9d2b21d5ec7c60552cd02ed561b": { + "balance": "6000000000000000000000" + }, + "61c830f1654718f075ccaba316faacb85b7d120b": { + "balance": "400000000000000000000" + }, + "8392e53776713578015bff4940cf43849d7dcba1": { + "balance": "153190000000000000000" + }, + "dc57477dafa42f705c7fe40eae9c81756e0225f1": { + "balance": "500044000000000000000" + }, + "febc3173bc9072136354002b7b4fb3bfc53f22f1": { + "balance": "370000000000000000000" + }, + "d78f84e38944a0e0255faece48ba4950d4bd39d2": { + "balance": "5000000000000000000000" + }, + "a7a3bb6139b0ada00c1f7f1f9f56d994ba4d1fa8": { + "balance": "2000000000000000000000" + }, + "aa3f29601a1331745e05c42830a15e71938a6237": { + "balance": "1700000000000000000000" + }, + "bec6640f4909b58cbf1e806342961d607595096c": { + "balance": "1999944000000000000000" + }, + "9be3c329b62a28b8b0886cbd8b99f8bc930ce3e6": { + "balance": "74500000000000000000" + }, + "e3eb2c0a132a524f72ccc0d60fee8b41685d39e2": { + "balance": "1970000000000000000000" + }, + "90b1f370f9c1eb0be0fb8e2b8ad96a416371dd8a": { + "balance": "900000000000000000000" + }, + "f2742e6859c569d5f2108351e0bf4dca352a48a8": { + "balance": "10000000000000000000000" + }, + "b134c004391ab4992878337a51ec242f42285742": { + "balance": "2000000000000000000000" + }, + "ab7416ff32254951cbbc624ec7fb45fc7ecaa872": { + "balance": "340000000000000000000" + }, + "9795f64319fc17dd0f8261f9d206fb66b64cd0c9": { + "balance": "200000000000000000000" + }, + "64e03ef070a54703b7184e48276c5c0077ef4b34": { + "balance": "320000000000000000000" + }, + "3430a16381f869f6ea5423915855e800883525a9": { + "balance": "17900000000000000000000" + }, + "f4a367b166d2991a2bfda9f56463a09f252c1b1d": { + "balance": "1970000000000000000000" + }, + "77c4a697e603d42b12056cbba761e7f51d0443f5": { + "balance": "680000000000000000000" + }, + "153ef58a1e2e7a3eb6b459a80ab2a547c94182a2": { + "balance": "96000000000000000000000" + }, + "6dbe8abfa1742806263981371bf3d35590806b6e": { + "balance": "20000000000000000000000" + }, + "4c99dae96481e807c1f99f8b7fbde29b7547c5bf": { + "balance": "150000000000000000000" + }, + "d5b9d277d8aad20697a51f76e20978996bffe055": { + "balance": "143250000000000000000" + }, + "0f24105abbdaa03fa6309ef6c188e51f714a6e59": { + "balance": "200000000000000000000" + }, + "1cb6b2d7cfc559b7f41e6f56ab95c7c958cd0e4c": { + "balance": "1337000000000000000000" + }, + "f37b426547a1642d8033324814f0ede3114fc212": { + "balance": "401100000000000000000" + }, + "318f1f8bd220b0558b95fb33100ffdbb640d7ca6": { + "balance": "4000000000000000000000" + }, + "206d55d5792a514ec108e090599f2a065e501185": { + "balance": "200550000000000000000" + }, + "11d2247a221e70c2d66d17ee138d38c55ffb8640": { + "balance": "10000000000000000000000" + }, + "e8de725eca5def805ff7941d31ac1c2e342dfe95": { + "balance": "2462500000000000000000" + }, + "d561cbbc05515de73ab8cf9eae1357341e7dfdf4": { + "balance": "6000000000000000000000" + }, + "0455dcec8a7fc4461bfd7f37456fce3f4c3caac7": { + "balance": "400000000000000000000" + }, + "5161fd49e847f67455f1c8bb7abb36e985260d03": { + "balance": "1200000000000000000000" + }, + "8e073bad25e42218615f4a0e6b2ea8f8de2230c0": { + "balance": "2402500000000000000000" + }, + "6c08a6dc0173c7342955d1d3f2c065d62f83aec7": { + "balance": "20000000000000000000" + }, + "95cb6d8a6379f94aba8b885669562c4d448e56a7": { + "balance": "2000000000000000000000" + }, + "2805415e1d7fdec6dedfb89e521d10592d743c10": { + "balance": "100000000000000000000" + }, + "daacdaf42226d15cb1cf98fa15048c7f4ceefe69": { + "balance": "300000000000000000000" + }, + "e33df4ce80ccb62a76b12bcdfcecc46289973aa9": { + "balance": "6000000000000000000000" + }, + "8f8cd26e82e7c6defd02dfad07979021cbf7150c": { + "balance": "3000000000000000000000" + }, + "77a17122fa31b98f1711d32a99f03ec326f33d08": { + "balance": "1700000000000000000000" + }, + "6f791d359bc3536a315d6382b88311af8ed6da47": { + "balance": "92000000000000000000" + }, + "de30e49e5ab313214d2f01dcabce8940b81b1c76": { + "balance": "197000000000000000000" + }, + "cf9be9b9ab86c66b59968e67b8d4dcff46b1814a": { + "balance": "660000000000000000000" + }, + "7fdfc88d78bf1b285ac64f1adb35dc11fcb03951": { + "balance": "2287900000000000000000" + }, + "c5134cfbb1df7a20b0ed7057622eeed280947dad": { + "balance": "3800000000000000000000" + }, + "fa9ec8efe08686fa58c181335872ba698560ecab": { + "balance": "1999944000000000000000" + }, + "f6a8635757c5e8c134d20d028cf778cf8609e46a": { + "balance": "1459416000000000000000" + }, + "6265b2e7730f36b776b52d0c9d02ada55d8e3cb6": { + "balance": "1000000000000000000000" + }, + "6a8cea2de84a8df997fd3f84e3083d93de57cda9": { + "balance": "100007000000000000000" + }, + "1b7ed974b6e234ce81247498429a5bd4a0a2d139": { + "balance": "2000000000000000000000" + }, + "9ba53dc8c95e9a472feba2c4e32c1dc4dd7bab46": { + "balance": "1337000000000000000000" + }, + "d7b740dff8c457668fdf74f6a266bfc1dcb723f9": { + "balance": "20000000000000000000" + }, + "07bc2cc8eedc01970700efc9c4fb36735e98cd71": { + "balance": "4000000000000000000000" + }, + "3e1c962063e0d5295941f210dca3ab531eec8809": { + "balance": "3000000000000000000000" + }, + "b447571dacbb3ecbb6d1cf0b0c8f3838e52324e2": { + "balance": "30199000000000000000" + }, + "87764e3677eef604cbc59aed24abdc566b09fc25": { + "balance": "3000000000000000000000" + }, + "03aa622881236dd0f4940c24c324ff8b7b7e2186": { + "balance": "3200000000000000000000" + }, + "a4a7d306f510cd58359428c0d2f7c3609d5674d7": { + "balance": "3349000000000000000000" + }, + "3c83c1701db0388b68210d00f5717cd9bd322c6a": { + "balance": "30000000000000000000000" + }, + "047d5a26d7ad8f8e70600f70a398ddaa1c2db26f": { + "balance": "6000000000000000000000" + }, + "43767bf7fd2af95b72e9312da9443cb1688e4343": { + "balance": "300000000000000000000" + }, + "34a85d6d243fb1dfb7d1d2d44f536e947a4cee9e": { + "balance": "20000000000000000000000" + }, + "65a9dad42e1632ba3e4e49623fab62a17e4d3611": { + "balance": "93120000000000000000" + }, + "48e0cbd67f18acdb7a6291e1254db32e0972737f": { + "balance": "100007000000000000000" + }, + "a5de5e434fdcdd688f1c31b6fb512cb196724701": { + "balance": "800000000000000000000" + }, + "6d63d38ee8b90e0e6ed8f192eda051b2d6a58bfd": { + "balance": "30000000000000000000" + }, + "b079bb4d9866143a6da72ae7ac0022062981315c": { + "balance": "760000000000000000000" + }, + "c0413f5a7c2d9a4b8108289ef6ecd271781524f4": { + "balance": "50000000000000000000000" + }, + "a91a5a7b341f99c535144e20be9c6b3bb4c28e4d": { + "balance": "5431790000000000000000" + }, + "993f146178605e66d517be782ef0b3c61a4e1925": { + "balance": "7011998000000000000000" + }, + "966c04781cb5e67dde3235d7f8620e1ab663a9a5": { + "balance": "75800000000000000000000" + }, + "b3f82a87e59a39d0d2808f0751eb72c2329cdcc5": { + "balance": "5000000000000000000000" + }, + "9b77ebced7e215f0920e8c2b870024f6ecb2ff31": { + "balance": "1000000000000000000000" + }, + "fe697ff22ca547bfc95e33d960da605c6763f35b": { + "balance": "1325000000000000000000" + }, + "480af52076009ca73781b70e43b95916a62203ab": { + "balance": "924171000000000000000" + }, + "a9dc0424c6969d798358b393b1933a1f51bee00a": { + "balance": "20000000000000000000000" + }, + "7aba56f63a48bc0817d6b97039039a7ad62fae2e": { + "balance": "600000000000000000000" + }, + "59d139e2e40c7b97239d23dfaca33858f602d22b": { + "balance": "2000000000000000000000" + }, + "8d6170ff66978e773bb621bf72b1ba7be3a7f87e": { + "balance": "200000000000000000000" + }, + "d668523a90f0293d65c538d2dd6c57673710196e": { + "balance": "39500000000000000000" + }, + "bbb5a0f4802c8648009e8a6998af352cde87544f": { + "balance": "95500000000000000000" + }, + "fc43829ac787ff88aaf183ba352aadbf5a15b193": { + "balance": "3960000000000000000000" + }, + "fe22a0b388668d1ae2643e771dacf38a434223cc": { + "balance": "4000304000000000000000" + }, + "092acb624b08c05510189bbbe21e6524d644ccad": { + "balance": "18200000000000000000" + }, + "8f0538ed71da1155e0f3bde5667ceb84318a1a87": { + "balance": "1940000000000000000000" + }, + "06994cd83aa2640a97b2600b41339d1e0d3ede6c": { + "balance": "250000000000000000000" + }, + "9d460c1b379ddb19a8c85b4c6747050ddf17a875": { + "balance": "3340000000000000000000" + }, + "77a769fafdecf4a638762d5ba3969df63120a41d": { + "balance": "2000000000000000000000" + }, + "5f375b86600c40cca8b2676b7a1a1d1644c5f52c": { + "balance": "78838000000000000000" + }, + "15ee0fc63ebf1b1fc49d7bb38f8863823a2e17d2": { + "balance": "1910000000000000000000" + }, + "6651736fb59b91fee9c93aa0bd6ea2f7b2506180": { + "balance": "500000000000000000000" + }, + "361d9ed80b5bd27cf9f1226f26753258ee5f9b3f": { + "balance": "3530900000000000000000" + }, + "c9b6b686111691ee6aa197c7231a88dc60bd295d": { + "balance": "500000000000000000000" + }, + "e9b4a4853577a9dbcc2e795be0310d1bed28641a": { + "balance": "1000000000000000000000" + }, + "36758e049cd98bcea12277a676f9297362890023": { + "balance": "4000000000000000000000" + }, + "6bb50813146a9add42ee22038c9f1f7469d47f47": { + "balance": "200200000000000000000" + }, + "6de4b581385cf7fc9fe8c77d131fe2ee7724c76a": { + "balance": "2308840000000000000000" + }, + "d2a5a024230a57ccc666760b89b0e26cafd189c7": { + "balance": "49997115000000000000000" + }, + "65af9087e05167715497c9a5a749189489004def": { + "balance": "835000000000000000000" + }, + "ead21c1deccfbf1c5cd96688a2476b69ba07ce4a": { + "balance": "72800000000000000000" + }, + "e308435204793764f5fcbe65eb510f5a744a655a": { + "balance": "200000000000000000000" + }, + "9376dce2af2ec8dcda741b7e7345664681d93668": { + "balance": "1000000000000000000000" + }, + "a1b47c4d0ed6018842e6cfc8630ac3a3142e5e6b": { + "balance": "20000000000000000000" + }, + "e2198c8ca1b399f7521561fd5384a7132fba486b": { + "balance": "1015200000000000000000" + }, + "92c13fe0d6ce87fd50e03def9fa6400509bd7073": { + "balance": "40000000000000000000" + }, + "7517f16c28d132bb40e3ba36c6aef131c462da17": { + "balance": "18200000000000000000" + }, + "6a023af57d584d845e698736f130db9db40dfa9a": { + "balance": "98800000000000000000" + }, + "1518627b88351fede796d3f3083364fbd4887b0c": { + "balance": "16000000000000000000000" + }, + "f5b6e9061a4eb096160777e26762cf48bdd8b55d": { + "balance": "254030000000000000000" + }, + "28073efc17d05cab3195c2db332b61984777a612": { + "balance": "1000000000000000000000" + }, + "f06a854a3c5dc36d1c49f4c87d6db333b57e4add": { + "balance": "10000000000000000000000" + }, + "9225983860a1cb4623c72480ac16272b0c95e5f5": { + "balance": "2000000000000000000000" + }, + "5260dc51ee07bddaababb9ee744b393c7f4793a6": { + "balance": "34040000000000000000" + }, + "0f127bbf8e311caea2ba502a33feced3f730ba42": { + "balance": "188000000000000000000" + }, + "17d521a8d9779023f7164d233c3b6420ffd223ed": { + "balance": "20000000000000000000" + }, + "8c2b7d8b608d28b77f5caa9cd645242a823e4cd9": { + "balance": "1820000000000000000000" + }, + "6e866d032d405abdd65cf651411d803796c22311": { + "balance": "2000000000000000000000" + }, + "dc51b2dc9d247a1d0e5bc36ca3156f7af21ff9f6": { + "balance": "1000000000000000000000" + }, + "c84d9bea0a7b9f140220fd8b9097cfbfd5edf564": { + "balance": "123047000000000000000" + }, + "ff86e5e8e15b53909600e41308dab75f0e24e46b": { + "balance": "902400000000000000000" + }, + "d7164aa261c09ad9b2b5068d453ed8eb6aa13083": { + "balance": "3000000000000000000000" + }, + "76aaf8c1ac012f8752d4c09bb46607b6651d5ca8": { + "balance": "20000000000000000000" + }, + "41786a10d447f484d33244ccb7facd8b427b5b8c": { + "balance": "1000000000000000000000" + }, + "2e0c57b47150f95aa6a7e16ab9b1cbf54328979a": { + "balance": "100000000000000000000" + }, + "3f747237806fed3f828a6852eb0867f79027af89": { + "balance": "1500000000000000000000" + }, + "a568db4d57e4d67462d733c69a9e0fe26e218327": { + "balance": "1096140000000000000000" + }, + "1f88f8a1338fc7c10976abcd3fb8d38554b5ec9c": { + "balance": "13400000000000000000" + }, + "d1ea4d72a67b5b3e0f315559f52bd0614d713069": { + "balance": "2000000000000000000000" + }, + "bfaeb91067617dcf8b44172b02af615674835dba": { + "balance": "160661000000000000000" + }, + "b71a13ba8e95167b80331b52d69e37054fe7a826": { + "balance": "200000000000000000000" + }, + "b67a80f170197d96cdcc4ab6cba627b4afa6e12c": { + "balance": "2400000000000000000000" + }, + "35af040a0cc2337a76af288154c7561e1a233349": { + "balance": "1000000000000000000000" + }, + "c86190904b8d079ec010e462cbffc90834ffaa5c": { + "balance": "10100000000000000000000" + }, + "383304dd7a5720b29c1a10f60342219f48032f80": { + "balance": "5600000000000000000000" + }, + "191313525238a21c767457a91374f02200c55448": { + "balance": "116400000000000000000" + }, + "cc4a2f2cf86cf3e43375f360a4734691195f1490": { + "balance": "1348127000000000000000" + }, + "4e020779b5ddd3df228a00cb48c2fc979da6ae38": { + "balance": "2000000000000000000000" + }, + "e206fb7324e9deb79e19903496d6961b9be56603": { + "balance": "100000000000000000000" + }, + "3ae160e3cd60ae31b9d6742d68e14e76bd96c517": { + "balance": "30000000000000000000" + }, + "1f7d8e86d6eeb02545aad90e91327bd369d7d2f3": { + "balance": "20000000000000000000" + }, + "68c7d1711b011a33f16f1f55b5c902cce970bdd7": { + "balance": "152000000000000000000" + }, + "637be71b3aa815ff453d5642f73074450b64c82a": { + "balance": "2000000000000000000000" + }, + "1584a2c066b7a455dbd6ae2807a7334e83c35fa5": { + "balance": "130000000000000000000" + }, + "9c05e9d0f0758e795303717e31da213ca157e686": { + "balance": "1000000000000000000000" + }, + "4f1a2da54a4c6da19d142412e56e815741db2325": { + "balance": "100000000000000000000" + }, + "9a4ca8b82117894e43db72b9fa78f0b9b93ace09": { + "balance": "50000000000000000000" + }, + "26c99f8849c9802b83c861217fd07a9e84cdb79d": { + "balance": "300000000000000000000" + }, + "45c0d19f0b8e054f9e893836d5ecae7901af2812": { + "balance": "5000000000000000000000" + }, + "00dc01cbf44978a42e8de8e436edf94205cfb6ec": { + "balance": "1458440000000000000000" + }, + "de7dee220f0457a7187d56c1c41f2eb00ac56021": { + "balance": "629924000000000000000" + }, + "1c128bd6cda5fca27575e4b43b3253c8c4172afe": { + "balance": "2000000000000000000000" + }, + "666746fb93d1935c5a3c684e725010c4fad0b1d8": { + "balance": "20000000000000000000" + }, + "51d78b178d707e396e8710965c4f41b1a1d9179d": { + "balance": "110600000000000000000" + }, + "68f7573cd457e14c03fea43e302d30347c10705c": { + "balance": "5000000000000000000000" + }, + "9d30cb237bc096f17036fc80dd21ca68992ca2d9": { + "balance": "30380000000000000000000" + }, + "fbcfcc4a7b0f26cf26e9f3332132e2fc6a230766": { + "balance": "8000000000000000000000" + }, + "b166e37d2e501ae73c84142b5ffb5aa655dd5a99": { + "balance": "1999000000000000000000" + }, + "6df24f6685a62f791ba337bf3ff67e91f3d4bc3a": { + "balance": "2166000000000000000000" + }, + "92e435340e9d253c00256389f52b067d55974e76": { + "balance": "268000000000000000000" + }, + "ea53d26564859d9e90bb0e53b7abf560e0162c38": { + "balance": "400000000000000000000" + }, + "e26657f0ed201ea2392c9222b80a7003608ddf30": { + "balance": "40000000000000000000" + }, + "f4177a0d85d48b0e264211ce2aa2efd3f1b47f08": { + "balance": "3593425000000000000000" + }, + "9d47ba5b4c8505ad8da42934280b61a0e1e8b971": { + "balance": "100000000000000000000" + }, + "63c2a3d235e5eeabd0d4a6afdb89d94627396495": { + "balance": "1241620000000000000000" + }, + "446a8039cecf9dce4879cbcaf3493bf545a88610": { + "balance": "7000000000000000000000" + }, + "7fa37ed67887751a471f0eb306be44e0dbcd6089": { + "balance": "1060000000000000000000" + }, + "26d4a16891f52922789217fcd886f7fce296d400": { + "balance": "2000000000000000000000" + }, + "487e108502b0b189ef9c8c6da4d0db6261eec6c0": { + "balance": "1910000000000000000000" + }, + "7484d26becc1eea8c6315ec3ee0a450117dc86a0": { + "balance": "12000000000000000000000" + }, + "ad9e97a0482f353a05c0f792b977b6c7e811fa5f": { + "balance": "200000000000000000000" + }, + "2273bad7bc4e487622d175ef7a66988b6a93c4ee": { + "balance": "20000000000000000000" + }, + "3b93b16136f11eaf10996c95990d3b2739ccea5f": { + "balance": "10000000000000000000000" + }, + "f3f1fa3918ca34e2cf7e84670b1f4d8eca160db3": { + "balance": "680000000000000000000" + }, + "88a2154430c0e41147d3c1fee3b3b006f851edbd": { + "balance": "999972000000000000000" + }, + "25185f325acf2d64500698f65c769ddf68301602": { + "balance": "5000000000000000000000" + }, + "e9cafe41a5e8bbd90ba02d9e06585b4eb546c57f": { + "balance": "2000000000000000000000" + }, + "95681cdae69b2049ce101e325c759892cac3f811": { + "balance": "2857600000000000000000" + }, + "475066f9ad26655196d5535327bbeb9b7929cb04": { + "balance": "3040000000000000000000" + }, + "6685fd2e2544702c360b8bb9ee78f130dad16da5": { + "balance": "2000000000000000000000" + }, + "45e68db94c7d0ab7ac41857a71d67147870f4e71": { + "balance": "400000000000000000000000" + }, + "4ad95d188d6464709add2555fb4d97fe1ebf311f": { + "balance": "346000000000000000000" + }, + "73bedd6fda7ba3272185087b6351fc133d484e37": { + "balance": "5057200000000000000000" + }, + "1ea4715504c6af107b0194f4f7b1cb6fcccd6f4b": { + "balance": "590598000000000000000" + }, + "77306ffe2e4a8f3ca826c1a249f7212da43aeffd": { + "balance": "20000000000000000000000" + }, + "eb453f5a3adddd8ab56750fadb0fe7f94d9c89e7": { + "balance": "20000000000000000000" + }, + "7201d1c06920cd397ae8ad869bcda6e47ffb1b5a": { + "balance": "20000000000000000000" + }, + "821cb5cd05c7ef909fe1be60733d8963d760dc41": { + "balance": "4000000000000000000000" + }, + "496e319592b341eaccd778dda7c8196d54cac775": { + "balance": "9250000000000000000000" + }, + "88609e0a465b6e99fce907166d57e9da0814f5c8": { + "balance": "20000000000000000000000" + }, + "c7ec62b804b1f69b1e3070b5d362c62fb309b070": { + "balance": "13068074000000000000000" + }, + "3eb9ef06d0c259040319947e8c7a6812aa0253d8": { + "balance": "167000000000000000000" + }, + "cbf37ff854a2f1ce53934494777892d3ec655782": { + "balance": "10000000000000000000000" + }, + "02b1af72339b2a2256389fd64607de24f0de600a": { + "balance": "2000000000000000000000" + }, + "a8beb91c2b99c8964aa95b6b4a184b1269fc3483": { + "balance": "400000000000000000000" + }, + "922a20c79a1d3a26dd3829677bf1d45c8f672bb6": { + "balance": "4000000000000000000000" + }, + "c5843399d150066bf7979c34ba294620368ad7c0": { + "balance": "200000000000000000000" + }, + "8cd0cd22e620eda79c0461e896c93c44837e2968": { + "balance": "2000000000000000000000" + }, + "6170dd0687bd55ca88b87adef51cfdc55c4dd458": { + "balance": "2005160000000000000000" + }, + "eed384ef2d41d9d203974e57c12328ea760e08ea": { + "balance": "1000000000000000000000" + }, + "b129a5cb7105fe810bd895dc7206a991a4545488": { + "balance": "30000000000000000000" + }, + "3872f48dc5e3f817bc6b2ad2d030fc5e0471193d": { + "balance": "4000000000000000000000" + }, + "514b7512c9ae5ea63cbf11715b63f21e18d296c1": { + "balance": "1999944000000000000000" + }, + "7ab256b204800af20137fabcc916a23258752501": { + "balance": "20000000000000000000000" + }, + "fc66faba277f4b5de64ad45eb19c31e00ced3ed5": { + "balance": "5640000000000000000000" + }, + "39824f8bced176fd3ea22ec6a493d0ccc33fc147": { + "balance": "4000000000000000000000" + }, + "e338e859fe2e8c15554848b75caecda877a0e832": { + "balance": "1801800000000000000000" + }, + "e53c68796212033e4e6f9cff56e19c461eb454f9": { + "balance": "1000000000000000000000" + }, + "8461ecc4a6a45eb1a5b947fb86b88069b91fcd6f": { + "balance": "2000000000000000000000" + }, + "6b4b99cb3fa9f7b74ce3a48317b1cd13090a1a7a": { + "balance": "57300000000000000000" + }, + "97de21e421c37fe4b8025f9a51b7b390b5df7804": { + "balance": "80000000000000000000000" + }, + "d25aecd7eb8bd6345b063b5dbd271c77d3514494": { + "balance": "1820000000000000000000" + }, + "57b23d6a1adc06c652a779c6a7fb6b95b9fead66": { + "balance": "200000000000000000000" + }, + "0d658014a199061cf6b39433140303c20ffd4e5a": { + "balance": "8200000000000000000000" + }, + "30eac740e4f02cb56eef0526e5d300322600d03e": { + "balance": "1970000000000000000000" + }, + "4eead40aad8c73ef08fc84bc0a92c9092f6a36bf": { + "balance": "26740000000000000000" + }, + "30f7d025d16f7bee105580486f9f561c7bae3fef": { + "balance": "500000000000000000000" + }, + "0977bfba038a44fb49b03970d8d8cf2cb61f8b25": { + "balance": "420000000000000000000" + }, + "b14bbeff70720975dc6191b2a44ff49f2672873c": { + "balance": "143000000000000000000" + }, + "d588c3a5df228185d98ee7e60748255cdea68b01": { + "balance": "4000000000000000000000" + }, + "225d35faedb391c7bc2db7fa9071160405996d00": { + "balance": "167774000000000000000" + }, + "c0e457bd56ec36a1246bfa3230fff38e5926ef22": { + "balance": "1940000000000000000000" + }, + "2a9c57fe7b6b138a920d676f3c76b6c2a0eef699": { + "balance": "9400000000000000000000" + }, + "36df8f883c1273ec8a171f7a33cfd649b1fe6075": { + "balance": "227290000000000000000" + }, + "234f46bab73fe45d31bf87f0a1e0466199f2ebac": { + "balance": "485000000000000000000" + }, + "a2e1b8aa900e9c139b3fa122354f6156d92a18b1": { + "balance": "500000000000000000000" + }, + "517cd7608e5d0d83a26b717f3603dac2277dc3a4": { + "balance": "2000000000000000000000" + }, + "75f7539d309e9039989efe2e8b2dbd865a0df088": { + "balance": "2460000000000000000000" + }, + "4b792e29683eb586e394bb33526c6001b397999e": { + "balance": "600000000000000000000" + }, + "a34f9d568bf7afd94c2a5b8a5ff55c66c4087999": { + "balance": "2444000000000000000000" + }, + "4b31bf41abc75c9ae2cd8f7f35163b6e2b745054": { + "balance": "382000000000000000000" + }, + "e35453eef2cc3c7a044d0ac134ba615908fa82ee": { + "balance": "147510000000000000000" + }, + "7aa79ac04316cc8d08f20065baa6d4142897d54e": { + "balance": "1400000000000000000000" + }, + "f1dc8ac81042c67a9c3c6792b230c46ac016ca10": { + "balance": "200000000000000000000" + }, + "2bb366b9edcb0da680f0e10b3b6e28748190d6c3": { + "balance": "5799400000000000000000" + }, + "a567770b6ae320bdde50f904d663e746a61dace6": { + "balance": "2000000000000000000000" + }, + "d9d42fd13ebd4bf69cac5e9c7e82483ab46dd7e9": { + "balance": "5348000000000000000000" + }, + "27830c5f6023afaaf79745676c204a0faccda0ba": { + "balance": "240000000000000000000" + }, + "3cb179cb4801a99b95c3b0c324a2bdc101a65360": { + "balance": "26000000000000000000" + }, + "976e3ceaf3f1af51f8c29aff5d7fa21f0386d8ee": { + "balance": "240000000000000000000" + }, + "752a5ee232612cd3005fb26e5b597de19f776be6": { + "balance": "5460000000000000000000" + }, + "7d5aa33fc14b51841a06906edb2bb49c2a117269": { + "balance": "300048000000000000000" + }, + "55ca6abe79ea2497f46fdbb830346010fe469cbe": { + "balance": "5730000000000000000000" + }, + "6bec311ad05008b4af353c958c40bd06739a3ff3": { + "balance": "16380000000000000000000" + }, + "30e9698cf1e08a9d048bd8d8048f28be7ed9409f": { + "balance": "6685000000000000000000" + }, + "9afa536b4c66bc38d875c4b30099d9261fdb38eb": { + "balance": "205981000000000000000" + }, + "6b63a2dfb2bcd0caec0022b88be30c1451ea56aa": { + "balance": "809021000000000000000" + }, + "d07be0f90997caf903c8ac1d53cde904fb190741": { + "balance": "1000200000000000000000" + }, + "893cdddf5377f3c751bf2e541120045a47cba101": { + "balance": "100000000000000000000" + }, + "c1cdc601f89c0428b31302d187e0dc08ad7d1c57": { + "balance": "6000000000000000000000" + }, + "8f8acb107607388479f64baaabea8ff007ada97d": { + "balance": "27281800000000000000000" + }, + "88bc43012edb0ea9f062ac437843250a39b78fbb": { + "balance": "20000000000000000000000" + }, + "fcfc3a5004d678613f0b36a642269a7f371c3f6a": { + "balance": "1000000000000000000000" + }, + "f509557e90183fbf0f0651a786487bcc428ba175": { + "balance": "194000000000000000000" + }, + "e3d915eda3b825d6ee4af9328d32ac18ada35497": { + "balance": "500000000000000000000" + }, + "f237ef05261c34d79cc22b860de0f17f793c3860": { + "balance": "200000000000000000000" + }, + "a3a2e319e7d3a1448b5aa2468953160c2dbcba71": { + "balance": "2000000000000000000000" + }, + "3a368efe4ad786e26395ec9fc6ad698cae29fe01": { + "balance": "632200000000000000000" + }, + "8e3240b0810e1cf407a500804740cf8d616432a4": { + "balance": "40309000000000000000" + }, + "5691dd2f6745f20e22d2e1d1b955aa2903d65656": { + "balance": "1969606000000000000000" + }, + "5f93ff832774db5114c55bb4bf44ccf3b58f903f": { + "balance": "192026650000000000000000" + }, + "2c1cc6e18c152488ba11c2cc1bcefa2df306abd1": { + "balance": "1670000000000000000000" + }, + "bde9786a84e75b48f18e726dd78d70e4af3ed802": { + "balance": "5730000000000000000000" + }, + "79551cede376f747e3716c8d79400d766d2e0195": { + "balance": "46250000000000000000000" + }, + "49f028395b5a86c9e07f7778630e4c2e3d373a77": { + "balance": "122735000000000000000" + }, + "6a3694424c7cc6b8bcd9bccaba540cc1f5df18d7": { + "balance": "2000000000000000000000" + }, + "068e29b3f191c812a6393918f71ab933ae6847f2": { + "balance": "1999944000000000000000" + }, + "6e64e6129f224e378c0e6e736a7e7a06c211e9ec": { + "balance": "1000000000000000000000" + }, + "c4c15318d370c73318cc18bdd466dbaa4c6603bf": { + "balance": "19700000000000000000" + }, + "8035bcffaefdeeea35830c497d14289d362023de": { + "balance": "300000000000000000000" + }, + "a997dfc7986a27050848fa1c64d7a7d6e07acca2": { + "balance": "143000000000000000000" + }, + "2fe13a8d0785de8758a5e41876c36e916cf75074": { + "balance": "4000000000000000000000" + }, + "6f24c9af2b763480515d1b0951bb77a540f1e3f9": { + "balance": "1970000000000000000000" + }, + "4c23b370fc992bb67cec06e26715b62f0b3a4ac3": { + "balance": "10000000000000000000000" + }, + "4ac07673e42f64c1a25ec2fa2d86e5aa2b34e039": { + "balance": "2000000000000000000000" + }, + "117db836377fe15455e02c2ebda40b1ceb551b19": { + "balance": "6000000000000000000000" + }, + "ef1c0477f1184d60accab374d374557a0a3e10f3": { + "balance": "152000000000000000000" + }, + "99fe0d201228a753145655d428eb9fd94985d36d": { + "balance": "1939268000000000000000" + }, + "b3731b046c8ac695a127fd79d0a5d5fa6ae6d12e": { + "balance": "1998000000000000000000" + }, + "dce30c31f3ca66721ecb213c809aab561d9b52e4": { + "balance": "2000000000000000000000" + }, + "ddd69c5b9bf5eb5a39cee7c3341a120d973fdb34": { + "balance": "1987730000000000000000" + }, + "216e41864ef98f060da08ecae19ad1166a17d036": { + "balance": "5730000000000000000000" + }, + "6a53d41ae4a752b21abed5374649953a513de5e5": { + "balance": "2000000000000000000000" + }, + "20dd8fcbb46ea46fe381a68b8ca0ea5be21fe9a5": { + "balance": "2000000000000000000000" + }, + "19732bf973055dbd91a4533adaa2149a91d38380": { + "balance": "2000000000000000000000" + }, + "51ea1c0934e3d04022ed9c95a087a150ef705e81": { + "balance": "6280000000000000000000" + }, + "a0de5c601e696635c698b7ae9ca4539fc7b941ec": { + "balance": "346150000000000000000" + }, + "94e1f5cb9b8abace03a1a6428256553b690c2355": { + "balance": "20000000000000000000" + }, + "a539b4a401b584dfe0f344b1b422c65543167e2e": { + "balance": "200000000000000000000" + }, + "50584d9206a46ce15c301117ee28f15c30e60e75": { + "balance": "13400000000000000000" + }, + "856eb204241a87830fb229031343dc30854f581a": { + "balance": "1000000000000000000000" + }, + "9dd46b1c6d3f05e29e9c6f037eed9a595af4a9aa": { + "balance": "500000000000000000000" + }, + "8925da4549e15155e57a628522cea9dddf627d81": { + "balance": "1000070000000000000000" + }, + "a89df34859edd7c820db887740d8ff9e15157c7b": { + "balance": "2000000000000000000000" + }, + "ad9f4c890a3b511cee51dfe6cfd7f1093b76412c": { + "balance": "506600000000000000000" + }, + "f8c7f34a38b31801da43063477b12b27d0f203ff": { + "balance": "494800000000000000000" + }, + "a642501004c90ea9c9ed1998ba140a4cd62c6f5f": { + "balance": "250543000000000000000" + }, + "508cf19119db70aa86454253da764a2cb1b2be1a": { + "balance": "1000000000000000000000" + }, + "2979741174a8c1ea0b7f9edf658177859417f512": { + "balance": "461283000000000000000" + }, + "654f524847b3a6acc0d3d5f1f362b603edf65f96": { + "balance": "8000000000000000000000" + }, + "5cf18fa7c8a7c0a2b3d5efd1990f64ddc569242c": { + "balance": "1000000000000000000000" + }, + "17e82e7078dc4fd9e879fb8a50667f53a5c54591": { + "balance": "200000000000000000000" + }, + "8b07d050754dc9ba230db01c310afdb5395aa1b3": { + "balance": "118080000000000000000" + }, + "5f77a107ab1226b3f95f10ee83aefc6c5dff3edc": { + "balance": "500000000000000000000" + }, + "475a6193572d4a4e59d7be09cb960ddd8c530e2f": { + "balance": "667323000000000000000" + }, + "6470a4f92ec6b0fccd01234fa59023e9ff1f3aac": { + "balance": "3000000000000000000000" + }, + "2fbcef3384d420e4bf61a0669990bc7054f1a5af": { + "balance": "2000000000000000000000" + }, + "bbabf6643beb4bd01c120bd0598a0987d82967d1": { + "balance": "3342500000000000000000" + }, + "41a2f2e6ecb86394ec0e338c0fc97e9c5583ded2": { + "balance": "2009400000000000000000" + }, + "fb9473cf7712350a1fa0395273fc80560752e4fb": { + "balance": "123300000000000000000" + }, + "38b2197106123387a0d4de368431a8bacdda30e2": { + "balance": "20000000000000000000" + }, + "5ed56115bd6505a88273df5c56839470d24a2db7": { + "balance": "65601000000000000000" + }, + "523f6d64690fdacd942853591bb0ff20d3656d95": { + "balance": "1820000000000000000000" + }, + "55caff4bba04d220c9a5d2018672ec85e31ef83e": { + "balance": "2000000000000000000000" + }, + "65af8d8b5b1d1eedfa77bcbc96c1b133f83306df": { + "balance": "98000000000000000000" + }, + "7456c5b2c5436e3e571008933f1805ccfe34e9ec": { + "balance": "1000000000000000000000" + }, + "a6eebbe464d39187bf80ca9c13d72027ec5ba8be": { + "balance": "3000000000000000000000" + }, + "dd35cfdbcb993395537aecc9f59085a8d5ddb6f5": { + "balance": "1000000000000000000000" + }, + "98e2b6d606fd2d6991c9d6d4077fdf3fdd4585da": { + "balance": "901520000000000000000" + }, + "860f5ffc10de767ded807f71e861d647dfd219b1": { + "balance": "10000000000000000000000" + }, + "1a644a50cbc2aee823bd2bf243e825be4d47df02": { + "balance": "100007000000000000000" + }, + "a8455b411765d6901e311e726403091e42c56683": { + "balance": "3380000000000000000000" + }, + "3a86ee94862b743dd34f410969d94e2c5652d4ad": { + "balance": "201610000000000000000" + }, + "a57360f002e0d64d2d74457d8ca4857ee00bcddf": { + "balance": "335780000000000000000" + }, + "e59b3bd300893f97233ef947c46f7217e392f7e9": { + "balance": "1000000000000000000000" + }, + "9f3a74fd5e7edcc1162993171381cbb632b7cff0": { + "balance": "10000000000000000000000" + }, + "675d5caa609bf70a18aca580465d8fb7310d1bbb": { + "balance": "20000000000000000000000" + }, + "77f609ca8720a023262c55c46f2d26fb3930ac69": { + "balance": "17300000000000000000" + }, + "f8ac4a39b53c11307820973b441365cffe596f66": { + "balance": "2000000000000000000000" + }, + "112634b4ec30ff786e024159f796a57939ea144e": { + "balance": "1999944000000000000000" + }, + "49d2c28ee9bc545eaaf7fd14c27c4073b4bb5f1a": { + "balance": "1474134000000000000000" + }, + "91cc46aa379f856a6640dccd5a648a7902f849d9": { + "balance": "200000000000000000000" + }, + "b46440c797a556e04c7d9104660491f96bb076bf": { + "balance": "14900000000000000000" + }, + "e5968797468ef767101b761d431fce14abffdbb4": { + "balance": "8040000000000000000000" + }, + "c0895efd056d9a3a81c3da578ada311bfb9356cf": { + "balance": "200000000000000000000" + }, + "76846f0de03b5a76971ead298cdd08843a4bc6c6": { + "balance": "15500000000000000000" + }, + "5f708eaf39d823946c51b3a3e9b7b3c003e26341": { + "balance": "1820000000000000000000" + }, + "24f7450ddbf18b020feb1a2032d9d54b633edf37": { + "balance": "50000000000000000000" + }, + "cae3a253bcb2cf4e13ba80c298ab0402da7c2aa0": { + "balance": "5400000000000000000000" + }, + "91e8810652e8e6161525d63bb7751dc20f676076": { + "balance": "725000000000000000000" + }, + "543629c95cdef428ad37d453ca9538a9f90900ac": { + "balance": "43250000000000000000000" + }, + "6e79edd4845b076e4cd88d188b6e432dd93f35aa": { + "balance": "955000000000000000000" + }, + "bd325d4029e0d8729f6d399c478224ae9e7ae41e": { + "balance": "3880000000000000000000" + }, + "42cecfd2921079c2d7df3f08b07aa3beee5e219a": { + "balance": "1000000000000000000000" + }, + "3690246ba3c80679e22eac4412a1aefce6d7cd82": { + "balance": "20000000000000000000000" + }, + "577aeee8d4bc08fc97ab156ed57fb970925366be": { + "balance": "333046000000000000000" + }, + "fe00bf439911a553982db638039245bcf032dbdc": { + "balance": "394000000000000000000" + }, + "91f624b24a1fa5a056fe571229e7379db14b9a1e": { + "balance": "11999974000000000000000" + }, + "f206d328e471d0117b246d2a4619827709e96df3": { + "balance": "3001000000000000000000" + }, + "073f1ed1c9c3e9c52a9b0249a5c1caa0571fdf05": { + "balance": "70400000000000000000" + }, + "f56048dd2181d4a36f64fcecc6215481e42abc15": { + "balance": "200000000000000000000" + }, + "ef76a4cd8febcbc9b818f17828f8d93473f3f3cb": { + "balance": "4000000000000000000000" + }, + "1031e0ecb54985ae21af1793950dc811888fde7c": { + "balance": "20000000000000000000" + }, + "8e0fee38685a94aabcd7ce857b6b1409824f75b8": { + "balance": "500000000000000000000" + }, + "f0cbef84e169630098d4e301b20208ef05846ac9": { + "balance": "259084000000000000000" + }, + "bbca65b3266ea2fb73a03f921635f912c7bede00": { + "balance": "1970000000000000000000" + }, + "0aec2e426ed6cc0cf3c249c1897eac47a7faa9bd": { + "balance": "200000000000000000000" + }, + "b8f30758faa808dbc919aa7b425ec922b93b8129": { + "balance": "1000076000000000000000" + }, + "936dcf000194e3bff50ac5b4243a3ba014d661d8": { + "balance": "10000000000000000000000" + }, + "b14ddb0386fb606398b8cc47565afae00ff1d66a": { + "balance": "2973024000000000000000" + }, + "2ec95822eb887bc113b4712a4dfd7f13b097b5e7": { + "balance": "1000000000000000000000" + }, + "0136a5af6c3299c6b5f005fdaddb148c070b299b": { + "balance": "20368000000000000000" + }, + "37cb868d2c3f95b257611eb34a4188d58b749802": { + "balance": "2000000000000000000000" + }, + "cd7f09d7ed66d0c38bc5ad4e32b7f2b08dc1b30d": { + "balance": "1148000000000000000000" + }, + "b5fa8184e43ed3e0b8ab91216461b3528d84fd09": { + "balance": "2680000000000000000000" + }, + "3dbf0dbfd77890800533f09dea8301b9f025d2a6": { + "balance": "1000000000000000000000" + }, + "b553d25d6b5421e81c2ad05e0b8ba751f8f010e3": { + "balance": "2000000000000000000000" + }, + "dbf8b13967f55125272de0562536c450ba5655a0": { + "balance": "2046830000000000000000" + }, + "0f6e840a3f2a24647d8e43e09d45c7c335df4248": { + "balance": "2500000000000000000000" + }, + "fa2fd29d03fee9a07893df3a269f56b72f2e1e64": { + "balance": "10000000000000000000000" + }, + "8b57b2bc83cc8d4de331204e893f2f3b1db1079a": { + "balance": "40000000000000000000" + }, + "7f541491d2ac00d2612f94aa7f0bcb014651fbd4": { + "balance": "376000000000000000000" + }, + "4f4a9be10cd5d3fb5de48c17be296f895690645b": { + "balance": "40000000000000000000000" + }, + "45d1c9eedf7cab41a779057b79395f5428d80528": { + "balance": "2000000000000000000000" + }, + "662334814724935b7931ddca6100e00d467727cd": { + "balance": "637000000000000000000" + }, + "2c52c984102ee0cd3e31821b84d408930efa1ac7": { + "balance": "2000000000000000000000" + }, + "000d836201318ec6899a67540690382780743280": { + "balance": "200000000000000000000" + }, + "81498ca07b0f2f17e8bbc7e61a7f4ae7be66b78b": { + "balance": "101600000000000000000" + }, + "7860a3de38df382ae4a4dce18c0c07b98bce3dfa": { + "balance": "1000000000000000000000" + }, + "5e8e4df18cf0af770978a8df8dac90931510a679": { + "balance": "2000000000000000000000" + }, + "05d68dad61d3bbdfb3f779265c49474aff3fcd30": { + "balance": "39399000000000000000" + }, + "96eafbf2fb6f4db9a436a74c45b5654452e23819": { + "balance": "20000000000000000000" + }, + "d7d7f2caa462a41b3b30a34aeb3ba61010e2626f": { + "balance": "2000000000000000000000" + }, + "0b71f554122469ef978e2f1fefd7cbb410982772": { + "balance": "3880000000000000000000" + }, + "504666ce8931175e11a5ed11c1dcaa06e57f4e66": { + "balance": "11792000000000000000000" + }, + "d00f067286c0fbd082f9f4a61083ec76deb3cee6": { + "balance": "1000000000000000000000" + }, + "02e4cb22be46258a40e16d4338d802fffd00c151": { + "balance": "379786000000000000000" + }, + "1c13d38637b9a47ce79d37a86f50fb409c060728": { + "balance": "1337000000000000000000" + }, + "e30212b2011bb56bdbf1bc35690f3a4e0fd905ea": { + "balance": "8022000000000000000000" + }, + "1df6911672679bb0ef3509038c0c27e394fdfe30": { + "balance": "540000000000000000000" + }, + "2b8fe4166e23d11963c0932b8ade8e0145ea0770": { + "balance": "43250000000000000000000" + }, + "6509eeb1347e842ffb413e37155e2cbc738273fd": { + "balance": "2000000000000000000000" + }, + "8b7e9f6f05f7e36476a16e3e7100c9031cf404af": { + "balance": "1000000000000000000000" + }, + "bec8caf7ee49468fee552eff3ac5234eb9b17d42": { + "balance": "2000000000000000000000" + }, + "38898bbb4553e00bbfd0cf268b2fc464d154add5": { + "balance": "320000000000000000000" + }, + "cbb3189e4bd7f45f178b1c30c76e26314d4a4b0a": { + "balance": "295007000000000000000" + }, + "be1cd7f4c472070968f3bde268366b21eeea8321": { + "balance": "4300000000000000000000" + }, + "976a18536af41874426308871bcd1512a775c9f8": { + "balance": "10000000000000000000000" + }, + "e9c758f8da41e3346e4350e5ac3976345c6c1082": { + "balance": "1930050000000000000000" + }, + "64ec8a5b743f3479e707dae9ee20ddaa4f40f1d9": { + "balance": "200000000000000000000" + }, + "9e01765aff08bc220550aca5ea2e1ce8e5b09923": { + "balance": "1000000000000000000000" + }, + "ba0f39023bdb29eb1862a9f9059cab5d306e662f": { + "balance": "2000000000000000000000" + }, + "2baf8d6e221174124820ee492b9459ec4fadafbb": { + "balance": "2000000000000000000000" + }, + "655d5cd7489629e2413c2105b5a172d933c27af8": { + "balance": "4040060000000000000000" + }, + "badc2aef9f5951a8d78a6b35c3d0b3a4e6e2e739": { + "balance": "6000000000000000000000" + }, + "e64f6e1d6401b56c076b64a1b0867d0b2f310d4e": { + "balance": "51570000000000000000" + }, + "7a8563867901206f3f2bf0fa3e1c8109cabccd85": { + "balance": "137000000000000000000" + }, + "d17fbe22d90462ed37280670a2ea0b3086a0d6d6": { + "balance": "199955000000000000000" + }, + "e96d7d4cdd15553a4e4d316d6d6480ca3cea1e38": { + "balance": "12200000000000000000000" + }, + "f04d2c91efb6e9c45ffbe74b434c8c5f2b028f1f": { + "balance": "1000000000000000000000" + }, + "81164deb10814ae08391f32c08667b6248c27d7a": { + "balance": "394000000000000000000" + }, + "7f5ae05ae0f8cbe5dfe721f044d7a7bef4c27997": { + "balance": "60000000000000000000" + }, + "c982586d63b0d74c201b1af8418372e30c7616be": { + "balance": "100000000000000000000" + }, + "64cf0935bf19d2cebbecd8780d27d2e2b2c34166": { + "balance": "1970000000000000000000" + }, + "cd566ad7b883f01fd3998a9a58a9dee4724ddca5": { + "balance": "58848000000000000000" + }, + "9da609fa3a7e6cf2cc0e70cdabe78dc4e382e11e": { + "balance": "1200000000000000000000" + }, + "0d69100c395ce6c5eaadf95d05d872837ededd21": { + "balance": "400000000000000000000" + }, + "fe91eccf2bd566afa11696c5049fa84c69630a52": { + "balance": "1940000000000000000000" + }, + "005d0ee8155ec0a6ff6808552ca5f16bb5be323a": { + "balance": "197000000000000000000" + }, + "3e5cb8928c417825c03a3bfcc52183e5c91e42d7": { + "balance": "4264790000000000000000" + }, + "9c1b771f09af882af0643083de2aa79dc097c40e": { + "balance": "2480000000000000000000" + }, + "eba388b0da27c87b1cc0eac6c57b2c5a0b459c1a": { + "balance": "6800000000000000000000" + }, + "7529f3797bb6a20f7ea6492419c84c867641d81c": { + "balance": "2000000000000000000000" + }, + "532a7da0a5ad7407468d3be8e07e69c7dd64e861": { + "balance": "500000000000000000000" + }, + "de82cc8d4a1bb1d9434392965b3e80bad3c03d4f": { + "balance": "1477500000000000000000" + }, + "4a82694fa29d9e213202a1a209285df6e745c209": { + "balance": "4000000000000000000000" + }, + "3e53ff2107a8debe3328493a92a586a7e1f49758": { + "balance": "23143470000000000000000" + }, + "b2ddb786d3794e270187d0451ad6c8b79e0e8745": { + "balance": "400000000000000000000" + }, + "6ebcf9957f5fc5e985add475223b04b8c14a7aed": { + "balance": "1730000000000000000000" + }, + "c5c7590b5621ecf8358588de9b6890f2626143f1": { + "balance": "3000000000000000000000" + }, + "ae4f122e35c0b1d1e4069291457c83c07f965fa3": { + "balance": "1000000000000000000000" + }, + "47885ababedf4d928e1c3c71d7ca40d563ed595f": { + "balance": "1820000000000000000000" + }, + "78ce3e3d474a8a047b92c41542242d0a08c70f99": { + "balance": "10000000000000000000000" + }, + "6134d942f037f2cc3d424a230c603d67abd3edf7": { + "balance": "2000000000000000000000" + }, + "1360e87df24c69ee6d51c76e73767ffe19a2131c": { + "balance": "92000000000000000000" + }, + "5fd1c3e31778276cb42ea740f5eae9c641dbc701": { + "balance": "194000000000000000000" + }, + "98397342ec5f3d4cb877e54ef5d6f1d366731bd4": { + "balance": "5910000000000000000000" + }, + "6d4b5c05d06a20957e1748ab6df206f343f92f01": { + "balance": "10020475000000000000000" + }, + "e6115b13f9795f7e956502d5074567dab945ce6b": { + "balance": "100000000000000000000000" + }, + "23730c357a91026e44b1d0e2fc2a51d071d8d77b": { + "balance": "4000000000000000000000" + }, + "fae881937047895a660cf229760f27e66828d643": { + "balance": "182000000000000000000" + }, + "ff3ef6ba151c21b59986ae64f6e8228bc9a2c733": { + "balance": "2000000000000000000000" + }, + "dfbd4232c17c407a980db87ffbcda03630e5c459": { + "balance": "553150000000000000000" + }, + "4429a29fee198450672c0c1d073162250bec6474": { + "balance": "999200000000000000000" + }, + "7e8f96cc29f57b0975120cb593b7dd833d606b53": { + "balance": "197000000000000000000" + }, + "5ed3f1ebe2ae6756b5d8dc19cad02c419aa5778b": { + "balance": "0" + }, + "daa776a6754469d7b9267a89b86725e740da0fa0": { + "balance": "1970000000000000000000" + }, + "139e479764b499d666208c4a8a047a97043163dd": { + "balance": "598880000000000000000" + }, + "5ad5e420755613886f35aa56ac403eebdfe4b0d0": { + "balance": "80000000000000000000000" + }, + "3fe801e61335c5140dc7eda2ef5204460a501230": { + "balance": "2000000000000000000000" + }, + "ce8a6b6d5033b1498b1ffeb41a41550405fa03a2": { + "balance": "4000000000000000000000" + }, + "26c2ffc30efdc5273e76183a16c2698d6e531286": { + "balance": "776000000000000000000" + }, + "71ec3aec3f8f9221f9149fede06903a0f9a232f2": { + "balance": "200000000000000000000" + }, + "ef35f6d4b1075e6aa139151c974b2f4658f70538": { + "balance": "1111111000000000000000" + }, + "26a68eab905a8b3dce00e317308225dab1b9f6b8": { + "balance": "1980000000000000000000" + }, + "63f5b53d79bf2e411489526530223845fac6f601": { + "balance": "30000000000000000000000" + }, + "481115296ab7db52492ff7b647d63329fb5cbc6b": { + "balance": "16100000000000000000000" + }, + "f19f193508393e4d2a127b20b2031f39c82581c6": { + "balance": "3500088000000000000000" + }, + "500e34cde5bd9e2b71bb92d7cf55eee188d5fa0c": { + "balance": "5348000000000000000000" + }, + "65ea67ad3fb56ad5fb94387dd38eb383001d7c68": { + "balance": "100000000000000000000" + }, + "7f9f9b56e4289dfb58e70fd5f12a97b56d35c6a5": { + "balance": "1970000000000000000000" + }, + "60be6f953f2a4d25b6256ffd2423ac1438252e4e": { + "balance": "150000000000000000000" + }, + "ac1dfc984b71a19929a81d81f04a7cbb14073703": { + "balance": "600000000000000000000" + }, + "a3c14ace28b192cbb062145fcbbd5869c67271f6": { + "balance": "8000000000000000000000" + }, + "2da76b7c39b420e388ba2c1020b0856b0270648a": { + "balance": "2000000000000000000000" + }, + "622be4b45495fcd93143efc412d699d6cdc23dc5": { + "balance": "17300000000000000000" + }, + "d3f873bd9956135789ab00ebc195b922e94b259d": { + "balance": "2000000000000000000000" + }, + "975f3764e97bbccf767cbd3b795ba86d8ba9840e": { + "balance": "346000000000000000000" + }, + "fc39be41094b1997d2169e8264c2c3baa6c99bc4": { + "balance": "2000000000000000000000" + }, + "12ffc1128605cb0c13709a7290506f2690977193": { + "balance": "3340000000000000000000" + }, + "9b1168de8ab64b47552f3389800a9cc08b4666cf": { + "balance": "1730000000000000000000" + }, + "9f1aa8fcfc89a1a5328cbd6344b71f278a2ca4a0": { + "balance": "500000000000000000000" + }, + "505a33a18634dd4800693c67f48a1d693d4833f8": { + "balance": "7252000000000000000000" + }, + "d08fc09a0030fd0928cd321198580182a76aae9f": { + "balance": "1000000000000000000000" + }, + "6acddca3cd2b4990e25cd65c24149d0912099e79": { + "balance": "3000037000000000000000" + }, + "397a6ef8763a18f00fac217e055c0d3094101011": { + "balance": "2000000000000000000000" + }, + "4e0bd32473c4c51bf25654def69f797c6b29a232": { + "balance": "1600930000000000000000" + }, + "28d8c35fb7eea622582135e3ad47a227c9a663bd": { + "balance": "18200000000000000000" + }, + "f96488698590dc3b2c555642b871348dfa067ad5": { + "balance": "500000000000000000000" + }, + "4eebe80cb6f3ae5904f6f4b28d907f907189fcab": { + "balance": "1999944000000000000000" + }, + "8d1abd897dacd4312e18080c88fb9647eab44052": { + "balance": "216000000000000000000" + }, + "457029c469c4548d168cec3e65872e4428d42b67": { + "balance": "2000000000000000000000" + }, + "1296acded1e063af39fe8ba0b4b63df789f70517": { + "balance": "100014000000000000000" + }, + "71762c63678c18d1c6378ce068e666381315147e": { + "balance": "2000000000000000000000" + }, + "6cc1c878fa6cde8a9a0b8311247e741e4642fe6d": { + "balance": "985000000000000000000" + }, + "8d9ed7f4553058c26f7836a3802d3064eb1b363d": { + "balance": "90000000000000000000" + }, + "5032e4bcf7932b49fdba377b6f1499636513cfc3": { + "balance": "100000000000000000000" + }, + "462b678b51b584f3ed7ada070b5cd99c0bf7b87f": { + "balance": "100000000000000000000" + }, + "c8aa49e3809f0899f28ab57e6743709d58419033": { + "balance": "880000000000000000000" + }, + "01b1cae91a3b9559afb33cdc6d689442fdbfe037": { + "balance": "200000000000000000000" + }, + "b1043004ec1941a8cf4f2b00b15700ddac6ff17e": { + "balance": "1000000000000000000000" + }, + "5ba2c6c35dfaec296826591904d544464aeabd5e": { + "balance": "20000000000000000000" + }, + "b32400fd13c5500917cb037b29fe22e7d5228f2d": { + "balance": "40000000000000000000000" + }, + "d59d92d2c8701980cc073c375d720af064743c0c": { + "balance": "19000000000000000000000" + }, + "11dd6185d9a8d73ddfdaa71e9b7774431c4dfec2": { + "balance": "1000000000000000000000" + }, + "d4cb21e590c5a0e06801366aff342c7d7db16424": { + "balance": "494000000000000000000" + }, + "5b6d55f6712967405c659129f4b1de09acf2cb7b": { + "balance": "267400000000000000000" + }, + "6179979907fe7f037e4c38029d60bcbab832b3d6": { + "balance": "1610000000000000000000" + }, + "33c407133b84b3ca4c3ded1f4658900c38101624": { + "balance": "2800000000000000000000" + }, + "cd2a36d753e9e0ed012a584d716807587b41d56a": { + "balance": "261400000000000000000" + }, + "8155fa6c51eb31d808412d748aa086105018122f": { + "balance": "1880000000000000000000" + }, + "3ecc8e1668dde995dc570fe414f44211c534a615": { + "balance": "2000000000000000000000" + }, + "d6395db5a4bb66e60f4cfbcdf0057bb4d97862e2": { + "balance": "910000000000000000000" + }, + "b6fb39786250081426a342c70d47ee521e5bc563": { + "balance": "15000000000000000000000" + }, + "510eda5601499a0d5e1a006bfffd833672f2e267": { + "balance": "2000000000000000000000" + }, + "98c19dba810ba611e68f2f83ee16f6e7744f0c1f": { + "balance": "200000000000000000000" + }, + "34ff26eb60a8d1a95a489fae136ee91d4e58084c": { + "balance": "600000000000000000000" + }, + "6ad90be252d9cd464d998125fab693060ba8e429": { + "balance": "4000000000000000000000" + }, + "038323b184cff7a82ae2e1bda7793fe4319ca0bf": { + "balance": "20000000000000000000000" + }, + "dc5305b4020a06b49d657c7ca34c35c91c5f2c56": { + "balance": "7045990000000000000000" + }, + "c9c80dc12e7bab86e949d01e4c3ed35f2b9bba5f": { + "balance": "2000000000000000000000" + }, + "7beb81fb2f5e91526b2ac9795e76c69bcff04bc0": { + "balance": "69400000000000000000000" + }, + "b8bc9bca7f71b4ed12e620438d620f53c114342f": { + "balance": "500000000000000000000" + }, + "d288e7cb7ba9f620ab0f7452e508633d1c5aa276": { + "balance": "4000000000000000000000" + }, + "a2e460a989cb15565f9ecca7d121a18e4eb405b6": { + "balance": "2000000000000000000000" + }, + "7489cc8abe75cda4ef0d01cef2605e47eda67ab1": { + "balance": "133700000000000000000" + }, + "38b403fb1fb7c14559a2d6f6564a5552bca39aff": { + "balance": "2000000000000000000000" + }, + "e55c80520a1b0f755b9a2cd3ce214f7625653e8a": { + "balance": "2000000000000000000000" + }, + "451b7070259bdba27100e36e23428a53dfe304e9": { + "balance": "13370000000000000000" + }, + "8b5c914b128bf1695c088923fa467e7911f351fa": { + "balance": "98500000000000000000" + }, + "17df49518d73b129f0da36b1c9b40cb66420fdc7": { + "balance": "10000000000000000000000" + }, + "c1950543554d8a713003f662bb612c10ad4cdf21": { + "balance": "18200000000000000000" + }, + "fa7606435b356cee257bd2fcd3d9eacb3cd1c4e1": { + "balance": "100000000000000000000" + }, + "e0bad98eee9698dbf6d76085b7923de5754e906d": { + "balance": "167000000000000000000" + }, + "ce53c8cdd74296aca987b2bc19c2b875a48749d0": { + "balance": "3000000000000000000000" + }, + "d0c55abf976fdc3db2afe9be99d499484d576c02": { + "balance": "1000000000000000000000" + }, + "238a6b7635252f5244486c0af0a73a207385e039": { + "balance": "1370000000000000000000" + }, + "ceb389381d48a8ae4ffc483ad0bb5e204cfdb1ec": { + "balance": "740745000000000000000" + }, + "3847667038f33b01c1cc795d8daf5475eff5a0d4": { + "balance": "728330000000000000000" + }, + "a08d215b5b6aac4861a281ac7e400b78fef04cbf": { + "balance": "20000000000000000000" + }, + "2d0dec51a6e87330a6a8fa2a0f65d88d4abcdf73": { + "balance": "185000000000000000000" + }, + "9e8f64ddcde9b8b451bafaa235a9bf511a25ac91": { + "balance": "2674000000000000000000" + }, + "ddac6bf4bbdd7d597d9c686d0695593bedccc7fa": { + "balance": "865000000000000000000" + }, + "22e15158b5ee3e86eb0332e3e6a9ac6cd9b55ecd": { + "balance": "160000000000000000000" + }, + "3aea4e82d2400248f99871a41ca257060d3a221b": { + "balance": "1000000000000000000000" + }, + "fb126f0ec769f49dcefca2f200286451583084b8": { + "balance": "5013750000000000000000" + }, + "1b8bd6d2eca20185a78e7d98e8e185678dac4830": { + "balance": "16700000000000000000000" + }, + "664cd67dccc9ac8228b45c55db8d76550b659cdc": { + "balance": "394000000000000000000" + }, + "553f37d92466550e9fd775ae74362df030179132": { + "balance": "2000000000000000000000" + }, + "730d8763c6a4fd824ab8b859161ef7e3a96a1200": { + "balance": "20000000000000000000000" + }, + "04c2c64bb54c3eccd05585e10ec6f99a0cdb01a3": { + "balance": "100000000000000000000" + }, + "f1624d980b65336feac5a6d54125005cfcf2aacb": { + "balance": "2000000000000000000000" + }, + "0b7fc9ddf70576f6330669eaaa71b6a831e99528": { + "balance": "140000000000000000000" + }, + "fa2bbca15d3fe39f8a328e91f90da14f7ac6253d": { + "balance": "200000000000000000000" + }, + "07feef54c136850829badc4b49c3f2a73c89fb9e": { + "balance": "118200000000000000000" + }, + "3703350c4d6fe337342cddc65bf1e2386bf3f9b2": { + "balance": "2020000000000000000000" + }, + "6d7d1c949511f88303808c60c5ea0640fcc02683": { + "balance": "10000000000000000000000" + }, + "34fa7792bad8bbd7ff64056214a33eb6600c1ea8": { + "balance": "50000000000000000000" + }, + "994cc2b5227ec3cf048512467c41b7b7b748909f": { + "balance": "2000000000000000000000" + }, + "08da3a7a0f452161cfbcec311bb68ebfdee17e88": { + "balance": "2000000000000000000000" + }, + "bbb4ee1d82f2e156442cc93338a2fc286fa28864": { + "balance": "1370000000000000000000" + }, + "7a2dfc770e24368131b7847795f203f3d50d5b56": { + "balance": "11400000000000000000000" + }, + "7cef4d43aa417f9ef8b787f8b99d53f1fea1ee88": { + "balance": "1910000000000000000000" + }, + "c6a30ef5bb3320f40dc5e981230d52ae3ac19322": { + "balance": "182000000000000000000" + }, + "6a74844d8e9cb5581c45079a2e94462a6cee8821": { + "balance": "1082970000000000000000" + }, + "c3110be01dc9734cfc6e1ce07f87d77d1345b7e1": { + "balance": "4999998000000000000000" + }, + "aeb916ebf49d0f86c13f7331cef19e129937512d": { + "balance": "599908000000000000000" + }, + "3e5abd09ce5af7ba8487c359e0f2a93a986b0b18": { + "balance": "10000000000000000000000" + }, + "cdd60d73efaad873c9bbfb178ca1b7105a81a681": { + "balance": "32000000000000000000" + }, + "31eb123c95c82bf685ace7a75a1881a289efca10": { + "balance": "920034000000000000000" + }, + "86e8670e27598ea09c3899ab7711d3b9fe901c17": { + "balance": "200000000000000000000" + }, + "a144f6b60f72d64a21e330dadb62d8990ade2b09": { + "balance": "1000000000000000000000" + }, + "68883e152e5660fee59626e7e3b4f05110e6222f": { + "balance": "54683300000000000000000" + }, + "fe4249127950e2f896ec0e7e2e3d055aab10550f": { + "balance": "668500000000000000000" + }, + "403d53cf620f0922b417848dee96c190b5bc8271": { + "balance": "9850000000000000000000" + }, + "bec2e6de39c07c2bae556acfbee2c4728b9982e3": { + "balance": "573000000000000000000" + }, + "f3c4716d1ee5279a86d0163a14618181e16136c7": { + "balance": "1000000000000000000000" + }, + "e38ef28a5ed984a7db24a1ae782dfb87f397dfc6": { + "balance": "143000000000000000000" + }, + "30fbe5885f9fcce9ea5edb82ed4a1196dd259aed": { + "balance": "5200000000000000000000" + }, + "48bf14d7b1fc84ebf3c96be12f7bce01aa69b03e": { + "balance": "120000000000000000000" + }, + "b8d5c324a8209d7c8049d0d4aede02ba80ab578b": { + "balance": "16889329000000000000000" + }, + "43d5a71ce8b8f8ae02b2eaf8eaf2ca2840b93fb6": { + "balance": "6000000000000000000000" + }, + "f9a59c3cc5ffacbcb67be0fc7256f64c9b127cb4": { + "balance": "2000000000000000000000" + }, + "0e21af1b8dbf27fcf63f37e047b87a825cbe7c27": { + "balance": "3000000000000000000000" + }, + "1c35aab688a0cd8ef82e76541ba7ac39527f743b": { + "balance": "500000000000000000000" + }, + "91ac5cfe67c54aa7ebfba448666c461a3b1fe2e1": { + "balance": "401880000000000000000" + }, + "4ba53ab549e2016dfa223c9ed5a38fad91288d07": { + "balance": "1400000000000000000000" + }, + "99a4de19ded79008cfdcd45d014d2e584b8914a8": { + "balance": "1500000000000000000000" + }, + "4adbf4aae0e3ef44f7dd4d8985cfaf096ec48e98": { + "balance": "150000000000000000000" + }, + "9a633fcd112cceeb765fe0418170732a9705e79c": { + "balance": "18200000000000000000" + }, + "292f228b0a94748c8eec612d246f989363e08f08": { + "balance": "185000000000000000000" + }, + "9f3497f5ef5fe63095836c004eb9ce02e9013b4b": { + "balance": "633424000000000000000" + }, + "0e6dfd553b2e873d2aec15bd5fbb3f8472d8d394": { + "balance": "12000000000000000000000" + }, + "74ebf4425646e6cf81b109ce7bf4a2a63d84815f": { + "balance": "40000000000000000000" + }, + "8ce5e3b5f591d5eca38abf228f2e3c35134bdac0": { + "balance": "2319920000000000000000" + }, + "90c41eba008e20cbe927f346603fc88698125969": { + "balance": "42000000000000000000" + }, + "382ba76db41b75606dd48a48f0137e9174e031b6": { + "balance": "20000000000000000000" + }, + "5d24bdbc1c47f0eb83d128cae48ac33c4817e91f": { + "balance": "1000000000000000000000" + }, + "a64e5ffb704c2c9139d77ef61d8cdfa31d7a88e9": { + "balance": "143000000000000000000" + }, + "a18360e985f2062e8f8efe02ad2cbc91ad9a5aad": { + "balance": "3000000000000000000000" + }, + "d251f903ae18727259eee841a189a1f569a5fd76": { + "balance": "10000000000000000000000" + }, + "efa6b1f0db603537826891b8b4bc163984bb40cd": { + "balance": "985000000000000000000" + }, + "47fff42c678551d141eb75a6ee398117df3e4a8d": { + "balance": "100010000000000000000" + }, + "f2294adbb6f0dcc76e632ebef48ab49f124dbba4": { + "balance": "1443690000000000000000" + }, + "53700d53254d430f22781a4a76a463933b5d6b08": { + "balance": "1970000000000000000000" + }, + "b14a7aaa8f49f2fb9a8102d6bbe4c48ae7c06fb2": { + "balance": "8000000000000000000000" + }, + "9ed4e63f526542d44fddd34d59cd25388ffd6bda": { + "balance": "3885000000000000000000" + }, + "4cac91fb83a147d2f76c3267984b910a79933348": { + "balance": "2167000000000000000000" + }, + "9b32cf4f5115f4b34a00a64c617de06387354323": { + "balance": "105501000000000000000" + }, + "b8bedd576a4b4c2027da735a5bc3f533252a1808": { + "balance": "2000000000000000000000" + }, + "c5a3b98e4593fea0b38c4f455a5065f051a2f815": { + "balance": "20309030000000000000000" + }, + "eaf52388546ec35aca6f6c6393d8d609de3a4bf3": { + "balance": "20000000000000000000" + }, + "4c423c76930d07f93c47a5cc4f615745c45a9d72": { + "balance": "100000000000000000000" + }, + "9052f2e4a3e3c12dd1c71bf78a4ec3043dc88b7e": { + "balance": "267400000000000000000" + }, + "2bade91d154517620fd4b439ac97157a4102a9f7": { + "balance": "4000000000000000000000" + }, + "da698d64c65c7f2b2c7253059cd3d181d899b6b7": { + "balance": "295500000000000000000" + }, + "c6d8954e8f3fc533d2d230ff025cb4dce14f3426": { + "balance": "400000000000000000000" + }, + "349a816b17ab3d27bbc0ae0051f6a070be1ff29d": { + "balance": "10000000000000000000000" + }, + "ff4d9c8484c43c42ff2c5ab759996498d323994d": { + "balance": "4000000000000000000000" + }, + "22944fbca9b57963084eb84df7c85fb9bcdfb856": { + "balance": "4649845000000000000000" + }, + "bfd93c90c29c07bc5fb5fc49aeea55a40e134f35": { + "balance": "28000000000000000000000" + }, + "3caedb5319fe806543c56e5021d372f71be9062e": { + "balance": "40000000000000000000000" + }, + "9a079c92a629ca15c8cafa2eb28d5bc17af82811": { + "balance": "500000000000000000000" + }, + "7d2a52a7cf0c8436a8e007976b6c26b7229d1e15": { + "balance": "438040000000000000000" + }, + "cf89f7460ba3dfe83c5a1d3a019ee1250f242f0f": { + "balance": "985177000000000000000" + }, + "577bfe64e3a1e3800e94db1c6c184d8dc8aafc66": { + "balance": "1498000000000000000000" + }, + "7ffd02ed370c7060b2ae53c078c8012190dfbb75": { + "balance": "10000000000000000000000" + }, + "90b62f131a5f29b45571513ee7a74a8f0b232202": { + "balance": "158000000000000000000" + }, + "6e8212b722afd408a7a73ed3e2395ee6454a0330": { + "balance": "159000000000000000000" + }, + "515f30bc90cdf4577ee47d65d785fbe2e837c6bc": { + "balance": "10166128000000000000000" + }, + "c27376f45d21e15ede3b26f2655fcee02ccc0f2a": { + "balance": "20000000000000000000" + }, + "3da39ce3ef4a7a3966b32ee7ea4ebc2335a8f11f": { + "balance": "2000000000000000000000" + }, + "25259d975a21d83ae30e33f800f53f37dfa01938": { + "balance": "20000000000000000000" + }, + "8ed143701f2f72280fd04a7b4164281979ea87c9": { + "balance": "14000000000000000000" + }, + "5ac99ad7816ae9020ff8adf79fa9869b7cea6601": { + "balance": "21000000000000000000000" + }, + "f51fded80acb502890e87369741f3722514cefff": { + "balance": "20000042000000000000000" + }, + "f657fcbe682eb4e8db152ecf892456000b513d15": { + "balance": "1940000000000000000000" + }, + "62c37c52b97f4b040b1aa391d6dec152893c4707": { + "balance": "1000000000000000000000" + }, + "89fc8e4d386b0d0bb4a707edf3bd560df1ad8f4e": { + "balance": "2955000000000000000000" + }, + "53c0bb7fc88ea422d2ef7e540e2d8f28b1bb8183": { + "balance": "20000000000000000000" + }, + "56f493a3d108aaa2d18d98922f8efe1662cfb73d": { + "balance": "2020000000000000000000" + }, + "e9458f68bb272cb5673a04f781b403556fd3a387": { + "balance": "61000000000000000000" + }, + "be525a33ea916177f17283fca29e8b350b7f530b": { + "balance": "2638000000000000000000" + }, + "4feb846be43041fd6b34202897943e3f21cb7f04": { + "balance": "83226000000000000000" + }, + "15aa530dc36958b4edb38eee6dd9e3c77d4c9145": { + "balance": "2000000000000000000000" + }, + "2458d6555ff98a129cce4037953d00206eff4287": { + "balance": "197000000000000000000" + }, + "8035fe4e6b6af27ae492a578515e9d39fa6fa65b": { + "balance": "4000000000000000000000" + }, + "296b71c0015819c242a7861e6ff7eded8a5f71e3": { + "balance": "1999800000000000000000" + }, + "8f1952eed1c548d9ee9b97d0169a07933be69f63": { + "balance": "1000000000000000000000" + }, + "a421dbb89b3a07419084ad10c3c15dfe9b32d0c2": { + "balance": "20000000000000000000000" + }, + "554336ee4ea155f9f24f87bca9ca72e253e12cd2": { + "balance": "100000000000000000000" + }, + "ffc5fc4b7e8a0293ff39a3a0f7d60d2646d37a74": { + "balance": "2000000000000000000000" + }, + "ea2c197d26e98b0da83e1b72c787618c979d3db0": { + "balance": "19700000000000000000" + }, + "96aa573fed2f233410dbae5180145b23c31a02f0": { + "balance": "1730000000000000000000" + }, + "c23b2f921ce4a37a259ee4ad8b2158d15d664f59": { + "balance": "25403000000000000000" + }, + "d874b9dfae456a929ba3b1a27e572c9b2cecdfb3": { + "balance": "170000000000000000000" + }, + "bf8b8005d636a49664f74275ef42438acd65ac91": { + "balance": "200000000000000000000" + }, + "441a52001661fac718b2d7b351b7c6fb521a7afd": { + "balance": "400000000000000000000" + }, + "812a55c43caedc597218379000ce510d548836fd": { + "balance": "18200000000000000000" + }, + "5e90c85877198756b0366c0e17b28e52b446505a": { + "balance": "374288000000000000000" + }, + "da3017c150dd0dce7fcf881b0a48d0d1c756c4c7": { + "balance": "100014000000000000000" + }, + "6baf7a2a02ae78801e8904ad7ac05108fc56cff6": { + "balance": "1000000000000000000000" + }, + "177dae78bc0113d8d39c4402f2a641ae2a105ab8": { + "balance": "1818320000000000000000" + }, + "01b5b5bc5a117fa08b34ed1db9440608597ac548": { + "balance": "200000000000000000000" + }, + "aae732eda65988c3a00c7f472f351c463b1c968e": { + "balance": "2000000000000000000000" + }, + "d95342953c8a21e8b635eefac7819bea30f17047": { + "balance": "94160000000000000000000" + }, + "8d616b1eee77eef6f176e0698db3c0c141b2fc8f": { + "balance": "500000000000000000000" + }, + "12d20790b7d3dbd88c81a279b812039e8a603bd0": { + "balance": "1604400000000000000000" + }, + "3734cb187491ede713ae5b3b2d12284af46b8101": { + "balance": "3000000000000000000000" + }, + "dd967c4c5f8ae47e266fb416aad1964ee3e7e8c3": { + "balance": "7750000000000000000000" + }, + "3dcef19c868b15d34eda426ec7e04b18b6017002": { + "balance": "1999800000000000000000" + }, + "ce9d21c692cd3c01f2011f505f870036fa8f6cd2": { + "balance": "400000000000000000000" + }, + "d44f6ac3923b5fd731a4c45944ec4f7ec52a6ae4": { + "balance": "10000000000000000000000" + }, + "b424d68d9d0d00cec1938c854e15ffb880ba0170": { + "balance": "200000000000000000000" + }, + "1f2186ded23e0cf9521694e4e164593e690a9685": { + "balance": "300000000000000000000" + }, + "7f4b5e278578c046cceaf65730a0e068329ed5b6": { + "balance": "1880000000000000000000" + }, + "8c50aa2a9212bcde56418ae261f0b35e7a9dbb82": { + "balance": "400000000000000000000" + }, + "1953313e2ad746239cb2270f48af34d8bb9c4465": { + "balance": "2000000000000000000000" + }, + "a15025f595acdbf3110f77c5bf24477e6548f9e8": { + "balance": "2000000000000000000000" + }, + "53af32c22fef99803f178cf90b802fb571c61cb9": { + "balance": "3880000000000000000000" + }, + "d0a8abd80a199b54b08b65f01d209c27fef0115b": { + "balance": "6525979000000000000000" + }, + "2b68306ba7f8daaf73f4c644ef7d2743c0f26856": { + "balance": "864800000000000000000" + }, + "96924191b7df655b3319dc6d6137f481a73a0ff3": { + "balance": "4020000000000000000000" + }, + "6fa72015fa78696efd9a86174f7f1f21019286b1": { + "balance": "1337000000000000000000" + }, + "0b119df99c6b8de58a1e2c3f297a6744bf552277": { + "balance": "2000000000000000000000" + }, + "61733947fab820dbd351efd67855ea0e881373a0": { + "balance": "20000000000000000000" + }, + "8ae6f80b70e1f23c91fbd5a966b0e499d95df832": { + "balance": "197000000000000000000" + }, + "01a7d9fa7d0eb1185c67e54da83c2e75db69e39f": { + "balance": "7623900000000000000000" + }, + "9932ef1c85b75a9b2a80057d508734c51085becc": { + "balance": "50170000000000000000" + }, + "aefcfe88c826ccf131d54eb4ea9eb80e61e1ee25": { + "balance": "340000000000000000000" + }, + "c21fa6643a1f14c02996ad7144b75926e87ecb4b": { + "balance": "20000000000000000000000" + }, + "97d9e46a7604d7b5a4ea4ee61a42b3d2350fc3ed": { + "balance": "2000000000000000000000" + }, + "3cafaf5e62505615068af8eb22a13ad8a9e55070": { + "balance": "1999600000000000000000" + }, + "22f2dcff5ad78c3eb6850b5cb951127b659522e6": { + "balance": "13700000000000000000" + }, + "aaad1baade5af04e2b17439e935987bf8c2bb4b9": { + "balance": "2000000000000000000000" + }, + "298887bab57c5ba4f0615229d7525fa113b7ea89": { + "balance": "40000000000000000000" + }, + "7539333046deb1ef3c4daf50619993f444e1de68": { + "balance": "1182000000000000000000" + }, + "9752d14f5e1093f071711c1adbc4e3eb1e5c57f3": { + "balance": "2000000000000000000000" + }, + "ed641e06368fb0efaa1703e01fe48f4a685309eb": { + "balance": "200000000000000000000" + }, + "d0ee4d02cf24382c3090d3e99560de3678735cdf": { + "balance": "2400000000000000000000" + }, + "47e25df8822538a8596b28c637896b4d143c351d": { + "balance": "80500000000000000000000" + }, + "559706c332d20779c45f8a6d046a699159b74921": { + "balance": "380123000000000000000" + }, + "3a4da78dce05aeb87de9aead9185726da1926798": { + "balance": "200000000000000000000" + }, + "3041445a33ba158741160d9c344eb88e5c306f94": { + "balance": "60000000000000000000" + }, + "08d4311c9c1bbaf87fabe1a1d01463828d5d98ce": { + "balance": "90000000000000000000000" + }, + "6bd3e59f239fafe4776bb9bddd6bee83ba5d9d9f": { + "balance": "1000000000000000000000" + }, + "29eaae82761762f4d2db53a9c68b0f6b0b6d4e66": { + "balance": "2000000000000000000000" + }, + "0b7d339371e5be6727e6e331b5821fa24bdb9d5a": { + "balance": "857738000000000000000" + }, + "4714cfa4f46bd6bd70737d75878197e08f88e631": { + "balance": "11792000000000000000000" + }, + "ad92ca066edb7c711dfc5b166192d1edf8e77185": { + "balance": "36000000000000000000000" + }, + "f97b56ebd5b77abc9fbacbabd494b9d2c221cd03": { + "balance": "1970000000000000000000" + }, + "591bef3171d1c5957717a4e98d17eb142c214e56": { + "balance": "20000000000000000000000" + }, + "899b3c249f0c4b81df75d212004d3d6d952fd223": { + "balance": "2000000000000000000000" + }, + "a819d2ece122e028c8e8a04a064d02b9029b08b9": { + "balance": "1000000000000000000000" + }, + "e341642d40d2afce2e9107c67079ac7a2660086c": { + "balance": "400000000000000000000" + }, + "0329188f080657ab3a2afa522467178279832085": { + "balance": "216700000000000000000" + }, + "03317826d1f70aa4bddfa09be0c4105552d2358b": { + "balance": "38800000000000000000" + }, + "3ac9dc7a436ae98fd01c7a9621aa8e9d0b8b531d": { + "balance": "1790000000000000000000" + }, + "93c88e2d88621e30f58a9586bed4098999eb67dd": { + "balance": "31200000000000000000000" + }, + "cd1e66ed539dd92fc40bbaa1fa16de8c02c14d45": { + "balance": "230000000000000000000" + }, + "e6c81ffcecb47ecdc55c0b71e4855f3e5e97fc1e": { + "balance": "334250000000000000000" + }, + "50f8fa4bb9e2677c990a4ee8ce70dd1523251e4f": { + "balance": "26030000000000000000" + }, + "4f64a85e8e9a40498c0c75fceb0337fb49083e5e": { + "balance": "1000000000000000000000" + }, + "4b29437c97b4a844be71cca3b648d4ca0fdd9ba4": { + "balance": "150200000000000000000" + }, + "1eee6cbee4fe96ad615a9cf5857a647940df8c78": { + "balance": "19400000000000000000" + }, + "29f0edc60338e7112085a1d114da8c42ce8f55d6": { + "balance": "2958000000000000000000" + }, + "23b1c4917fbd93ee3d48389306957384a5496cbf": { + "balance": "4000086000000000000000" + }, + "1767525c5f5a22ed80e9d4d7710f0362d29efa33": { + "balance": "400000000000000000000" + }, + "3064899a963c4779cbf613cd6980846af1e6ec65": { + "balance": "6999908000000000000000" + }, + "68531f4dda808f5320767a03113428ca0ce2f389": { + "balance": "19400000000000000000" + }, + "1db9ac9a9eaeec0a523757050c71f47278c72d50": { + "balance": "1337000000000000000000" + }, + "7592c69d067b51b6cc639d1164d5578c60d2d244": { + "balance": "20000000000000000000" + }, + "cf3fbfa1fd32d7a6e0e6f8ef4eab57be34025c4c": { + "balance": "1063120000000000000000" + }, + "8efec058cc546157766a632775404a334aaada87": { + "balance": "1999000000000000000000" + }, + "faf5f0b7b6d558f5090d9ea1fb2d42259c586078": { + "balance": "6401000000000000000000" + }, + "19ecf2abf40c9e857b252fe1dbfd3d4c5d8f816e": { + "balance": "2000000000000000000000" + }, + "6e8a26689f7a2fdefd009cbaaa5310253450daba": { + "balance": "2049982000000000000000" + }, + "e2f40d358f5e3fe7463ec70480bd2ed398a7063b": { + "balance": "20000000000000000000" + }, + "fa19d6f7a50f4f079893d167bf14e21d0073d196": { + "balance": "530000000000000000000" + }, + "3e2ca0d234baf607ad466a1b85f4a6488ef00ae7": { + "balance": "89505000000000000000" + }, + "f8a49ca2390c1f6d5c0e62513b079571743f7cc6": { + "balance": "3000000000000000000000" + }, + "5d3f3b1f7130b0bb21a0fd32396239179a25657f": { + "balance": "62474000000000000000000" + }, + "f332c0f3e05a27d9126fd0b641a8c2d4060608fd": { + "balance": "5001041000000000000000" + }, + "e304a32f05a83762744a9542976ff9b723fa31ea": { + "balance": "1576256000000000000000" + }, + "f768f321fd6433d96b4f354d3cc1652c1732f57f": { + "balance": "10000000000000000000000" + }, + "147af46ae9ccd18bb35ca01b353b51990e49dce1": { + "balance": "4000000000000000000000" + }, + "21eae6feffa9fbf4cd874f4739ace530ccbe5937": { + "balance": "5000000000000000000000" + }, + "6994fb3231d7e41d491a9d68d1fa4cae2cc15960": { + "balance": "4000000000000000000000" + }, + "51126446ab3d8032557e8eba65597d75fadc815c": { + "balance": "322000000000000000000" + }, + "24daaaddf7b06bbcea9b80590085a88567682b4e": { + "balance": "319008000000000000000" + }, + "cd020f8edfcf524798a9b73a640334bbf72f80a5": { + "balance": "133700000000000000000" + }, + "56febf9e1003af15b1bd4907ec089a4a1b91d268": { + "balance": "200000000000000000000" + }, + "3c79c863c3d372b3ff0c6f452734a7f97042d706": { + "balance": "176000000000000000000" + }, + "e1203eb3a723e99c2220117ca6afeb66fa424f61": { + "balance": "9461996000000000000000" + }, + "18fb09188f27f1038e654031924f628a2106703d": { + "balance": "2000000000000000000000" + }, + "2eba0c6ee5a1145c1c573984963a605d880a7a20": { + "balance": "500000000000000000000" + }, + "4cefbe2398e47d52e78db4334c8b697675f193ae": { + "balance": "4011000000000000000000" + }, + "c02471e3fc2ea0532615a7571d493289c13c36ef": { + "balance": "20000000000000000000" + }, + "ba469aa5c386b19295d4a1b5473b540353390c85": { + "balance": "2000000000000000000000" + }, + "7b11673cc019626b290cbdce26046f7e6d141e21": { + "balance": "500000000000000000000" + }, + "26784ade91c8a83a8e39658c8d8277413ccc9954": { + "balance": "6000000000000000000000" + }, + "57d3df804f2beee6ef53ab94cb3ee9cf524a18d3": { + "balance": "393606000000000000000" + }, + "ccae0d3d852a7da3860f0636154c0a6ca31628d4": { + "balance": "106560000000000000000" + }, + "bfe3a1fc6e24c8f7b3250560991f93cba2cf8047": { + "balance": "80000000000000000000000" + }, + "724ce858857ec5481c86bd906e83a04882e5821d": { + "balance": "3000000000000000000000" + }, + "fb37cf6b4f81a9e222fba22e9bd24b5098b733cf": { + "balance": "38800000000000000000" + }, + "9b22a80d5c7b3374a05b446081f97d0a34079e7f": { + "balance": "3000000000000000000000" + }, + "0a29a8a4d5fd950075ffb34d77afeb2d823bd689": { + "balance": "200000000000000000000" + }, + "d01af9134faf5257174e8b79186f42ee354e642d": { + "balance": "1000000000000000000000" + }, + "7f1619988f3715e94ff1d253262dc5581db3de1c": { + "balance": "900000000000000000000" + }, + "6f137a71a6f197df2cbbf010dcbd3c444ef5c925": { + "balance": "2000000000000000000000" + }, + "11efb8a20451161b644a8ccebbc1d343a3bbcb52": { + "balance": "3200000000000000000000" + }, + "46504e6a215ac83bccf956befc82ab5a679371c8": { + "balance": "518898000000000000000" + }, + "b523fff9749871b35388438837f7e6e0dea9cb6b": { + "balance": "2000000000000000000000" + }, + "c5c6a4998a33feb764437a8be929a73ba34a0764": { + "balance": "50000000000000000000000" + }, + "3cd7f7c7c2353780cde081eeec45822b25f2860c": { + "balance": "200000000000000000000" + }, + "b3050beff9de33c80e1fa15225e28f2c413ae313": { + "balance": "700000000000000000000" + }, + "59268171b833e0aa13c54b52ccc0422e4fa03aeb": { + "balance": "3000000000000000000000" + }, + "7169724ee72271c534cad6420fb04ee644cb86fe": { + "balance": "410164000000000000000" + }, + "6e6d5bbbb9053b89d744a27316c2a7b8c09b547d": { + "balance": "909831000000000000000" + }, + "3f3f46b75cabe37bfacc8760281f4341ca7f463d": { + "balance": "602709000000000000000" + }, + "7a33834e8583733e2d52aead589bd1affb1dd256": { + "balance": "1000000000000000000000" + }, + "e94ded99dcb572b9bb1dcba32f6dee91e057984e": { + "balance": "394000000000000000000" + }, + "19336a236ded755872411f2e0491d83e3e00159e": { + "balance": "940000000000000000000" + }, + "63ac545c991243fa18aec41d4f6f598e555015dc": { + "balance": "600000000000000000000" + }, + "cfee05c69d1f29e7714684c88de5a16098e91399": { + "balance": "1970000000000000000000" + }, + "77be6b64d7c733a436adec5e14bf9ad7402b1b46": { + "balance": "1000000000000000000000" + }, + "233bdddd5da94852f4ade8d212885682d9076bc6": { + "balance": "4000000000000000000000" + }, + "952c57d2fb195107d4cd5ca300774119dfad2f78": { + "balance": "2000000000000000000000" + }, + "e237baa4dbc9926e32a3d85d1264402d54db012f": { + "balance": "2000000000000000000000" + }, + "aa91237e740d25a92f7fa146faa18ce56dc6e1f3": { + "balance": "925000000000000000000" + }, + "2339e9492870afea2537f389ac2f838302a33c06": { + "balance": "2000000000000000000000" + }, + "1d45586eb803ca2190650bf748a2b174312bb507": { + "balance": "1400000000000000000000" + }, + "c61446b754c24e3b1642d9e51765b4d3e46b34b6": { + "balance": "2000000000000000000000" + }, + "ac28b5edea05b76f8c5f97084541277c96696a4c": { + "balance": "1000000000000000000000" + }, + "1a1c9a26e0e02418a5cf687da75a275c622c9440": { + "balance": "5000000000000000000000" + }, + "299368609042a858d1ecdf1fc0ada5eaceca29cf": { + "balance": "2000000000000000000000" + }, + "095f5a51d06f6340d80b6d29ea2e88118ad730fe": { + "balance": "2000200000000000000000" + }, + "751a2ca34e7187c163d28e3618db28b13c196d26": { + "balance": "500000000000000000000" + }, + "75b0e9c942a4f0f6f86d3f95ff998022fa67963b": { + "balance": "1490000000000000000000" + }, + "d1b37f03cb107424e9c4dd575ccd4f4cee57e6cd": { + "balance": "2000000000000000000000" + }, + "7f993ddb7e02c282b898f6155f680ef5b9aff907": { + "balance": "20000000000000000000000" + }, + "a3d583a7b65b23f60b7905f3e4aa62aac87f4227": { + "balance": "1046779000000000000000" + }, + "526bb533b76e20c8ee1ebf123f1e9ff4148e40be": { + "balance": "197000000000000000000" + }, + "2160b4c02cac0a81de9108de434590a8bfe68735": { + "balance": "1970000000000000000000" + }, + "010007394b8b7565a1658af88ce463499135d6b7": { + "balance": "100000000000000000000" + }, + "64457fa33b0832506c4f7d1180dce48f46f3e0ff": { + "balance": "2000000000000000000000" + }, + "b51e558eb5512fbcfa81f8d0bd938c79ebb5242b": { + "balance": "715000000000000000000" + }, + "94f13f9f0836a3ee2437a84922d2984dc0f7d53b": { + "balance": "2999916000000000000000" + }, + "6bd457ade051795df3f2465c3839aed3c5dee978": { + "balance": "999925000000000000000" + }, + "f3dbcf135acb9dee1a489c593c024f03c2bbaece": { + "balance": "2000000000000000000000" + }, + "61b902c5a673885826820d1fe14549e4865fbdc2": { + "balance": "334703000000000000000" + }, + "2acc9c1a32240b4d5b2f777a2ea052b42fc1271c": { + "balance": "41764000000000000000000" + }, + "6ddfef639155daab0a5cb4953aa8c5afaa880453": { + "balance": "1820000000000000000000" + }, + "96ff6f509968f36cb42cba48db32f21f5676abf8": { + "balance": "1970000000000000000000" + }, + "b4c8170f7b2ab536d1d9a25bdd203ae1288dc3d5": { + "balance": "200000000000000000000" + }, + "78d4f8c71c1e68a69a98f52fcb45da8af56ea1a0": { + "balance": "2000000000000000000000" + }, + "dec99e972fca7177508c8e1a47ac22d768acab7c": { + "balance": "2000000000000000000000" + }, + "a07aa16d74aee8a9a3288d52db1551d593883297": { + "balance": "600000000000000000000" + }, + "cf1169041c1745e45b172435a2fc99b49ace2b00": { + "balance": "31960000000000000000" + }, + "526cb09ce3ada3672eec1deb46205be89a4b563e": { + "balance": "2468000000000000000000" + }, + "ee6959de2b67967b71948c891ab00d8c8f38c7dc": { + "balance": "118200000000000000000" + }, + "ca7ba3ff536c7e5f0e153800bd383db8312998e0": { + "balance": "169600000000000000000" + }, + "1ed06ee51662a86c634588fb62dc43c8f27e7c17": { + "balance": "200000000000000000000" + }, + "730447f97ce9b25f22ba1afb36df27f9586beb9b": { + "balance": "820000000000000000000" + }, + "ae5c9bdad3c5c8a1220444aea5c229c1839f1d64": { + "balance": "477500000000000000000" + }, + "a38306cb70baa8e49186bd68aa70a83d242f2907": { + "balance": "2000000000000000000000" + }, + "71213fca313404204ecba87197741aa9dfe96338": { + "balance": "60000000000000000000" + }, + "10e390ad2ba33d82b37388d09c4544c6b0225de5": { + "balance": "200000000000000000000" + }, + "3b6e814f770748a7c3997806347605480a3fd509": { + "balance": "2000000000000000000000" + }, + "fd452c3969ece3801c542020f1cdcaa1c71ed23d": { + "balance": "100000000000000000000000" + }, + "e742b1e6069a8ffc3c4767235defb0d49cbed222": { + "balance": "800000000000000000000" + }, + "d7225738dcf3578438f8e7c8b3837e42e04a262f": { + "balance": "445860000000000000000" + }, + "cd0b0257e783a3d2c2e3ba9d6e79b75ef98024d4": { + "balance": "2945500000000000000000" + }, + "e80e7fef18a5db15b01473f3ad6b78b2a2f8acd9": { + "balance": "500000000000000000000" + }, + "261575e9cf59c8226fa7aaf91de86fb70f5ac3ae": { + "balance": "300022000000000000000" + }, + "7e71171f2949fa0c3ac254254b1f0440e5e6a038": { + "balance": "40000000000000000000" + }, + "96ea6ac89a2bac95347b51dba63d8bd5ebdedce1": { + "balance": "2000000000000000000000" + }, + "e6ec5cf0c49b9c317e1e706315ef9eb7c0bf11a7": { + "balance": "17200000000000000000000" + }, + "2b99b42e4f42619ee36baa7e4af2d65eacfcba35": { + "balance": "40000000000000000000000" + }, + "c6e4cc0c7283fc1c85bc4813effaaf72b49823c0": { + "balance": "276926000000000000000" + }, + "dbc1ce0e49b1a705d22e2037aec878ee0d75c703": { + "balance": "250000000000000000000" + }, + "806f44bdeb688037015e84ff218049e382332a33": { + "balance": "1999000000000000000000" + }, + "1a3a330e4fcb69dbef5e6901783bf50fd1c15342": { + "balance": "4200000000000000000000" + }, + "d2a84f75675c62d80c88756c428eee2bcb185421": { + "balance": "1200000000000000000000" + }, + "c593b546b7698710a205ad468b2c13152219a342": { + "balance": "1550000000000000000000" + }, + "3f627a769e6a950eb87017a7cd9ca20871136831": { + "balance": "13790000000000000000000" + }, + "f2d5763ce073127e2cedde6faba786c73ca94141": { + "balance": "7900000000000000000000" + }, + "162110f29eac5f7d02b543d8dcd5bb59a5e33b73": { + "balance": "2000000000000000000000" + }, + "59473cd300fffae240f5785626c65dfec792b9af": { + "balance": "20000000000000000000" + }, + "4dcd11815818ae29b85d01367349a8a7fb12d06b": { + "balance": "7900000000000000000000" + }, + "9329ffdc268babde8874b366406c81445b9b2d35": { + "balance": "422415000000000000000" + }, + "0ab4281ebb318590abb89a81df07fa3af904258a": { + "balance": "500000000000000000000" + }, + "875061ee12e820041a01942cb0e65bb427b00060": { + "balance": "2800000000000000000000" + }, + "c9b698e898d20d4d4f408e4e4d061922aa856307": { + "balance": "40000000000000000000" + }, + "ca49a5f58adbefae23ee59eea241cf0482622eaa": { + "balance": "1430000000000000000000" + }, + "196e85df7e732b4a8f0ed03623f4db9db0b8fa31": { + "balance": "21165000000000000000" + }, + "4c760cd9e195ee4f2d6bce2500ff96da7c43ee91": { + "balance": "60000000000000000000000" + }, + "024a098ae702bef5406c9c22b78bd4eb2cc7a293": { + "balance": "4000000000000000000000" + }, + "9d81aea69aed6ad07089d61445348c17f34bfc5b": { + "balance": "300000000000000000000" + }, + "76ab87dd5a05ad839a4e2fc8c85aa6ba05641730": { + "balance": "2000000000000000000000" + }, + "c6e2f5af979a03fd723a1b6efa728318cf9c1800": { + "balance": "668500000000000000000" + }, + "5db69fe93e6fb6fbd450966b97238b110ad8279a": { + "balance": "40000000000000000000000" + }, + "a4259f8345f7e3a8b72b0fec2cf75e321fda4dc2": { + "balance": "1910000000000000000000" + }, + "095030e4b82692dcf8b8d0912494b9b378ec9328": { + "balance": "1340000000000000000000" + }, + "4b470f7ba030bc7cfcf338d4bf0432a91e2ea5ff": { + "balance": "2000000000000000000000" + }, + "99c9f93e45fe3c1418c353e4c5ac3894eef8121e": { + "balance": "101870000000000000000" + }, + "ffac3db879a6c7158e8dec603b407463ba0d31cf": { + "balance": "1970000000000000000000" + }, + "ac8e87ddda5e78fcbcb9fa7fc3ce038f9f7d2e34": { + "balance": "2000000000000000000000" + }, + "7a0589b143a8e5e107c9ac66a9f9f8597ab3e7ab": { + "balance": "1510990000000000000000" + }, + "b7d581fe0af1ec383f3b3c416783f385146a7612": { + "balance": "20000000000000000000000" + }, + "bb3fc0a29c034d710812dcc775c8cab9d28d6975": { + "balance": "1066806000000000000000" + }, + "2c603ff0fe93616c43573ef279bfea40888d6ae7": { + "balance": "4740000000000000000000" + }, + "15f2b7b16432ee50a5f55b41232f6334ed58bdc0": { + "balance": "400000000000000000000" + }, + "7f3d7203c8a447f7bf36d88ae9b6062a5eee78ae": { + "balance": "6000000000000000000000" + }, + "f067e1f1d683556a4cc4fd0c0313239f32c4cfd8": { + "balance": "1000000000000000000000" + }, + "52738c90d860e04cb12f498d96fdb5bf36fc340e": { + "balance": "30000000000000000000" + }, + "45781bbe7714a1c8f73b1c747921df4f84278b70": { + "balance": "2000000000000000000000" + }, + "4a97e8fcf4635ea7fc5e96ee51752ec388716b60": { + "balance": "546000000000000000000" + }, + "54939ff08921b467cf2946751d856378296c63ed": { + "balance": "1000000000000000000000" + }, + "6485470e61db110aebdbafd536769e3c599cc908": { + "balance": "600000000000000000000" + }, + "e20d1bcb71286dc7128a9fc7c6ed7f733892eef5": { + "balance": "1003400000000000000000" + }, + "d6eea898d4ae2b718027a19ce9a5eb7300abe3ca": { + "balance": "27475000000000000000" + }, + "014974a1f46bf204944a853111e52f1602617def": { + "balance": "2000000000000000000000" + }, + "6aa5732f3b86fb8c81efbe6b5b47b563730b06c8": { + "balance": "1000000000000000000000" + }, + "6107d71dd6d0eefb11d4c916404cb98c753e117d": { + "balance": "2000000000000000000000" + }, + "dd7bcda65924aaa49b80984ae173750258b92847": { + "balance": "10000000000000000000000" + }, + "4e7b54474d01fefd388dfcd53b9f662624418a05": { + "balance": "8000000000000000000000" + }, + "24fc73d20793098e09ddab5798506224fa1e1850": { + "balance": "200000000000000000000" + }, + "2b8488bd2d3c197a3d26151815b5a798d27168dc": { + "balance": "6680000000000000000000" + }, + "949131f28943925cfc97d41e0cea0b262973a730": { + "balance": "2800000000000000000000" + }, + "60b8d6b73b79534fb08bb8cbcefac7f393c57bfe": { + "balance": "1760000000000000000000" + }, + "d6acc220ba2e51dfcf21d443361eea765cbd35d8": { + "balance": "20000000000000000000" + }, + "c4c6cb723dd7afa7eb535615e53f3cef14f18118": { + "balance": "1999999000000000000000" + }, + "4c9a862ad115d6c8274ed0b944bdd6a5500510a7": { + "balance": "100000000000000000000" + }, + "85732c065cbd64119941aed430ac59670b6c51c4": { + "balance": "731345000000000000000" + }, + "0126e12ebc17035f35c0e9d11dd148393c405d7a": { + "balance": "1999600000000000000000" + }, + "472048cc609aeb242165eaaa8705850cf3125de0": { + "balance": "1000000000000000000000" + }, + "d2edd1ddd6d86dc005baeb541d22b640d5c7cae5": { + "balance": "20000000000000000000" + }, + "4549b15979255f7e65e99b0d5604db98dfcac8bf": { + "balance": "4000000000000000000000" + }, + "c6c7c191379897dd9c9d9a33839c4a5f62c0890d": { + "balance": "4000085000000000000000" + }, + "d367009ab658263b62c2333a1c9e4140498e1389": { + "balance": "2000000000000000000000" + }, + "143f5f1658d9e578f4f3d95f80c0b1bd3933cbda": { + "balance": "1490000000000000000000" + }, + "1a09fdc2c7a20e23574b97c69e93deba67d37220": { + "balance": "1998000000000000000000" + }, + "ac8b509aefea1dbfaf2bb33500d6570b6fd96d51": { + "balance": "1820000000000000000000" + }, + "16ffac84032940f0121a09668b858a7e79ffa3bb": { + "balance": "3879210000000000000000" + }, + "f338459f32a159b23db30ac335769ab2351aa63c": { + "balance": "30000000000000000000000" + }, + "d82251456dc1380f8f5692f962828640ab9f2a03": { + "balance": "4879980000000000000000" + }, + "47f4696bd462b20da09fb83ed2039818d77625b3": { + "balance": "149000000000000000000" + }, + "3dde8b15b3ccbaa5780112c3d674f313bba68026": { + "balance": "1773000000000000000000" + }, + "f70d637a845c06db6cdc91e6371ce7c4388a628e": { + "balance": "20000000000000000000" + }, + "68295e8ea5afd9093fc0a465d157922b5d2ae234": { + "balance": "19982000000000000000" + }, + "614e8bef3dd2c59b59a4145674401018351884ea": { + "balance": "20000000000000000000" + }, + "4737d042dc6ae73ec73ae2517acea2fdd96487c5": { + "balance": "1000000000000000000000" + }, + "cec6fc65853f9cce5f8e844676362e1579015f02": { + "balance": "2000000000000000000000" + }, + "ae47e2609cfafe369d66d415d939de05081a9872": { + "balance": "27060000000000000000000" + }, + "09a928d528ec1b3e25ffc83e218c1e0afe8928c7": { + "balance": "18200000000000000000" + }, + "9b444fd337e5d75293adcfff70e1ea01db023222": { + "balance": "100000000000000000000" + }, + "168bdec818eafc6d2992e5ef54aa0e1601e3c561": { + "balance": "1000110000000000000000" + }, + "353dbec42f92b50f975129b93c4c997375f09073": { + "balance": "1999000000000000000000" + }, + "6fcc2c732bdd934af6ccd16846fb26ef89b2aa9b": { + "balance": "10001242000000000000000" + }, + "6f2576da4de283bbe8e3ee69ddd66e5e711db3f5": { + "balance": "1260800000000000000000" + }, + "3a3dd104cd7eb04f21932fd433ea7affd39369f5": { + "balance": "357500000000000000000" + }, + "d44f4ac5fad76bdc1537a3b3af6472319b410d9d": { + "balance": "1600000000000000000000" + }, + "3d9d6be57ff83e065985664f12564483f2e600b2": { + "balance": "2041600000000000000000" + }, + "88f1045f19f2d3191816b1df18bb6e1435ad1b38": { + "balance": "240000000000000000000" + }, + "ddab75fb2ff9fecb88f89476688e2b00e367ebf9": { + "balance": "19400000000000000000000" + }, + "092e815558402d67f90d6bfe6da0b2fffa91455a": { + "balance": "60000000000000000000" + }, + "a7024cfd742c1ec13c01fea18d3042e65f1d5dee": { + "balance": "11272229000000000000000" + }, + "7f46bb25460dd7dae4211ca7f15ad312fc7dc75c": { + "balance": "6685000000000000000000" + }, + "93f18cd2526040761488c513174d1e7963768b2c": { + "balance": "2416500000000000000000" + }, + "352f25babf4a690673e35195efa8f79d05848aad": { + "balance": "66800000000000000000000" + }, + "f7b151cc5e571c17c76539dbe9964cbb6fe5de79": { + "balance": "2148000000000000000000" + }, + "ff3eee57c34d6dae970d8b311117c53586cd3502": { + "balance": "1700000000000000000000" + }, + "ae6f0c73fdd77c489727512174d9b50296611c4c": { + "balance": "6000000000000000000000" + }, + "7819b0458e314e2b53bfe00c38495fd4b9fdf8d6": { + "balance": "20000000000000000000" + }, + "7fdba031c78f9c096d62d05a369eeab0bccc55e5": { + "balance": "2800000000000000000000" + }, + "735e328666ed5637142b3306b77ccc5460e72c3d": { + "balance": "1968682000000000000000" + }, + "0bfbb6925dc75e52cf2684224bbe0550fea685d3": { + "balance": "1970000000000000000000" + }, + "6be16313643ebc91ff9bb1a2e116b854ea933a45": { + "balance": "500000000000000000000" + }, + "d6acffd0bfd99c382e7bd56ff0e6144a9e52b08e": { + "balance": "160000000000000000000" + }, + "276a006e3028ecd44cdb62ba0a77ce94ebd9f10f": { + "balance": "1800000000000000000000" + }, + "10711c3dda32317885f0a2fd8ae92e82069b0d0b": { + "balance": "4000000000000000000000" + }, + "43cb9652818c6f4d6796b0e89409306c79db6349": { + "balance": "2000000000000000000000" + }, + "7109dd011d15f3122d9d3a27588c10d77744508b": { + "balance": "2000000000000000000000" + }, + "3497dd66fd118071a78c2cb36e40b6651cc82598": { + "balance": "109600000000000000000" + }, + "9bf672d979b36652fc5282547a6a6bc212ae4368": { + "balance": "656000000000000000000" + }, + "eaed16eaf5daab5bf0295e5e077f59fb8255900b": { + "balance": "4000000000000000000000" + }, + "7ac58f6ffc4f8107ae6e30378e4e9f99c57fbb24": { + "balance": "40000000000000000000" + }, + "45a570dcc2090c86a6b3ea29a60863dde41f13b5": { + "balance": "232500000000000000000" + }, + "433a3b68e56b0df1862b90586bbd39c840ff1936": { + "balance": "2000000000000000000000" + }, + "e8eaf12944092dc3599b3953fa7cb1c9761cc246": { + "balance": "1800000000000000000000" + }, + "ec11362cec810985d0ebbd7b73451444985b369f": { + "balance": "30000047000000000000000" + }, + "78e83f80b3678c7a0a4e3e8c84dccde064426277": { + "balance": "1790000000000000000000" + }, + "0cc67f8273e1bae0867fd42e8b8193d72679dbf8": { + "balance": "500000000000000000000" + }, + "c70d856d621ec145303c0a6400cd17bbd6f5eaf7": { + "balance": "20000000000000000000" + }, + "f468906e7edf664ab0d8be3d83eb7ab3f7ffdc78": { + "balance": "1700000000000000000000" + }, + "3c286cfb30146e5fd790c2c8541552578de334d8": { + "balance": "10203000000000000000000" + }, + "c401c427cccff10decb864202f36f5808322a0a8": { + "balance": "3329300000000000000000" + }, + "afd019ff36a09155346b69974815a1c912c90aa4": { + "balance": "2000000000000000000000" + }, + "96fe59c3dbb3aa7cc8cb62480c65e56e6204a7e2": { + "balance": "20000000000000000000000" + }, + "a47779d8bc1c7bce0f011ccb39ef68b854f8de8f": { + "balance": "2000000000000000000000" + }, + "58c650ced40bb65641b8e8a924a039def46854df": { + "balance": "18500000000000000000" + }, + "86f4f40ad984fbb80933ae626e0e42f9333fdd41": { + "balance": "1000000000000000000000" + }, + "b22d5055d9623135961e6abd273c90deea16a3e7": { + "balance": "1400000000000000000000" + }, + "ee3564f5f1ba0f94ec7bac164bddbf31c6888b55": { + "balance": "100000000000000000000" + }, + "cf26b47bd034bc508e6c4bcfd6c7d30034925761": { + "balance": "1800000000000000000000" + }, + "e87dbac636a37721df54b08a32ef4959b5e4ff82": { + "balance": "2000000000000000000000" + }, + "3bf86ed8a3153ec933786a02ac090301855e576b": { + "balance": "450000000000000000000000" + }, + "cfd2728dfb8bdbf3bf73598a6e13eaf43052ea2b": { + "balance": "170000000000000000000" + }, + "85b16f0b8b34dff3804f69e2168a4f7b24d1042b": { + "balance": "317000000000000000000" + }, + "84db1459bb00812ea67ecb3dc189b72187d9c501": { + "balance": "148851000000000000000" + }, + "8c3a9ee71f729f236cba3867b4d79d8ceee25dbc": { + "balance": "100000000000000000000" + }, + "e677c31fd9cb720075dca49f1abccd59ec33f734": { + "balance": "7800000000000000000000" + }, + "8889448316ccf14ed86df8e2f478dc63c4338340": { + "balance": "15200000000000000000" + }, + "b279c7d355c2880392aad1aa21ee867c3b3507df": { + "balance": "1261000000000000000000" + }, + "12b5e28945bb2969f9c64c63cc05b6f1f8d6f4d5": { + "balance": "7722162000000000000000" + }, + "8d2303341e1e1eb5e8189bde03f73a60a2a54861": { + "balance": "100000000000000000000" + }, + "94d81074db5ae197d2bb1373ab80a87d121c4bd3": { + "balance": "9400000000000000000000" + }, + "752c9febf42f66c4787bfa7eb17cf5333bba5070": { + "balance": "1966448000000000000000" + }, + "16816aac0ede0d2d3cd442da79e063880f0f1d67": { + "balance": "2000000000000000000000" + }, + "daac91c1e859d5e57ed3084b50200f9766e2c52b": { + "balance": "400000000000000000000" + }, + "32c2fde2b6aabb80e5aea2b949a217f3cb092283": { + "balance": "5614827000000000000000" + }, + "cdab46a5902080646fbf954204204ae88404822b": { + "balance": "544942000000000000000" + }, + "fdf42343019b0b0c6bf260b173afab7e45b9d621": { + "balance": "1999944000000000000000" + }, + "791f6040b4e3e50dcf3553f182cd97a90630b75d": { + "balance": "4000000000000000000000" + }, + "4b762166dd1118e84369f804c75f9cd657bf730c": { + "balance": "500000000000000000000" + }, + "a76d3f156251b72c0ccf4b47a3393cbd6f49a9c5": { + "balance": "1337000000000000000000" + }, + "c5eb42295e9cadeaf2af12dede8a8d53c579c469": { + "balance": "3820000000000000000000" + }, + "db9371b30c4c844e59e03e924be606a938d1d310": { + "balance": "2000000000000000000000" + }, + "2cd39334ac7eac797257abe3736195f5b4b5ce0f": { + "balance": "99964000000000000000" + }, + "ad44357e017e244f476931c7b8189efee80a5d0a": { + "balance": "300000000000000000000" + }, + "4ca7b717d9bc8793b04e051a8d23e1640f5ba5e3": { + "balance": "1248980000000000000000" + }, + "73e4a2b60cf48e8baf2b777e175a5b1e4d0c2d8f": { + "balance": "100000000000000000000" + }, + "5a1d2d2d1d520304b6208849570437eb3091bb9f": { + "balance": "1970000000000000000000" + }, + "53047dc8ac9083d90672e8b3473c100ccd278323": { + "balance": "40000000000000000000" + }, + "26fe174cbf526650e0cd009bd6126502ce8e684d": { + "balance": "11640000000000000000000" + }, + "e2df23f6ea04becf4ab701748dc0963184555cdb": { + "balance": "2000000000000000000000" + }, + "c1170dbaadb3dee6198ea544baec93251860fda5": { + "balance": "1200000000000000000000" + }, + "8bbeacfc29cfe93402db3c41d99ab759662e73ec": { + "balance": "2000000000000000000000" + }, + "165305b787322e25dc6ad0cefe6c6f334678d569": { + "balance": "2000000000000000000000" + }, + "095457f8ef8e2bdc362196b9a9125da09c67e3ab": { + "balance": "200000000000000000000" + }, + "702802f36d00250fab53adbcd696f0176f638a49": { + "balance": "2000000000000000000000" + }, + "489334c2b695c8ee0794bd864217fb9fd8f8b135": { + "balance": "18200000000000000000" + }, + "fa8cf4e627698c5d5788abb7880417e750231399": { + "balance": "4244640000000000000000" + }, + "3329eb3baf4345d600ced40e6e9975656f113742": { + "balance": "4999711000000000000000" + }, + "b4dd5499daeb2507fb2de12297731d4c72b16bb0": { + "balance": "20000000000000000000" + }, + "88c2516a7cdb09a6276d7297d30f5a4db1e84b86": { + "balance": "4000000000000000000000" + }, + "612ced8dc0dc9e899ee46f7962333315f3f55e44": { + "balance": "338830000000000000000" + }, + "d71e43a45177ad51cbe0f72184a5cb503917285a": { + "balance": "200000000000000000000" + }, + "2fb566c94bbba4e3cb67cdda7d5fad7131539102": { + "balance": "2000000000000000000000" + }, + "03be5b4629aefbbcab9de26d39576cb7f691d764": { + "balance": "200550000000000000000" + }, + "025367960304beee34591118e9ac2d1358d8021a": { + "balance": "2000000000000000000000" + }, + "a5d5b8b62d002def92413710d13b6ff8d4fc7dd3": { + "balance": "400000000000000000000" + }, + "df3b72c5bd71d4814e88a62321a93d4011e3578b": { + "balance": "4000000000000000000000" + }, + "3588895ac9fbafec012092dc05c0c302d90740fa": { + "balance": "3000000000000000000000" + }, + "6021e85a8814fce1e82a41abd1d3b2dad2faefe0": { + "balance": "2000000000000000000000" + }, + "17ee9f54d4ddc84d670eff11e54a659fd72f4455": { + "balance": "16000000000000000000000" + }, + "873c6f70efb6b1d0f2bbc57eebcd70617c6ce662": { + "balance": "1013478000000000000000" + }, + "1fcc7ce6a8485895a3199e16481f72e1f762defe": { + "balance": "1000000000000000000000" + }, + "d0a7209b80cf60db62f57d0a5d7d521a69606655": { + "balance": "160000000000000000000" + }, + "a514d00edd7108a6be839a638db2415418174196": { + "balance": "30000000000000000000000" + }, + "046377f864b0143f282174a892a73d3ec8ec6132": { + "balance": "191000000000000000000" + }, + "c126573d87b0175a5295f1dd07c575cf8cfa15f2": { + "balance": "10000000000000000000000" + }, + "0e123d7da6d1e6fac2dcadd27029240bb39052fe": { + "balance": "1000000000000000000000" + }, + "ad5a8d3c6478b69f657db3837a2575ef8e1df931": { + "balance": "36990000000000000000" + }, + "db882eacedd0eff263511b312adbbc59c6b8b25b": { + "balance": "9100000000000000000000" + }, + "0b43bd2391025581d8956ce42a072579cbbfcb14": { + "balance": "18800000000000000000" + }, + "affea0473722cb7f0e0e86b9e11883bf428d8d54": { + "balance": "1940000000000000000000" + }, + "e32b1c4725a1875449e98f970eb3e54062d15800": { + "balance": "200000000000000000000" + }, + "98f4af3af0aede5fafdc42a081ecc1f89e3ccf20": { + "balance": "9400000000000000000000" + }, + "3b4768fd71e2db2cbe7fa050483c27b4eb931df3": { + "balance": "2000000000000000000000" + }, + "d5f7c41e07729dfa6dfc64c4423160a22c609fd3": { + "balance": "1790000000000000000000" + }, + "d944c8a69ff2ca1249690c1229c7192f36251062": { + "balance": "1970000000000000000000" + }, + "5ae64e853ba0a51282cb8db52e41615e7c9f733f": { + "balance": "2000000000000000000000" + }, + "b13f93af30e8d7667381b2b95bc1a699d5e3e129": { + "balance": "420000000000000000000" + }, + "8a20e5b5cee7cd1f5515bace3bf4f77ffde5cc07": { + "balance": "80000000000000000000" + }, + "2448596f91c09baa30bc96106a2d37b5705e5d28": { + "balance": "2000000000000000000000" + }, + "ccca24d8c56d6e2c07db086ec07e585be267ac8d": { + "balance": "200000000000000000000" + }, + "f67bb8e2118bbcd59027666eedf6943ec9f880a5": { + "balance": "4000000000000000000000" + }, + "7ae659eb3bc46852fa86fac4e21c768d50388945": { + "balance": "286000000000000000000" + }, + "467e0ed54f3b76ae0636176e07420815a021736e": { + "balance": "2000000000000000000000" + }, + "a46cd237b63eea438c8e3b6585f679e4860832ac": { + "balance": "1000000000000000000000" + }, + "6b760d4877e6a627c1c967bee451a8507ddddbab": { + "balance": "910000000000000000000" + }, + "593044670faeff00a55b5ae051eb7be870b11694": { + "balance": "133700000000000000000" + }, + "533c06928f19d0a956cc28866bf6c8d8f4191a94": { + "balance": "292320000000000000000" + }, + "262dc1364ccf6df85c43268ee182554dae692e29": { + "balance": "4927600000000000000000" + }, + "e4368bc1420b35efda95fafbc73090521916aa34": { + "balance": "4000000000000000000000" + }, + "feb92d30bf01ff9a1901666c5573532bfa07eeec": { + "balance": "1000000000000000000000" + }, + "ee25b9a7032679b113588ed52c137d1a053a1e94": { + "balance": "199820000000000000000" + }, + "20134cbff88bfadc466b52eceaa79857891d831e": { + "balance": "1000000000000000000000" + }, + "07b1a306cb4312df66482c2cae72d1e061400fcd": { + "balance": "20000000000000000000000" + }, + "e791d585b89936b25d298f9d35f9f9edc25a2932": { + "balance": "2000000000000000000000" + }, + "2e6933543d4f2cc00b5350bd8068ba9243d6beb0": { + "balance": "2000000000000000000000" + }, + "dae0d33eaa341569fa9ff5982684854a4a328a6e": { + "balance": "1000000000000000000000" + }, + "125cc5e4d56b2bcc2ee1c709fb9e68fb177440bd": { + "balance": "2000000000000000000000" + }, + "ec99e95dece46ffffb175eb6400fbebb08ee9b95": { + "balance": "100000000000000000000" + }, + "c538a0ff282aaa5f4b75cfb62c70037ee67d4fb5": { + "balance": "2000000000000000000000" + }, + "60676d1fa21fca052297e24bf96389c5b12a70d7": { + "balance": "241500000000000000000" + }, + "4b3dfbdb454be5279a3b8addfd0ed1cd37a9420d": { + "balance": "2000000000000000000000" + }, + "cdb597299030183f6e2d238533f4642aa58754b6": { + "balance": "400000000000000000000" + }, + "1ef2dcbfe0a500411d956eb8c8939c3d6cfe669d": { + "balance": "776000000000000000000" + }, + "a7247c53d059eb7c9310f628d7fc6c6a0a773f08": { + "balance": "500000000000000000000" + }, + "9799ca21dbcf69bfa1b3f72bac51b9e3ca587cf9": { + "balance": "1700000000000000000000" + }, + "ddf95c1e99ce2f9f5698057c19d5c94027ee4a6e": { + "balance": "6000000000000000000000" + }, + "83563bc364ed81a0c6da3b56ff49bbf267827a9c": { + "balance": "17332000000000000000000" + }, + "a192698007cc11aa603d221d5feea076bcf7c30d": { + "balance": "2000000000000000000000" + }, + "0134ff38155fabae94fd35c4ffe1d79de7ef9c59": { + "balance": "985000000000000000000" + }, + "80977316944e5942e79b0e3abad38da746086519": { + "balance": "38800000000000000000" + }, + "193d37ed347d1c2f4e35350d9a444bc57ca4db43": { + "balance": "60000000000000000000" + }, + "009a6d7db326679b77c90391a7476d238f3ba33e": { + "balance": "200200000000000000000" + }, + "337b3bdf86d713dbd07b5dbfcc022b7a7b1946ae": { + "balance": "3980000000000000000000" + }, + "7de7fe419cc61f91f408d234cc80d5ca3d054d99": { + "balance": "20000000000000000000" + }, + "f47bb134da30a812d003af8dccb888f44bbf5724": { + "balance": "5190000000000000000000" + }, + "fd920f722682afb5af451b0544d4f41b3b9d5742": { + "balance": "2330200000000000000000" + }, + "0a917f3b5cb0b883047fd9b6593dbcd557f453b9": { + "balance": "1000000000000000000000" + }, + "ce9786d3712fa200e9f68537eeaa1a06a6f45a4b": { + "balance": "1790000000000000000000" + }, + "9ab98d6dbb1eaae16d45a04568541ad3d8fe06cc": { + "balance": "272451000000000000000" + }, + "0b7bb342f01bc9888e6a9af4a887cbf4c2dd2caf": { + "balance": "16000000000000000000000" + }, + "4c0b1515dfced7a13e13ee12c0f523ae504f032b": { + "balance": "50000000000000000000000" + }, + "ac2889b5966f0c7f9edb42895cb69d1c04f923a2": { + "balance": "5000000000000000000000" + }, + "d008513b27604a89ba1763b6f84ce688b346945b": { + "balance": "1000000000000000000000" + }, + "a4b09de6e713dc69546e76ef0acf40b94f0241e6": { + "balance": "322656000000000000000" + }, + "b153f828dd076d4a7c1c2574bb2dee1a44a318a8": { + "balance": "400000000000000000000" + }, + "02ade5db22f8b758ee1443626c64ec2f32aa0a15": { + "balance": "20000000000000000000000" + }, + "0a0650861f785ed8e4bf1005c450bbd06eb48fb6": { + "balance": "3066860000000000000000" + }, + "b75149e185f6e3927057739073a1822ae1cf0df2": { + "balance": "4000086000000000000000" + }, + "84cb7da0502df45cf561817bbd2362f451be02da": { + "balance": "1337000000000000000000" + }, + "c91bb562e42bd46130e2d3ae4652b6a4eb86bc0f": { + "balance": "540000000000000000000" + }, + "b234035f7544463ce1e22bc553064684c513cd51": { + "balance": "249750000000000000000" + }, + "e5e33800a1b2e96bde1031630a959aa007f26e51": { + "balance": "1337000000000000000000" + }, + "ae5ce3355a7ba9b332760c0950c2bc45a85fa9a0": { + "balance": "400000000000000000000" + }, + "e6f5eb649afb99599c414b27a9c9c855357fa878": { + "balance": "2674000000000000000000" + }, + "7010be2df57bd0ab9ae8196cd50ab0c521aba9f9": { + "balance": "1970000000000000000000" + }, + "ca4288014eddc5632f5facb5e38517a8f8bc5d98": { + "balance": "340000000000000000000" + }, + "2784903f1d7c1b5cd901f8875d14a79b3cbe2a56": { + "balance": "22388000000000000000000" + }, + "f8dce867f0a39c5bef9eeba609229efa02678b6c": { + "balance": "2000000000000000000000" + }, + "e020e86362b487752836a6de0bc02cd8d89a8b6a": { + "balance": "6000000000000000000000" + }, + "c4088c025f3e85013f5439fb3440a17301e544fe": { + "balance": "2325000000000000000000" + }, + "befb448c0c5f683fb67ee570baf0db5686599751": { + "balance": "1970000000000000000000" + }, + "2f187d5a704d5a338c5b2876a090dce964284e29": { + "balance": "4000000000000000000000" + }, + "ec0e18a01dc4dc5daae567c3fa4c7f8f9b590205": { + "balance": "315900000000000000000" + }, + "637f5869d6e4695f0eb9e27311c4878aff333380": { + "balance": "1969212000000000000000" + }, + "d1100dd00fe2ddf18163ad964d0b69f1f2e9658a": { + "balance": "5959598000000000000000" + }, + "17ef4acc1bf147e326749d10e677dcffd76f9e06": { + "balance": "39980000000000000000000" + }, + "200dfc0b71e359b2b465440a36a6cdc352773007": { + "balance": "1500000000000000000000" + }, + "efe0675da98a5dda70cd96196b87f4e726b43348": { + "balance": "1164000000000000000000" + }, + "d5bd5e8455c130169357c471e3e681b7996a7276": { + "balance": "841500000000000000000" + }, + "9c7b6dc5190fe2912963fcd579683ec7395116b0": { + "balance": "776000000000000000000" + }, + "b105dd3d987cffd813e9c8500a80a1ad257d56c6": { + "balance": "1999944000000000000000" + }, + "145250b06e4fa7cb2749422eb817bdda8b54de5f": { + "balance": "219000000000000000000" + }, + "d96db33b7b5a950c3efa2dc31b10ba10a532ef87": { + "balance": "2000000000000000000000" + }, + "af529bdb459cc185bee5a1c58bf7e8cce25c150d": { + "balance": "197000000000000000000" + }, + "185546e8768d506873818ac9751c1f12116a3bef": { + "balance": "200000000000000000000" + }, + "51d24bc3736f88dd63b7222026886630b6eb878d": { + "balance": "2000000000000000000000" + }, + "69af28b0746cac0da17084b9398c5e36bb3a0df2": { + "balance": "1004700000000000000000" + }, + "76f83ac3da30f7092628c7339f208bfc142cb1ee": { + "balance": "2842600000000000000000" + }, + "00f463e137dcf625fbf3bca39eca98d2b968cf7f": { + "balance": "5910000000000000000000" + }, + "2084fce505d97bebf1ad8c5ff6826fc645371fb2": { + "balance": "30000000000000000000" + }, + "53a714f99fa00fef758e23a2e746326dad247ca7": { + "balance": "1490000000000000000000" + }, + "0bf064428f83626722a7b5b26a9ab20421a7723e": { + "balance": "133700000000000000000" + }, + "ac6f68e837cf1961cb14ab47446da168a16dde89": { + "balance": "1337000000000000000000" + }, + "4b3c7388cc76da3d62d40067dabccd7ef0433d23": { + "balance": "100076000000000000000" + }, + "deb9a49a43873020f0759185e20bbb4cf381bb8f": { + "balance": "211628000000000000000" + }, + "5bf9f2226e5aeacf1d80ae0a59c6e38038bc8db5": { + "balance": "6000000000000000000000" + }, + "9d0e7d92fb305853d798263bf15e97c72bf9d7e0": { + "balance": "1000000000000000000000" + }, + "2b5c60e84535eeb4d580de127a12eb2677ccb392": { + "balance": "20000000000000000000000" + }, + "d8d65420c18c2327cc5af97425f857e4a9fd51b3": { + "balance": "1760000000000000000000" + }, + "30ec9392244a2108c987bc5cdde0ed9f837a817b": { + "balance": "1560562000000000000000" + }, + "56a1d60d40f57f308eebf087dee3b37f1e7c2cba": { + "balance": "1159600000000000000000" + }, + "a9a1cdc33bfd376f1c0d76fb6c84b6b4ac274d68": { + "balance": "5000000000000000000000" + }, + "a67f38819565423aa85f3e3ab61bc763cbab89dd": { + "balance": "2130000000000000000000" + }, + "62d5cc7117e18500ac2f9e3c26c86b0a94b0de15": { + "balance": "105000000000000000000" + }, + "4970d3acf72b5b1f32a7003cf102c64ee0547941": { + "balance": "140000000000000000000000" + }, + "76628150e2995b5b279fc83e0dd5f102a671dd1c": { + "balance": "40000000000000000000000" + }, + "3d8f39881b9edfe91227c33fa4cdd91e678544b0": { + "balance": "86111000000000000000" + }, + "ff0b7cb71da9d4c1ea6ecc28ebda504c63f82fd1": { + "balance": "1043000000000000000000" + }, + "8d795c5f4a5689ad62da961671f028065286d554": { + "balance": "2048000000000000000000" + }, + "be2346a27ff9b702044f500deff2e7ffe6824541": { + "balance": "20000000000000000000" + }, + "0dbd417c372b8b0d01bcd944706bd32e60ae28d1": { + "balance": "340000000000000000000" + }, + "467fbf41441600757fe15830c8cd5f4ffbbbd560": { + "balance": "10000000000000000000000" + }, + "090cd67b60e81d54e7b5f6078f3e021ba65b9a1e": { + "balance": "1000000000000000000000" + }, + "55a4cac0cb8b582d9fef38c5c9fff9bd53093d1f": { + "balance": "1970000000000000000000" + }, + "3b7b4f53c45655f3dc5f017edc23b16f9bc536fa": { + "balance": "100000000000000000000" + }, + "d508d39c70916f6abc4cc7f999f011f077105802": { + "balance": "100470000000000000000" + }, + "037dd056e7fdbd641db5b6bea2a8780a83fae180": { + "balance": "140000000000000000000" + }, + "660557bb43f4be3a1b8b85e7df7b3c5bcd548057": { + "balance": "6000000000000000000000" + }, + "02089361a3fe7451fb1f87f01a2d866653dc0b07": { + "balance": "39976000000000000000" + }, + "c4bec96308a20f90cab18399c493fd3d065abf45": { + "balance": "14000000000000000000000" + }, + "cca07bb794571d4acf041dad87f0d1ef3185b319": { + "balance": "2000000000000000000000" + }, + "f2d0e986d814ea13c8f466a0538c53dc922651f0": { + "balance": "1380000000000000000000" + }, + "662cfa038fab37a01745a364e1b98127c503746d": { + "balance": "3940000000000000000000" + }, + "3336c3ef6e8b50ee90e037b164b7a8ea5faac65d": { + "balance": "272712000000000000000" + }, + "30e33358fc21c85006e40f32357dc8895940aaf0": { + "balance": "1910000000000000000000" + }, + "41a9a404fc9f5bfee48ec265b12523338e29a8bf": { + "balance": "388000000000000000000" + }, + "6af235d2bbe050e6291615b71ca5829658810142": { + "balance": "3000000000000000000000" + }, + "fd5a63157f914fd398eab19c137dd9550bb7715c": { + "balance": "100000000000000000000" + }, + "8a4314fb61cd938fc33e15e816b113f2ac89a7fb": { + "balance": "432800000000000000000" + }, + "b216dc59e27c3d7279f5cd5bb2becfb2606e14d9": { + "balance": "400000000000000000000" + }, + "f5a5459fcdd5e5b273830df88eea4cb77ddadfb9": { + "balance": "74500000000000000000" + }, + "df31025f5649d2c6eea41ed3bdd3471a790f759a": { + "balance": "20000000000000000000" + }, + "721f9d17e5a0e74205947aeb9bc6a7938961038f": { + "balance": "51900000000000000000" + }, + "08d0864dc32f9acb36bf4ea447e8dd6726906a15": { + "balance": "2000200000000000000000" + }, + "54575c3114751e3c631971da6a2a02fd3ffbfcc8": { + "balance": "1940000000000000000000" + }, + "8f60895fbebbb5017fcbff3cdda397292bf25ba6": { + "balance": "429177000000000000000" + }, + "91fe8a4c6164df8fa606995d6ba7adcaf1c893ce": { + "balance": "17000000000000000000000" + }, + "889087f66ff284f8b5efbd29493b706733ab1447": { + "balance": "9850000000000000000000" + }, + "051633080d07a557adde319261b074997f14692d": { + "balance": "5800000000000000000000" + }, + "59a12df2e3ef857aceff9306b309f6a500f70134": { + "balance": "1000000000000000000000" + }, + "9f64a8e8dacf4ade30d10f4d59b0a3d5abfdbf74": { + "balance": "1000060000000000000000" + }, + "8846928d683289a2d11df8db7a9474988ef01348": { + "balance": "10000000000000000000000" + }, + "dff1b220de3d8e9ca4c1b5be34a799bcded4f61c": { + "balance": "385428000000000000000" + }, + "7e7c1e9a61a08a83984835c70ec31d34d3eaa87f": { + "balance": "191000000000000000000" + }, + "fe210b8f04dc6d4f76216acfcbd59ba83be9b630": { + "balance": "20000000000000000000" + }, + "dc8c2912f084a6d184aa73638513ccbc326e0102": { + "balance": "1295000000000000000000" + }, + "dddd7b9e6eab409b92263ac272da801b664f8a57": { + "balance": "500000000000000000000000" + }, + "86a5f8259ed5b09e188ce346ee92d34aa5dd93fa": { + "balance": "200000000000000000000" + }, + "dc1f1979615f082140b8bb78c67b27a1942713b1": { + "balance": "60000000000000000000" + }, + "ea66e7b84dcdbf36eea3e75b85382a75f1a15d96": { + "balance": "1729135000000000000000" + }, + "039e7a4ebc284e2ccd42b1bdd60bd6511c0f7706": { + "balance": "17300000000000000000" + }, + "36bfe1fa3b7b70c172eb042f6819a8972595413e": { + "balance": "1000000000000000000000" + }, + "039ef1ce52fe7963f166d5a275c4b1069fe3a832": { + "balance": "400008000000000000000" + }, + "f1df55dcc34a051012b575cb968bc9c458ea09c9": { + "balance": "4000000000000000000000" + }, + "168b5019b818691644835fe69bf229e17112d52c": { + "balance": "28000000000000000000000" + }, + "f60bd735543e6bfd2ea6f11bff627340bc035a23": { + "balance": "2000000000000000000000" + }, + "2cbb0c73df91b91740b6693b774a7d05177e8e58": { + "balance": "1850000000000000000000" + }, + "9ffcf5ef46d933a519d1d16c6ba3189b27496224": { + "balance": "1000000000000000000000" + }, + "0e11d77a8977fac30d268445e531149b31541a24": { + "balance": "2000000000000000000000" + }, + "dfb1626ef48a1d7d7552a5e0298f1fc23a3b482d": { + "balance": "1713860000000000000000" + }, + "cc943be1222cd1400a2399dd1b459445cf6d54a9": { + "balance": "12530000000000000000000" + }, + "b37c2b9f50637bece0ca959208aefee6463ba720": { + "balance": "400000000000000000000" + }, + "96b906ea729f4655afe3e57d35277c967dfa1577": { + "balance": "1000000000000000000000" + }, + "7995bd8ce2e0c67bf1c7a531d477bca1b2b97561": { + "balance": "5945100000000000000000" + }, + "96f820500b70f4a3e3239d619cff8f222075b135": { + "balance": "200000000000000000000" + }, + "ad3565d52b688added08168b2d3872d17d0a26ae": { + "balance": "100000000000000000000" + }, + "9e7c2050a227bbfd60937e268cea3e68fea8d1fe": { + "balance": "100000000000000000000" + }, + "7e59dc60be8b2fc19abd0a5782c52c28400bce97": { + "balance": "1000000000000000000000" + }, + "01ed5fba8d2eab673aec042d30e4e8a611d8c55a": { + "balance": "2000000000000000000000" + }, + "59a087b9351ca42f58f36e021927a22988284f38": { + "balance": "18500000000000000000" + }, + "2fe0023f5722650f3a8ac01009125e74e3f82e9b": { + "balance": "3000000000000000000000" + }, + "bd1803370bddb129d239fd16ea8526a6188ae58e": { + "balance": "500000000000000000000" + }, + "c70527d444c490e9fc3f5cc44e66eb4f306b380f": { + "balance": "4000000000000000000000" + }, + "0f206e1a1da7207ea518b112418baa8b06260328": { + "balance": "600000000000000000000" + }, + "6e1a046caf5b4a57f4fd4bc173622126b4e2fd86": { + "balance": "1790000000000000000000" + }, + "84008a72f8036f3feba542e35078c057f32a8825": { + "balance": "100000000000000000000" + }, + "246291165b59332df5f18ce5c98856fae95897d6": { + "balance": "1700000000000000000000" + }, + "7e99dfbe989d3ba529d19751b7f4317f8953a3e2": { + "balance": "400000000000000000000" + }, + "748c285ef1233fe4d31c8fb1378333721c12e27a": { + "balance": "2000000000000000000000" + }, + "3dd12e556a603736feba4a6fa8bd4ac45d662a04": { + "balance": "167450000000000000000000" + }, + "d0ae735d915e946866e1fea77e5ea466b5cadd16": { + "balance": "2000000000000000000000" + }, + "4f767bc8794aef9a0a38fea5c81f14694ff21a13": { + "balance": "512200000000000000000" + }, + "0e2f8e28a681f77c583bd0ecde16634bdd7e00cd": { + "balance": "95060000000000000000" + }, + "d74a6e8d6aab34ce85976814c1327bd6ea0784d2": { + "balance": "100000000000000000000000" + }, + "629be7ab126a5398edd6da9f18447e78c692a4fd": { + "balance": "2000000000000000000000" + }, + "2e46fcee6a3bb145b594a243a3913fce5dad6fba": { + "balance": "10000000000000000000000" + }, + "e39b11a8ab1ff5e22e5ae6517214f73c5b9b55dc": { + "balance": "2000000000000000000000" + }, + "119aa64d5b7d181dae9d3cb449955c89c1f963fa": { + "balance": "700000000000000000000" + }, + "ce079f51887774d8021cb3b575f58f18e9acf984": { + "balance": "180000000000000000000" + }, + "550c306f81ef5d9580c06cb1ab201b95c748a691": { + "balance": "665800000000000000000" + }, + "06dc7f18cee7edab5b795337b1df6a9e8bd8ae59": { + "balance": "400000000000000000000" + }, + "e21c778ef2a0d7f751ea8c074d1f812243863e4e": { + "balance": "5308559000000000000000" + }, + "45d4b54d37a8cf599821235f062fa9d170ede8a4": { + "balance": "324000000000000000000" + }, + "893a6c2eb8b40ab096b4f67e74a897b840746e86": { + "balance": "1730000000000000000000" + }, + "d44d81e18f46e2cfb5c1fcf5041bc8569767d100": { + "balance": "36381800000000000000000" + }, + "c5de1203d3cc2cea31c82ee2de5916880799eafd": { + "balance": "5000000000000000000000" + }, + "7f0f04fcf37a53a4e24ede6e93104e78be1d3c9e": { + "balance": "2000000000000000000000" + }, + "3ce1dc97fcd7b7c4d3a18a49d6f2a5c1b1a906d7": { + "balance": "200000000000000000000" + }, + "ac4ee9d502e7d2d2e99e59d8ca7d5f00c94b4dd6": { + "balance": "1000000000000000000000" + }, + "7640a37f8052981515bce078da93afa4789b5734": { + "balance": "2000000000000000000000" + }, + "76cac488111a4fd595f568ae3a858770fc915d5f": { + "balance": "200000000000000000000" + }, + "ff4a408f50e9e72146a28ce4fc8d90271f116e84": { + "balance": "1970000000000000000000" + }, + "249db29dbc19d1235da7298a04081c315742e9ac": { + "balance": "1801800000000000000000" + }, + "3a04572847d31e81f7765ca5bfc9d557159f3683": { + "balance": "133031000000000000000" + }, + "b6771b0bf3427f9ae7a93e7c2e61ee63941fdb08": { + "balance": "18800000000000000000000" + }, + "30c26a8e971baa1855d633ba703f028cc7873140": { + "balance": "10000000000000000000000" + }, + "167e3e3ae2003348459392f7dfce44af7c21ad59": { + "balance": "500000000000000000000" + }, + "43f16f1e75c3c06a9478e8c597a40a3cb0bf04cc": { + "balance": "2914000000000000000000" + }, + "056b1546894f9a85e203fb336db569b16c25e04f": { + "balance": "169397000000000000000" + }, + "70616e2892fa269705b2046b8fe3e72fa55816d3": { + "balance": "20000000000000000000000" + }, + "8f4d1d41693e462cf982fd81d0aa701d3a5374c9": { + "balance": "4000000000000000000000" + }, + "c518799a5925576213e21896e0539abb85b05ae3": { + "balance": "1000000000000000000000" + }, + "0e3a28c1dfafb0505bdce19fe025f506a6d01ceb": { + "balance": "2000000000000000000000" + }, + "e4a47e3933246c3fd62979a1ea19ffdf8c72ef37": { + "balance": "148273000000000000000" + }, + "d231929735132102471ba59007b6644cc0c1de3e": { + "balance": "1000090000000000000000" + }, + "555d8d3ce1798aca902754f164b8be2a02329c6c": { + "balance": "10000000000000000000000" + }, + "5ab1a5615348001c7c775dc75748669b8be4de14": { + "balance": "690200000000000000000" + }, + "2fee36a49ee50ecf716f1047915646779f8ba03f": { + "balance": "1056230000000000000000" + }, + "54db5e06b4815d31cb56a8719ba33af2d73e7252": { + "balance": "670000000000000000000" + }, + "7c8bb65a6fbb49bd413396a9d7e31053bbb37aa9": { + "balance": "6000000000000000000000" + }, + "c1384c6e717ebe4b23014e51f31c9df7e4e25b31": { + "balance": "500000000000000000000" + }, + "474158a1a9dc693c133f65e47b5c3ae2f773a86f": { + "balance": "200200000000000000000" + }, + "2934c0df7bbc172b6c186b0b72547ace8bf75454": { + "balance": "60000000000000000000" + }, + "6966063aa5de1db5c671f3dd699d5abe213ee902": { + "balance": "8000000000000000000000" + }, + "9225d46a5a80943924a39e5b84b96da0ac450581": { + "balance": "40000000000000000000000" + }, + "671bbca099ff899bab07ea1cf86965c3054c8960": { + "balance": "50000000000000000000" + }, + "f1f766b0e46d73fcd4d52e7a72e1b9190cc632b3": { + "balance": "8000000000000000000000" + }, + "ef0dc7dd7a53d612728bcbd2b27c19dd4d7d666f": { + "balance": "705668000000000000000" + }, + "38d2e9154964b41c8d50a7487d391e7ee2c3d3c2": { + "balance": "3500000000000000000000" + }, + "352a785f4a921632504ce5d015f83c49aa838d6d": { + "balance": "4314800000000000000000" + }, + "743de50026ca67c94df54f066260e1d14acc11ac": { + "balance": "2000000000000000000000" + }, + "b188078444027e386798a8ae68698919d5cc230d": { + "balance": "267400000000000000000" + }, + "53608105ce4b9e11f86bf497ffca3b78967b5f96": { + "balance": "20000000000000000000000" + }, + "3b159099075207c6807663b1f0f7eda54ac8cce3": { + "balance": "1969543000000000000000" + }, + "141a5e39ee2f680a600fbf6fa297de90f3225cdd": { + "balance": "10000000000000000000000" + }, + "44fff37be01a3888d3b8b8e18880a7ddefeeead3": { + "balance": "259145000000000000000" + }, + "c5a629a3962552cb8eded889636aafbd0c18ce65": { + "balance": "10000000000000000000000" + }, + "fdba5359f7ec3bc770ac49975d844ec9716256f1": { + "balance": "1000000000000000000000" + }, + "7c1df24a4f7fb2c7b472e0bb006cb27dcd164156": { + "balance": "1000000000000000000000" + }, + "ab7d54c7c6570efca5b4b8ce70f52a5773e5d53b": { + "balance": "279600000000000000000" + }, + "3f173aa6edf469d185e59bd26ae4236b92b4d8e1": { + "balance": "320000000000000000000" + }, + "a3f4ad14e0bb44e2ce2c14359c75b8e732d37054": { + "balance": "200000000000000000000" + }, + "ac5f627231480d0d95302e6d89fc32cb1d4fe7e3": { + "balance": "200000000000000000000" + }, + "d0775dba2af4c30a3a78365939cd71c2f9de95d2": { + "balance": "1940000000000000000000" + }, + "ad94235fc3b3f47a2413af31e884914908ef0c45": { + "balance": "500008000000000000000" + }, + "eaedcc6b8b6962d5d9288c156c579d47c0a9fcff": { + "balance": "85000000000000000000" + }, + "7ac48d40c664cc9a6d89f1c5f5c80a1c70e744e6": { + "balance": "3008000000000000000000" + }, + "ec73114c5e406fdbbe09b4fa621bd70ed54ea1ef": { + "balance": "24500000000000000000000" + }, + "a690f1a4b20ab7ba34628620de9ca040c43c1963": { + "balance": "4000000000000000000000" + }, + "cad14f9ebba76680eb836b079c7f7baaf481ed6d": { + "balance": "238600000000000000000" + }, + "6c714a58fff6e97d14b8a5e305eb244065688bbd": { + "balance": "4000000000000000000000" + }, + "3e618350fa01657ab0ef3ebac8e37012f8fc2b6f": { + "balance": "2804400000000000000000" + }, + "c946d5acc1346eba0a7279a0ac1d465c996d827e": { + "balance": "16385128000000000000000" + }, + "1164caaa8cc5977afe1fad8a7d6028ce2d57299b": { + "balance": "400000000000000000000" + }, + "7917e5bd82a9790fd650d043cdd930f7799633db": { + "balance": "3999800000000000000000" + }, + "d52aecc6493938a28ca1c367b701c21598b6a02e": { + "balance": "1100000000000000000000" + }, + "98bed3a72eccfbafb923489293e429e703c7e25b": { + "balance": "2000000000000000000000" + }, + "42db0b902559e04087dd5c441bc7611934184b89": { + "balance": "2014420000000000000000" + }, + "43bc2d4ddcd6583be2c7bc094b28fb72e62ba83b": { + "balance": "2000000000000000000000" + }, + "85f0e7c1e3aff805a627a2aaf2cff6b4c0dbe9cb": { + "balance": "20000000000000000000" + }, + "581b9fd6eae372f3501f42eb9619eec820b78a84": { + "balance": "19699015000000000000000" + }, + "541db20a80cf3b17f1621f1b3ff79b882f50def3": { + "balance": "1000000000000000000000" + }, + "4e8a6d63489ccc10a57f885f96eb04ecbb546024": { + "balance": "18500000000000000000000" + }, + "28349f7ef974ea55fe36a1583b34cec3c45065f0": { + "balance": "234490000000000000000" + }, + "a3241d890a92baf52908dc4aa049726be426ebd3": { + "balance": "19999560000000000000000" + }, + "b4b11d109f608fa8edd3fea9f8c315649aeb3d11": { + "balance": "5000000000000000000000" + }, + "5f321b3daaa296cadf29439f9dab062a4bffedd6": { + "balance": "81868000000000000000" + }, + "c5ae86b0c6c7e3900f1368105c56537faf8d743e": { + "balance": "188000000000000000000" + }, + "9a8eca4189ff4aa8ff7ed4b6b7039f0902219b15": { + "balance": "20000000000000000000" + }, + "a3facc50195c0b4933c85897fecc5bbd995c34b8": { + "balance": "20000000000000000000" + }, + "f07bd0e5c2ce69c7c4a724bd26bbfa9d2a17ca03": { + "balance": "5910000000000000000000" + }, + "640aba6de984d94517377803705eaea7095f4a11": { + "balance": "10000000000000000000000" + }, + "204ac98867a7c9c7ed711cb82f28a878caf69b48": { + "balance": "6000000000000000000000" + }, + "9d34dac25bd15828faefaaf28f710753b39e89dc": { + "balance": "1090400000000000000000" + }, + "fe418b421a9c6d373602790475d2303e11a75930": { + "balance": "1015200000000000000000" + }, + "3f472963197883bbda5a9b7dfcb22db11440ad31": { + "balance": "481445000000000000000" + }, + "1578bdbc371b4d243845330556fff2d5ef4dff67": { + "balance": "100000000000000000000" + }, + "dba4796d0ceb4d3a836b84c96f910afc103f5ba0": { + "balance": "166666000000000000000" + }, + "466fda6b9b58c5532750306a10a2a8c768103b07": { + "balance": "199955000000000000000" + }, + "2770f14efb165ddeba79c10bb0af31c31e59334c": { + "balance": "3000000000000000000000" + }, + "7c382c0296612e4e97e440e02d3871273b55f53b": { + "balance": "197600000000000000000" + }, + "1fb7bd310d95f2a6d9baaf8a8a430a9a04453a8b": { + "balance": "3000000000000000000000" + }, + "a9acf600081bb55bb6bfbab1815ffc4e17e85a95": { + "balance": "200000000000000000000" + }, + "f93d5bcb0644b0cce5fcdda343f5168ffab2877d": { + "balance": "209978000000000000000" + }, + "db0cc78f74d9827bdc8a6473276eb84fdc976212": { + "balance": "2000000000000000000000" + }, + "b66411e3a02dedb726fa79107dc90bc1cae64d48": { + "balance": "2000000000000000000000" + }, + "4d6e8fe109ccd2158e4db114132fe75fecc8be5b": { + "balance": "25019000000000000000" + }, + "6fd947d5a73b175008ae6ee8228163da289b167d": { + "balance": "30000000000000000000000" + }, + "32d950d5e93ea1d5b48db4714f867b0320b31c0f": { + "balance": "1015200000000000000000" + }, + "9c99b62606281b5cefabf36156c8fe62839ef5f3": { + "balance": "4000000000000000000000" + }, + "86c8d0d982b539f48f9830f9891f9d607a942659": { + "balance": "13260000000000000000000" + }, + "f2127d54188fedef0f338a5f38c7ff73ad9f6f42": { + "balance": "20000000000000000000000" + }, + "e864fec07ed1214a65311e11e329de040d04f0fd": { + "balance": "1656353000000000000000" + }, + "1d09ad2412691cc581c1ab36b6f9434cd4f08b54": { + "balance": "7000000000000000000000" + }, + "4ea70f04313fae65c3ff224a055c3d2dab28dddf": { + "balance": "19999800000000000000000" + }, + "e0668fa82c14d6e8d93a53113ef2862fa81581bc": { + "balance": "870400000000000000000" + }, + "f0d858105e1b648101ac3f85a0f8222bf4f81d6a": { + "balance": "600000000000000000000" + }, + "0f3a1023cac04dbf44f5a5fa6a9cf8508cd4fddf": { + "balance": "1820000000000000000000" + }, + "5793abe6f1533311fd51536891783b3f9625ef1c": { + "balance": "827268000000000000000" + }, + "8d667637e29eca05b6bfbef1f96d460eefbf9984": { + "balance": "4000000000000000000000" + }, + "d76dbaebc30d4ef67b03e6e6ecc6d84e004d502d": { + "balance": "2019250000000000000000" + }, + "42d1a6399b3016a8597f8b640927b8afbce4b215": { + "balance": "2980000000000000000000" + }, + "21fd47c5256012198fa5abf131c06d6aa1965f75": { + "balance": "7880000000000000000000" + }, + "2f2bba1b1796821a766fce64b84f28ec68f15aea": { + "balance": "20000000000000000000" + }, + "d24bf12d2ddf457decb17874efde2052b65cbb49": { + "balance": "14000000000000000000000" + }, + "88de13b09931877c910d593165c364c8a1641bd3": { + "balance": "3000000000000000000000" + }, + "555ca9f05cc134ab54ae9bea1c3ff87aa85198ca": { + "balance": "100000000000000000000" + }, + "ae9ecd6bdd952ef497c0050ae0ab8a82a91898ce": { + "balance": "30000000000000000000" + }, + "ad8bfef8c68a4816b3916f35cb7bfcd7d3040976": { + "balance": "40000000000000000000000" + }, + "dad136b88178b4837a6c780feba226b98569a94c": { + "balance": "200000000000000000000" + }, + "800e7d631c6e573a90332f17f71f5fd19b528cb9": { + "balance": "152000000000000000000" + }, + "94a9a71691317c2064271b51c9353fbded3501a8": { + "balance": "3340000000000000000000" + }, + "80a0f6cc186cf6201400736e065a391f52a9df4a": { + "balance": "10000000000000000000000" + }, + "712ff7370a13ed360973fedc9ff5d2c93a505e9e": { + "balance": "3940000000000000000000" + }, + "42399659aca6a5a863ea2245c933fe9a35b7880e": { + "balance": "2044000000000000000000" + }, + "ae239acffd4ebe2e1ba5b4170572dc79cc6533ec": { + "balance": "12000000000000000000000" + }, + "007b9fc31905b4994b04c9e2cfdc5e2770503f42": { + "balance": "1999000000000000000000" + }, + "7480de62254f2ba82b578219c07ba5be430dc3cb": { + "balance": "7040000000000000000000" + }, + "917b8f9f3a8d09e9202c52c29e724196b897d35e": { + "balance": "161000000000000000000" + }, + "708ea707bae4357f1ebea959c3a250acd6aa21b3": { + "balance": "500000000000000000000" + }, + "6dc7053a718616cfc78bee6382ee51add0c70330": { + "balance": "2000000000000000000000" + }, + "c4dac5a8a0264fbc1055391c509cc3ee21a6e04c": { + "balance": "6501000000000000000000" + }, + "c1b2a0fb9cad45cd699192cd27540b88d3384279": { + "balance": "500000000000000000000" + }, + "b07cb9c12405b711807543c4934465f87f98bd2d": { + "balance": "2000000000000000000000" + }, + "c7f72bb758016b374714d4899bce22b4aec70a31": { + "balance": "1072706000000000000000" + }, + "0c480de9f7461002908b49f60fc61e2b62d3140b": { + "balance": "10000000000000000000000" + }, + "83d532d38d6dee3f60adc68b936133c7a2a1b0dd": { + "balance": "500000000000000000000" + }, + "12afbcba1427a6a39e7ba4849f7ab1c4358ac31b": { + "balance": "20000000000000000000000" + }, + "f8f6645e0dee644b3dad81d571ef9baf840021ad": { + "balance": "2000000000000000000000" + }, + "40cf890591eae4a18f812a2954cb295f633327e6": { + "balance": "48132000000000000000" + }, + "735b97f2fc1bd24b12076efaf3d1288073d20c8c": { + "balance": "20000000000000000000" + }, + "47c7e5efb48b3aed4b7c6e824b435f357df4c723": { + "balance": "18200000000000000000" + }, + "d34d708d7398024533a5a2b2309b19d3c55171bb": { + "balance": "400000000000000000000" + }, + "64370e87202645125a35b207af1231fb6072f9a7": { + "balance": "200000000000000000000" + }, + "b055af4cadfcfdb425cf65ba6431078f07ecd5ab": { + "balance": "100000000000000000000" + }, + "c7de5e8eafb5f62b1a0af2195cf793c7894c9268": { + "balance": "1000000000000000000000" + }, + "c63cd7882118b8a91e074d4c8f4ba91851303b9a": { + "balance": "260000000000000000000" + }, + "164d7aac3eecbaeca1ad5191b753f173fe12ec33": { + "balance": "744090000000000000000" + }, + "e4fb26d1ca1eecba3d8298d9d148119ac2bbf580": { + "balance": "400000000000000000000" + }, + "613ac53be565d46536b820715b9b8d3ae68a4b95": { + "balance": "3760000000000000000000" + }, + "7f616c6f008adfa082f34da7d0650460368075fb": { + "balance": "1000000000000000000000" + }, + "9af100cc3dae83a33402051ce4496b16615483f6": { + "balance": "2000000000000000000000" + }, + "b45cca0d36826662683cf7d0b2fdac687f02d0c4": { + "balance": "1000000000000000000000" + }, + "93a6b3ab423010f981a7489d4aad25e2625c5741": { + "balance": "20190033000000000000000" + }, + "ee049af005974dd1c7b3a9ca8d9aa77175ba53aa": { + "balance": "333333000000000000000" + }, + "687927e3048bb5162ae7c15cf76bd124f9497b9e": { + "balance": "2000000000000000000000" + }, + "1aa40270d21e5cde86b6316d1ac3c533494b79ed": { + "balance": "20000000000000000000" + }, + "426259b0a756701a8b663528522156c0288f0f24": { + "balance": "9900000000000000000000" + }, + "91c75e3cb4aa89f34619a164e2a47898f5674d9c": { + "balance": "2000000000000000000000" + }, + "437983388ab59a4ffc215f8e8269461029c3f1c1": { + "balance": "20000000000000000000000" + }, + "272a131a5a656a7a3aca35c8bd202222a7592258": { + "balance": "2674000000000000000000" + }, + "bc0ca4f217e052753614d6b019948824d0d8688b": { + "balance": "400000000000000000000" + }, + "cc6c03bd603e09de54e9c4d5ac6d41cbce715724": { + "balance": "98500000000000000000" + }, + "d79aff13ba2da75d46240cac0a2467c656949823": { + "balance": "1730000000000000000000" + }, + "477b24eee8839e4fd19d1250bd0b6645794a61ca": { + "balance": "8000000000000000000000" + }, + "79fd6d48315066c204f9651869c1096c14fc9781": { + "balance": "2000000000000000000000" + }, + "1463a873555bc0397e575c2471cf77fa9db146e0": { + "balance": "10000000000000000000000" + }, + "89ab13ee266d779c35e8bb04cd8a90cc2103a95b": { + "balance": "60000000000000000000000" + }, + "90acced7e48c08c6b934646dfa0adf29dc94074f": { + "balance": "56154000000000000000" + }, + "31ea6eab19d00764e9a95e183f2b1b22fc7dc40f": { + "balance": "20000000000000000000" + }, + "87a53ea39f59a35bada8352521645594a1a714cb": { + "balance": "1910000000000000000000" + }, + "1e1aed85b86c6562cb8fa1eb6f8f3bc9dcae6e79": { + "balance": "4516200000000000000000" + }, + "e36a8ea87f1e99e8a2dc1b2608d166667c9dfa01": { + "balance": "100000000000000000000" + }, + "ec2cb8b9378dff31aec3c22e0e6dadff314ab5dd": { + "balance": "2000000000000000000000" + }, + "3cadeb3d3eed3f62311d52553e70df4afce56f23": { + "balance": "4000000000000000000000" + }, + "3ceca96bb1cdc214029cbc5e181d398ab94d3d41": { + "balance": "80000000000000000000000" + }, + "3283eb7f9137dd39bed55ffe6b8dc845f3e1a079": { + "balance": "66224000000000000000" + }, + "0954a8cb5d321fc3351a7523a617d0f58da676a7": { + "balance": "2506000000000000000000" + }, + "de33d708a3b89e909eaf653b30fdc3a5d5ccb4b3": { + "balance": "177300000000000000000" + }, + "1c6702b3b05a5114bdbcaeca25531aeeb34835f4": { + "balance": "26071500000000000000000" + }, + "e5b96fc9ac03d448c1613ac91d15978145dbdfd1": { + "balance": "200000000000000000000" + }, + "fbf204c813f836d83962c7870c7808ca347fd33e": { + "balance": "20000000000000000000" + }, + "3b13631a1b89cb566548899a1d60915cdcc4205b": { + "balance": "2000000000000000000000" + }, + "a87f7abd6fa31194289678efb63cf584ee5e2a61": { + "balance": "4000000000000000000000" + }, + "c0a39308a80e9e84aaaf16ac01e3b01d74bd6b2d": { + "balance": "136499000000000000000" + }, + "ffd6da958eecbc016bab91058440d39b41c7be83": { + "balance": "20000000000000000000000" + }, + "0e3dd7d4e429fe3930a6414035f52bdc599d784d": { + "balance": "40110000000000000000" + }, + "e0663e8cd66792a641f56e5003660147880f018e": { + "balance": "2000000000000000000000" + }, + "5b78eca27fbdea6f26befba8972b295e7814364b": { + "balance": "2000000000000000000000" + }, + "ec9851bd917270610267d60518b54d3ca2b35b17": { + "balance": "40000000000000000000000" + }, + "bc9c95dfab97a574cea2aa803b5caa197cef0cff": { + "balance": "420000000000000000000" + }, + "100b4d0977fcbad4debd5e64a0497aeae5168fab": { + "balance": "314500000000000000000" + }, + "1b6610fb68bad6ed1cfaa0bbe33a24eb2e96fafb": { + "balance": "152000000000000000000" + }, + "b4524c95a7860e21840296a616244019421c4aba": { + "balance": "8000000000000000000000" + }, + "88975a5f1ef2528c300b83c0c607b8e87dd69315": { + "balance": "83500000000000000000" + }, + "853e6abaf44469c72f151d4e223819aced4e3728": { + "balance": "2000000000000000000000" + }, + "d604abce4330842e3d396ca73ddb5519ed3ec03f": { + "balance": "163940000000000000000" + }, + "d209482bb549abc4777bea6d7f650062c9c57a1c": { + "balance": "320880000000000000000" + }, + "590acbda37290c0d3ec84fc2000d7697f9a4b15d": { + "balance": "500000000000000000000" + }, + "571950ea2c90c1427d939d61b4f2de4cf1cfbfb0": { + "balance": "20000000000000000000" + }, + "cb94e76febe208116733e76e805d48d112ec9fca": { + "balance": "1000000000000000000000" + }, + "fa8e3b1f13433900737daaf1f6299c4887f85b5f": { + "balance": "715000000000000000000" + }, + "162d76c2e6514a3afb6fe3d3cb93a35c5ae783f1": { + "balance": "2000000000000000000000" + }, + "4bea288eea42c4955eb9faad2a9faf4783cbddac": { + "balance": "28790618000000000000000" + }, + "c8ab1a3cf46cb8b064df2e222d39607394203277": { + "balance": "2000000000000000000000" + }, + "318b2ea5f0aaa879c4d5e548ac9d92a0c67487b7": { + "balance": "200000000000000000000" + }, + "53c5fe0119e1e848640cee30adea96940f2a5d8b": { + "balance": "21746000000000000000000" + }, + "0701f9f147ec486856f5e1b71de9f117e99e2105": { + "balance": "173360000000000000000" + }, + "337cfe1157a5c6912010dd561533791769c2b6a6": { + "balance": "1000000000000000000000" + }, + "fd60d2b5af3d35f7aaf0c393052e79c4d823d985": { + "balance": "56400000000000000000" + }, + "0f049a8bdfd761de8ec02cee2829c4005b23c06b": { + "balance": "252000000000000000000" + }, + "924bce7a853c970bb5ec7bb759baeb9c7410857b": { + "balance": "13700000000000000000" + }, + "16abb8b021a710bdc78ea53494b20614ff4eafe8": { + "balance": "158000000000000000000" + }, + "9e7f65a90e8508867bccc914256a1ea574cf07e3": { + "balance": "1240000000000000000000" + }, + "01d03815c61f416b71a2610a2daba59ff6a6de5b": { + "balance": "9553100000000000000000" + }, + "3df762049eda8ac6927d904c7af42f94e5519601": { + "balance": "2000000000000000000000" + }, + "5593c9d4b664730fd93ca60151c25c2eaed93c3b": { + "balance": "200000000000000000000" + }, + "e023f09b2887612c7c9cf1988e3a3a602b3394c9": { + "balance": "2000000000000000000000" + }, + "4c13980c32dcf3920b78a4a7903312907c1b123f": { + "balance": "60024000000000000000" + }, + "a282e969cac9f7a0e1c0cd90f5d0c438ac570da3": { + "balance": "627760000000000000000" + }, + "3b22da2a0271c8efe102532773636a69b1c17e09": { + "balance": "502000000000000000000" + }, + "1aa1021f550af158c747668dd13b463160f95a40": { + "balance": "1470000000000000000000" + }, + "f15178ffc43aa8070ece327e930f809ab1a54f9d": { + "balance": "197600000000000000000" + }, + "db1293a506e90cad2a59e1b8561f5e66961a6788": { + "balance": "2000000000000000000000" + }, + "88c361640d6b69373b081ce0c433bd590287d5ec": { + "balance": "50000000000000000000000" + }, + "3737216ee91f177732fb58fa4097267207e2cf55": { + "balance": "1520000000000000000000" + }, + "a16d9e3d63986159a800b46837f45e8bb980ee0b": { + "balance": "2030400000000000000000" + }, + "ec76f12e57a65504033f2c0bce6fc03bd7fa0ac4": { + "balance": "3580000000000000000000" + }, + "d9f1b26408f0ec67ad1d0d6fe22e8515e1740624": { + "balance": "24000000000000000000" + }, + "716ba01ead2a91270635f95f25bfaf2dd610ca23": { + "balance": "44750000000000000000000" + }, + "42a98bf16027ce589c4ed2c95831e2724205064e": { + "balance": "10000000000000000000000" + }, + "0f88aac9346cb0e7347fba70905475ba8b3e5ece": { + "balance": "10000000000000000000000" + }, + "2d8c52329f38d2a2fa9cbaf5c583daf1490bb11c": { + "balance": "20000000000000000000" + }, + "3cea302a472a940379dd398a24eafdbadf88ad79": { + "balance": "3000000000000000000000" + }, + "a29d5bda74e003474872bd5894b88533ff64c2b5": { + "balance": "10000000000000000000000" + }, + "2d23766b6f6b05737dad80a419c40eda4d77103e": { + "balance": "3820000000000000000000" + }, + "b07249e055044a9155359a402937bbd954fe48b6": { + "balance": "100000000000000000000" + }, + "f1e980c559a1a8e5e50a47f8fffdc773b7e06a54": { + "balance": "30104784000000000000000" + }, + "8275cd684c3679d5887d03664e338345dc3cdde1": { + "balance": "15800000000000000000" + }, + "b27c1a24204c1e118d75149dd109311e07c073ab": { + "balance": "3100000000000000000000" + }, + "451b3699475bed5d7905f8905aa3456f1ed788fc": { + "balance": "2560000000000000000000" + }, + "31ad4d9946ef09d8e988d946b1227f9141901736": { + "balance": "22880000000000000000000" + }, + "52b8a9592634f7300b7c5c59a3345b835f01b95c": { + "balance": "2000000000000000000000" + }, + "b161725fdcedd17952d57b23ef285b7e4b1169e8": { + "balance": "50071000000000000000" + }, + "74fc5a99c0c5460503a13b0509459da19ce7cd90": { + "balance": "200000000000000000000" + }, + "d99df7421b9382e42c89b006c7f087702a0757c0": { + "balance": "480000000000000000000" + }, + "8a4f4a7f52a355ba105fca2072d3065fc8f7944b": { + "balance": "500000000000000000000" + }, + "12316fc7f178eac22eb2b25aedeadf3d75d00177": { + "balance": "19999999000000000000000" + }, + "f598db2e09a8a5ee7d720d2b5c43bb126d11ecc2": { + "balance": "200000000000000000000" + }, + "37b8beac7b1ca38829d61ab552c766f48a10c32f": { + "balance": "400000000000000000000" + }, + "851dc38adb4593729a76f33a8616dab6f5f59a77": { + "balance": "100000000000000000000" + }, + "bf4096bc547dbfc4e74809a31c039e7b389d5e17": { + "balance": "3940000000000000000000" + }, + "98d3731992d1d40e1211c7f735f2189afa0702e0": { + "balance": "8000000000000000000000" + }, + "0f4073c1b99df60a1549d69789c7318d9403a814": { + "balance": "20000000000000000000000" + }, + "a430995ddb185b9865dbe62539ad90d22e4b73c2": { + "balance": "10000000000000000000000" + }, + "898c72dd736558ef9e4be9fdc34fef54d7fc7e08": { + "balance": "1000000000000000000000" + }, + "f9b617f752edecae3e909fbb911d2f8192f84209": { + "balance": "2674000000000000000000" + }, + "e1ae029b17e373cde3de5a9152201a14cac4e119": { + "balance": "99968000000000000000" + }, + "d8e8474292e7a051604ca164c0707783bb2885e8": { + "balance": "13370000000000000000000" + }, + "f476f2cb7208a32e051fd94ea8662992638287a2": { + "balance": "100000000000000000000" + }, + "3a84e950ed410e51b7e8801049ab2634b285fea1": { + "balance": "18690000000000000000000" + }, + "5b7784caea01799ca30227827667ce207c5cbc76": { + "balance": "2000000000000000000000" + }, + "3af65b3e28895a4a001153391d1e69c31fb9db39": { + "balance": "3940000000000000000000" + }, + "95fb5afb14c1ef9ab7d179c5c300503fd66a5ee2": { + "balance": "34225000000000000000" + }, + "a8446c4781a737ac4328b1e15b8a0b3fbb0fd668": { + "balance": "21390500000000000000000" + }, + "4888fb25cd50dbb9e048f41ca47d78b78a27c7d9": { + "balance": "17300000000000000000000" + }, + "566c10d638e8b88b47d6e6a414497afdd00600d4": { + "balance": "99960000000000000000" + }, + "bd47f5f76e3b930fd9485209efa0d4763da07568": { + "balance": "1000000000000000000000" + }, + "1e1c6351776ac31091397ecf16002d979a1b2d51": { + "balance": "1400000000000000000000" + }, + "edf603890228d7d5de9309942b5cad4219ef9ad7": { + "balance": "5000000000000000000000" + }, + "1923cfc68b13ea7e2055803645c1e320156bd88d": { + "balance": "1337000000000000000000" + }, + "8f8f37d0ad8f335d2a7101b41156b688a81a9cbe": { + "balance": "70000000000000000000" + }, + "63334fcf1745840e4b094a3bb40bb76f9604c04c": { + "balance": "3978000000000000000000" + }, + "001762430ea9c3a26e5749afdb70da5f78ddbb8c": { + "balance": "200000000000000000000" + }, + "512116817ba9aaf843d1507c65a5ea640a7b9eec": { + "balance": "50000000000000000000" + }, + "2961fb391c61957cb5c9e407dda29338d3b92c80": { + "balance": "999942000000000000000" + }, + "fc2952b4c49fedd0bc0528a308495e6d6a1c71d6": { + "balance": "2000000000000000000000" + }, + "13ec812284026e409bc066dfebf9d5a4a2bf801e": { + "balance": "1610000000000000000000" + }, + "ef463c2679fb279164e20c3d2691358773a0ad95": { + "balance": "2000000000000000000000" + }, + "3aadf98b61e5c896e7d100a3391d3250225d61df": { + "balance": "234000000000000000000" + }, + "e8137fc1b2ec7cc7103af921899b4a39e1d959a1": { + "balance": "1490000000000000000000" + }, + "b1a2b43a7433dd150bb82227ed519cd6b142d382": { + "balance": "2738000000000000000000" + }, + "c1f39bd35dd9cec337b96f47c677818160df37b7": { + "balance": "20000000000000000000" + }, + "b587b44a2ca79e4bc1dd8bfdd43a207150f2e7e0": { + "balance": "630400000000000000000" + }, + "41485612d03446ec4c05e5244e563f1cbae0f197": { + "balance": "970000000000000000000" + }, + "a12623e629df93096704b16084be2cd89d562da4": { + "balance": "8500000000000000000000" + }, + "3f2f381491797cc5c0d48296c14fd0cd00cdfa2d": { + "balance": "804000000000000000000" + }, + "9470cc36594586821821c5c996b6edc83b6d5a32": { + "balance": "24000000000000000000" + }, + "3605372d93a9010988018f9f315d032ed1880fa1": { + "balance": "500066000000000000000" + }, + "12632388b2765ee4452b50161d1fffd91ab81f4a": { + "balance": "740000000000000000000" + }, + "274a3d771a3d709796fbc4d5f48fce2fe38c79d6": { + "balance": "20000000000000000000" + }, + "d60a52580728520df7546bc1e283291788dbae0c": { + "balance": "999910000000000000000" + }, + "1ab53a11bcc63ddfaa40a02b9e186496cdbb8aff": { + "balance": "1996800000000000000000" + }, + "c282e6993fbe7a912ea047153ffd9274270e285b": { + "balance": "139939000000000000000" + }, + "a291e9c7990d552dd1ae16cebc3fca342cbaf1d1": { + "balance": "20000000000000000000000" + }, + "5547fdb4ae11953e01292b7807fa9223d0e4606a": { + "balance": "98940000000000000000" + }, + "bded11612fb5c6da99d1e30e320bc0995466141e": { + "balance": "400000000000000000000" + }, + "b73b4ff99eb88fd89b0b6d57a9bc338e886fa06a": { + "balance": "32000000000000000000" + }, + "b1c751786939bba0d671a677a158c6abe7265e46": { + "balance": "10000000000000000000000" + }, + "e881bbbe69722d81efecaa48d1952a10a2bfac8f": { + "balance": "16000000000000000000000" + }, + "fe96c4cd381562401aa32a86e65b9d52fa8aee27": { + "balance": "2640000000000000000000" + }, + "683dba36f7e94f40ea6aea0d79b8f521de55076e": { + "balance": "140000000000000000000" + }, + "5ac2908b0f398c0df5bac2cb13ca7314fba8fa3d": { + "balance": "199800000000000000000" + }, + "8914a680a5aec5226d4baaec2e5552b44dd7c874": { + "balance": "100076000000000000000" + }, + "041170f581de80e58b2a045c8f7c1493b001b7cb": { + "balance": "889800000000000000000" + }, + "4665e47396c7db97eb2a03d90863d5d4ba319a94": { + "balance": "600000000000000000000" + }, + "ed4be04a052d7accb3dcce90319dba4020ab2c68": { + "balance": "37547947000000000000000" + }, + "4b0619d9d8aa313a9531ac7dbe04ca0d6a5ad1b6": { + "balance": "2000000000000000000000" + }, + "a21442ab05340ade68c915f3c3399b9955f3f7eb": { + "balance": "775000000000000000000" + }, + "655934da8e744eaa3de34dbbc0894c4eda0b61f2": { + "balance": "200000000000000000000" + }, + "6038740ae28d66ba93b0be08482b3205a0f7a07b": { + "balance": "316000000000000000000" + }, + "99924a9816bb7ddf3fec1844828e9ad7d06bf4e6": { + "balance": "1760000000000000000000" + }, + "6847825bdee8240e28042c83cad642f286a3bddc": { + "balance": "1500000000000000000000" + }, + "a718aaad59bf395cba2b23e09b02fe0c89816247": { + "balance": "999600000000000000000" + }, + "2c89f5fdca3d155409b638b98a742e55eb4652b7": { + "balance": "98500000000000000000000" + }, + "1a7044e2383f8708305b495bd1176b92e7ef043a": { + "balance": "200000000000000000000" + }, + "282e80a554875a56799fa0a97f5510e795974c4e": { + "balance": "1000000000000000000000" + }, + "ffb3bcc3196a8c3cb834cec94c34fed35b3e1054": { + "balance": "1340000000000000000000" + }, + "d135794b149a18e147d16e621a6931f0a40a969a": { + "balance": "20000000000000000000000" + }, + "6b94615db750656ac38c7e1cf29a9d13677f4e15": { + "balance": "12000000000000000000000" + }, + "ecbe425e670d39094e20fb5643a9d818eed236de": { + "balance": "5000000000000000000000" + }, + "511e0efb04ac4e3ff2e6550e498295bfcd56ffd5": { + "balance": "668500000000000000000" + }, + "ff65511cada259260c1ddc41974ecaecd32d6357": { + "balance": "1760000000000000000000" + }, + "9ffc5fe06f33f5a480b75aa94eb8556d997a16c0": { + "balance": "20000000000000000000" + }, + "57df23bebdc65eb75feb9cb2fad1c073692b2baf": { + "balance": "4000000000000000000000" + }, + "207ef80b5d60b6fbffc51f3a64b8c72036a5abbd": { + "balance": "6685000000000000000000" + }, + "c573e841fa08174a208b060ccb7b4c0d7697127f": { + "balance": "668500000000000000000" + }, + "411610b178d5617dfab934d293f512a93e5c10e1": { + "balance": "170000000000000000000" + }, + "9991614c5baa47dd6c96874645f97add2c3d8380": { + "balance": "1970000000000000000000" + }, + "2d3480bf0865074a72c7759ee5137b4d70c51ce9": { + "balance": "200000000000000000000" + }, + "9d40e012f60425a340d82d03a1c757bfabc706fb": { + "balance": "169799000000000000000" + }, + "47648bed01f3cd3249084e635d14daa9e7ec3c8a": { + "balance": "194000000000000000000" + }, + "a5ff62222d80c013cec1a0e8850ed4d354dac16d": { + "balance": "207600000000000000000" + }, + "f80d3619702fa5838c48391859a839fb9ce7160f": { + "balance": "1992800000000000000000" + }, + "7c0f5e072043c9ee740242197e78cc4b98cdf960": { + "balance": "200000000000000000000" + }, + "a40aa2bbce0c72b4d0dfffcc42715b2b54b01bfa": { + "balance": "1000000000000000000000" + }, + "2eeed50471a1a2bf53ee30b1232e6e9d80ef866d": { + "balance": "20000000000000000000" + }, + "0c2808b951ed9e872d7b32790fcc5994ae41ffdc": { + "balance": "102000000000000000000000" + }, + "7f06c89d59807fa60bc60136fcf814cbaf2543bd": { + "balance": "10000000000000000000000" + }, + "8d4b603c5dd4570c34669515fdcc665890840c77": { + "balance": "18200000000000000000" + }, + "d5e5c135d0c4c3303934711993d0d16ff9e7baa0": { + "balance": "2000000000000000000000" + }, + "241361559feef80ef137302153bd9ed2f25db3ef": { + "balance": "20000000000000000000000" + }, + "db63122de7037da4971531fae9af85867886c692": { + "balance": "277000000000000000000" + }, + "417e4e2688b1fd66d821529e46ed4f42f8b3db3d": { + "balance": "2000000000000000000000" + }, + "127db1cadf1b771cbd7475e1b272690f558c8565": { + "balance": "14000000000000000000000" + }, + "48659d8f8c9a2fd44f68daa55d23a608fbe500dc": { + "balance": "2000000000000000000000" + }, + "b3a64b1176724f5409e1414a3523661baee74b4a": { + "balance": "25610000000000000000" + }, + "aa14422d6f0ae5a758194ed15780c838d67f1ee1": { + "balance": "28503824000000000000000" + }, + "a0a0e65204541fca9b2fb282cd95138fae16f809": { + "balance": "10000000000000000000000" + }, + "d2107b353726c3a2b46566eaa7d9f80b5d21dbe3": { + "balance": "20000000000000000000" + }, + "e4cafb727fb5c6b70bb27533b8a9ccc9ef6888e1": { + "balance": "300443000000000000000" + }, + "09f3f601f605441140586ce0656fa24aa5b1d9ae": { + "balance": "1539400000000000000000" + }, + "87fcbe7c4193ffcb08143779c9bec83fe7fda9fc": { + "balance": "100275000000000000000" + }, + "03ebc63fda6660a465045e235fbe6e5cf195735f": { + "balance": "141840000000000000000" + }, + "bdbaf6434d40d6355b1e80e40cc4ab9c68d96116": { + "balance": "100000000000000000000" + }, + "4e2225a1bb59bc88a2316674d333b9b0afca6655": { + "balance": "155000000000000000000" + }, + "4dc3da13b2b4afd44f5d0d3189f444d4ddf91b1b": { + "balance": "2000000000000000000000" + }, + "4ba8e0117fc0b6a3e56b24a3a58fe6cef442ff98": { + "balance": "5640000000000000000000" + }, + "27146913563aa745e2588430d9348e86ea7c3510": { + "balance": "400000000000000000000" + }, + "4c5afe40f18ffc48d3a1aec41fc29de179f4d297": { + "balance": "2000000000000000000000" + }, + "8a810114b2025db9fbb50099a6e0cb9e2efa6bdc": { + "balance": "1910000000000000000000" + }, + "2dee90a28f192d676a8773232b56f18f239e2fad": { + "balance": "18587970000000000000000" + }, + "60676e92d18b000509c61de540e6c5ddb676d509": { + "balance": "1200000000000000000000" + }, + "9bfc659c9c601ea42a6b21b8f17084ec87d70212": { + "balance": "10000000000000000000000" + }, + "5d5d6e821c6eef96810c83c491468560ef70bfb5": { + "balance": "2000000000000000000000" + }, + "d5787668c2c5175b01a8ee1ac3ecc9c8b2aba95a": { + "balance": "1999944000000000000000" + }, + "33b336f5ba5edb7b1ccc7eb1a0d984c1231d0edc": { + "balance": "2000000000000000000000" + }, + "3abb8adfc604f48d5984811d7f1d52fef6758270": { + "balance": "4475000000000000000000" + }, + "980a84b686fc31bdc83c221058546a71b11f838a": { + "balance": "779471000000000000000" + }, + "0b507cf553568daaf65504ae4eaa17a8ea3cdbf5": { + "balance": "2000000000000000000000" + }, + "896009526a2c7b0c09a6f63a80bdf29d9c87de9c": { + "balance": "3462830000000000000000" + }, + "9696052138338c722f1140815cf7749d0d3b3a74": { + "balance": "500000000000000000000" + }, + "3831757eae7557cb8a37a4b10644b63e4d3b3c75": { + "balance": "200000000000000000000" + }, + "62dc72729024375fc37cbb9c7c2393d10233330f": { + "balance": "2000000000000000000000" + }, + "44098866a69b68c0b6bc168229b9603587058967": { + "balance": "188000000000000000000" + }, + "25adb8f96f39492c9bb47c5edc88624e46075697": { + "balance": "26740000000000000000000" + }, + "fd4de8e3748a289cf7d060517d9d38388db01fb8": { + "balance": "250000000000000000000" + }, + "6be7595ea0f068489a2701ec4649158ddc43e178": { + "balance": "2000000000000000000000" + }, + "d402b4f6a099ebe716cb14df4f79c0cd01c6071b": { + "balance": "2000000000000000000000" + }, + "a07682000b1bcf3002f85c80c0fa2949bd1e82fd": { + "balance": "4000000000000000000000" + }, + "eb4f00e28336ea09942588eeac921811c522143c": { + "balance": "2000000000000000000000" + }, + "8f31c7005197ec997a87e69bec48649ab94bb2a5": { + "balance": "4000000000000000000000" + }, + "e7fd8fd959aed2767ea7fa960ce1db53af802573": { + "balance": "1000000000000000000000" + }, + "a8ef9ad274436042903e413c3b0c62f5f52ed584": { + "balance": "10000000000000000000000" + }, + "d83ad260e9a6f432fb6ea28743299b4a09ad658c": { + "balance": "2000000000000000000000" + }, + "b5c816a8283ca4df68a1a73d63bd80260488df08": { + "balance": "200000000000000000000" + }, + "d7d3c75920590438b82c3e9515be2eb6ed7a8b1a": { + "balance": "60000000000000000000000" + }, + "af3cb5965933e7dad883693b9c3e15beb68a4873": { + "balance": "2000000000000000000000" + }, + "6e899e59a9b41ab7ea41df7517860f2acb59f4fd": { + "balance": "20000000000000000000000" + }, + "527a8ca1268633a6c939c5de1b929aee92aeac8d": { + "balance": "900000000000000000000" + }, + "1680cec5021ee93050f8ae127251839e74c1f1fd": { + "balance": "13098657000000000000000" + }, + "ff7843c7010aa7e61519b762dfe49124a76b0e4e": { + "balance": "933580000000000000000000" + }, + "140fba58dbc04803d84c2130f01978f9e0c73129": { + "balance": "400000000000000000000" + }, + "0261ad3a172abf1315f0ffec3270986a8409cb25": { + "balance": "203500000000000000000" + }, + "ab5a79016176320973e8cd38f6375530022531c0": { + "balance": "1000000000000000000000" + }, + "fca73eff8771c0103ba3cc1a9c259448c72abf0b": { + "balance": "1000000000000000000000" + }, + "07d41217badca5e0e60327d845a3464f0f27f84a": { + "balance": "4000000000000000000000" + }, + "2c1c19114e3d6de27851484b8d2715e50f8a1065": { + "balance": "100000000000000000000" + }, + "abd21eff954fc6a7de26912a7cbb303a6607804e": { + "balance": "1517000000000000000000" + }, + "f303d5a816affd97e83d9e4dac2f79072bb0098f": { + "balance": "960000000000000000000" + }, + "114cfefe50170dd97ae08f0a44544978c599548d": { + "balance": "863000000000000000000" + }, + "647b85044df2cf0b4ed4882e88819fe22ae5f793": { + "balance": "1000032000000000000000" + }, + "1b130d6fa51d5c48ec8d1d52dc8a227be8735c8a": { + "balance": "2000000000000000000000" + }, + "0d9d3f9bc4a4c6efbd59679b69826bc1f63d9916": { + "balance": "600000000000000000000" + }, + "c765e00476810947816af142d46d2ee7bca8cc4f": { + "balance": "500000000000000000000" + }, + "b57b04fa23d1203fae061eac4542cb60f3a57637": { + "balance": "191000000000000000000" + }, + "e192489b85a982c1883246d915b229cb13207f38": { + "balance": "5000000000000000000000" + }, + "5f483ffb8f680aedf2a38f7833afdcde59b61e4b": { + "balance": "2000000000000000000000" + }, + "b46d1182e5aacaff0d26b2fcf72f3c9ffbcdd97d": { + "balance": "3139000000000000000000" + }, + "59c7f785c93160e5807ed34e5e534bc6188647a7": { + "balance": "640000000000000000000" + }, + "18e4ce47483b53040adbab35172c01ef64506e0c": { + "balance": "9000000000000000000000" + }, + "296d66b521571a4e4103a7f562c511e6aa732d81": { + "balance": "668500000000000000000" + }, + "bcd99edc2160f210a05e3a1fa0b0434ced00439b": { + "balance": "2000000000000000000000" + }, + "f14f0eb86db0eb68753f16918e5d4b807437bd3e": { + "balance": "200000000000000000000" + }, + "60d5667140d12614b21c8e5e8a33082e32dfcf23": { + "balance": "20000000000000000000000" + }, + "8ccabf25077f3aa41545344d53be1b2b9c339000": { + "balance": "1695400000000000000000" + }, + "8cc0d7c016fa7aa950114aa1db094882eda274ea": { + "balance": "159800000000000000000" + }, + "c71145e529c7a714e67903ee6206e4c3042b6727": { + "balance": "1430000000000000000000" + }, + "c5e9939334f1252ed2ba26814487dfd2982b3128": { + "balance": "70000000000000000000" + }, + "f09b3e87f913ddfd57ae8049c731dba9b636dfc3": { + "balance": "608000000000000000000" + }, + "4349225a62f70aea480a029915a01e5379e64fa5": { + "balance": "2598000000000000000000" + }, + "666b4f37d55d63b7d056b615bb74c96b3b01991a": { + "balance": "4000000000000000000000" + }, + "8bd6b1c6d74d010d1008dba6ef835d4430b35c32": { + "balance": "50000000000000000000" + }, + "7363cd90fbab5bb8c49ac20fc62c398fe6fb744c": { + "balance": "2000000000000000000000" + }, + "b7479dab5022c4d5dbaaf8de171b4e951dd1a457": { + "balance": "80000000000000000000" + }, + "5a5468fa5ca226c7532ecf06e1bc1c45225d7ec9": { + "balance": "1910000000000000000000" + }, + "32a20d028e2c6218b9d95b445c771524636a22ef": { + "balance": "9500000000000000000000" + }, + "1bd28cd5c78aee51357c95c1ef9235e7c18bc854": { + "balance": "2000000000000000000000" + }, + "693492a5c51396a482881669ccf6d8d779f00951": { + "balance": "345827000000000000000" + }, + "bd723b289a7367b6ece2455ed61edb49670ab9c4": { + "balance": "4999995000000000000000" + }, + "1be3542c3613687465f15a70aeeb81662b65cca8": { + "balance": "2000000000000000000000" + }, + "5803e68b34da121aef08b602badbafb4d12481ca": { + "balance": "18000000000000000000000" + }, + "9ac907ee85e6f3e223459992e256a43fa08fa8b2": { + "balance": "10000000000000000000000" + }, + "833b6a8ec8da408186ac8a7d2a6dd61523e7ce84": { + "balance": "16000000000000000000000" + }, + "64628c6fb8ec743adbd87ce5e018d531d9210437": { + "balance": "26740000000000000000" + }, + "566c28e34c3808d9766fe8421ebf4f2b1c4f7d77": { + "balance": "1970000000000000000000" + }, + "171ad9a04bedc8b861e8ed4bddf5717813b1bb48": { + "balance": "400000000000000000000" + }, + "4f85bc1fc5cbc9c001e8f1372e07505370d8c71f": { + "balance": "940000000000000000000" + }, + "6d2f976734b9d0070d1883cf7acab8b3e4920fc1": { + "balance": "10000000000000000000000" + }, + "357a02c0a9dfe287de447fb67a70ec5b62366647": { + "balance": "26740000000000000000" + }, + "44a01fb04ac0db2cce5dbe281e1c46e28b39d878": { + "balance": "1999944000000000000000" + }, + "3630c5e565ceaa8a0f0ffe32875eae2a6ce63c19": { + "balance": "170016000000000000000" + }, + "334340ee4b9cdc81f850a75116d50ee9b69825bf": { + "balance": "2000000000000000000000" + }, + "c0afb7d8b79370cfd663c68cc6b9702a37cd9eff": { + "balance": "1000000000000000000000" + }, + "2016895df32c8ed5478269468423aea7b7fbce50": { + "balance": "20000000000000000000" + }, + "1e2fe4e4a77d141ff49a0c7fbc95b0a2b283eeeb": { + "balance": "2000000000000000000000" + }, + "260df8943a8c9a5dba7945327fd7e0837c11ad07": { + "balance": "200000000000000000000" + }, + "32fbeed6f626fcdfd51acafb730b9eeff612f564": { + "balance": "2000000000000000000000" + }, + "9bd88068e13075f3a8cac464a5f949d6d818c0f6": { + "balance": "6000000000000000000000" + }, + "ab4572fbb1d72b575d69ec6ad17333873e8552fc": { + "balance": "1999942000000000000000" + }, + "e44ea51063405154aae736be2bf1ee3b9be639ae": { + "balance": "4000000000000000000000" + }, + "617f20894fa70e94a86a49cd74e03238f64d3cd9": { + "balance": "5000057000000000000000" + }, + "3e914e3018ac00449341c49da71d04dfeeed6221": { + "balance": "4000000000000000000000" + }, + "590181d445007bd0875aaf061c8d51153900836a": { + "balance": "2000000000000000000000" + }, + "27987110221a880826adb2e7ab5eca78c6e31aec": { + "balance": "4000000000000000000000" + }, + "06618e9d5762df62028601a81d4487d6a0ecb80e": { + "balance": "1337000000000000000000" + }, + "8cc652dd13e7fe14dabbb36d5d320db9ffee8a54": { + "balance": "1790000000000000000000" + }, + "8973aefd5efaee96095d9e288f6a046c97374b43": { + "balance": "141000000000000000000" + }, + "dbd51cdf2c3bfacdff106221de2e19ad6d420414": { + "balance": "1760000000000000000000" + }, + "25697ef20cccaa70d32d376f8272d9c1070c3d78": { + "balance": "200000000000000000000" + }, + "0726c42e00f45404836eb1e280d073e7059687f5": { + "balance": "1623331000000000000000" + }, + "5e0785532c7723e4c0af9357d5274b73bdddddde": { + "balance": "25000088000000000000000" + }, + "38430e931d93be01b4c3ef0dc535f1e0a9610063": { + "balance": "10000000000000000000000" + }, + "143d536b8b1cb84f56a39e0bc81fd5442bcacce1": { + "balance": "100000000000000000000" + }, + "5c6d041da7af4487b9dc48e8e1f60766d0a56dbc": { + "balance": "1457800000000000000000" + }, + "f9bfb59d538afc4874d4f5941b08c9730e38e24b": { + "balance": "40000000000000000000" + }, + "83dbfd8eda01d0de8e158b16d0935fc2380a5dc7": { + "balance": "600000000000000000000" + }, + "0e6cd664ad9c1ed64bf98749f40644b626e3792c": { + "balance": "60000000000000000000000" + }, + "ce2e0da8934699bb1a553e55a0b85c169435bea3": { + "balance": "4999962000000000000000" + }, + "a39bfee4aec9bd75bd22c6b672898ca9a1e95d32": { + "balance": "10000000000000000000000" + }, + "1bc44c8761231ba1f11f5faa40fa669a013e12ce": { + "balance": "203586000000000000000" + }, + "68809af5d532a11c1a4d6e32aac75c4c52b08ead": { + "balance": "10000000000000000000000" + }, + "80cc21bd99f39005c58fe4a448909220218f66cb": { + "balance": "1000072000000000000000" + }, + "1080c1d8358a15bc84dac8253c6883319020df2c": { + "balance": "2674000000000000000000" + }, + "9eaf6a328a4076024efa6b67b48b21eedcc0f0b8": { + "balance": "158000000000000000000" + }, + "1e7b5e4d1f572becf2c00fc90cb4767b4a6e33d4": { + "balance": "112970000000000000000" + }, + "acbd185589f7a68a67aa4b1bd65077f8c64e4e21": { + "balance": "200000000000000000000" + }, + "ff78541756ab2b706e0d70b18adb700fc4f1643d": { + "balance": "43250000000000000000000" + }, + "7f0ec3db804692d4d1ea3245365aab0590075bc4": { + "balance": "4000000000000000000000" + }, + "4a918032439159bb315b6725b6830dc83697739f": { + "balance": "343800000000000000000" + }, + "bc1b021a78fde42d9b5226d6ec26e06aa3670090": { + "balance": "80000000000000000000" + }, + "2f2523cc834f0086052402626296675186a8e582": { + "balance": "16000000000000000000000" + }, + "9db2e15ca681f4c66048f6f9b7941ed08b1ff506": { + "balance": "4000000000000000000000" + }, + "20b9a9e6bd8880d9994ae00dd0b9282a0beab816": { + "balance": "500000000000000000000" + }, + "3bddbc8134f77d55597fc97c26d26698090604eb": { + "balance": "13700000000000000000" + }, + "80c3a9f695b16db1597286d1b3a8b7696c39fa27": { + "balance": "100000000000000000000" + }, + "53194d8afa3e883502767edbc30586af33b114d3": { + "balance": "2000000000000000000000" + }, + "e2efd0a9bc407ece03d67e8ec8e9d283f48d2a49": { + "balance": "12280000000000000000000" + }, + "1cb450920078aab2317c7db3b38af7dd298b2d41": { + "balance": "340000000000000000000" + }, + "ca8276c477b4a07b80107b843594189607b53bec": { + "balance": "6000000000000000000000" + }, + "147f4210ab5804940a0b7db8c14c28396b62a6bf": { + "balance": "2000000000000000000000" + }, + "d3df3b53cb3b4755de54e180451cc44c9e8ae0aa": { + "balance": "659801000000000000000" + }, + "f7c708015071d4fb0a3a2a09a45d156396e3349e": { + "balance": "3000000000000000000000" + }, + "a8cafac32280d021020bf6f2a9782883d7aabe12": { + "balance": "100000000000000000000" + }, + "399aa6f5d078cb0970882bc9992006f8fbdf3471": { + "balance": "1000000000000000000000" + }, + "15669180dee29598869b08a721c7d24c4c0ee63f": { + "balance": "1000000000000000000000" + }, + "bba8ab22d2fedbcfc63f684c08afdf1c175090b5": { + "balance": "99091000000000000000" + }, + "5e5a441974a83d74c687ebdc633fb1a49e7b1ad7": { + "balance": "3000000000000000000000" + }, + "98b769cc305cecfb629a00c907069d7ef9bc3a12": { + "balance": "26000000000000000000" + }, + "c820c711f07705273807aaaa6de44d0e4b48be2e": { + "balance": "155000000000000000000" + }, + "12aa7d86ddfbad301692feac8a08f841cb215c37": { + "balance": "137000000000000000000" + }, + "6ff5d361b52ad0b68b1588607ec304ae5665fc98": { + "balance": "1940000000000000000000" + }, + "2382a9d48ec83ea3652890fd0ee79c907b5b2dc1": { + "balance": "133700000000000000000" + }, + "b2a144b1ea67b9510f2267f9da39d3f93de26642": { + "balance": "2000000000000000000000" + }, + "b3e20eb4de18bd060221689894bee5aeb25351ee": { + "balance": "73535000000000000000" + }, + "101a0a64f9afcc448a8a130d4dfcbee89537d854": { + "balance": "15200000000000000000000" + }, + "1b826fb3c012b0d159e294ba5b8a499ff3c0e03c": { + "balance": "2000000000000000000000" + }, + "aafb7b013aa1f8541c7e327bf650adbd194c208f": { + "balance": "1358000000000000000000" + }, + "96eb523e832f500a017de13ec27f5d366c560eff": { + "balance": "307600000000000000000" + }, + "c7bf17c4c11f98941f507e77084fffbd2dbd3db5": { + "balance": "1000000000000000000000" + }, + "840ec83ea93621f034e7bb3762bb8e29ded4c479": { + "balance": "2500000000000000000000" + }, + "0e9c511864a177f49be78202773f60489fe04e52": { + "balance": "6000000000000000000000" + }, + "f6f1a44309051c6b25e47dff909b179bb9ab591c": { + "balance": "1940000000000000000000" + }, + "63fe6bcc4b8a9850abbe75803730c932251f145b": { + "balance": "18200000000000000000" + }, + "f88b58db37420b464c0be88b45ee2b95290f8cfa": { + "balance": "40000000000000000000" + }, + "9d4d321177256ebd9afbda304135d517c3dc5693": { + "balance": "616000000000000000000" + }, + "8c1fbe5f0aea359c5aa1fa08c8895412ca8e05a6": { + "balance": "1000000000000000000000" + }, + "cb0dd7cf4e5d8661f6028943a4b9b75c914436a7": { + "balance": "120000000000000000000000" + }, + "a3979a92760a135adf69d72f75e167755f1cb8c3": { + "balance": "100000000000000000000" + }, + "ca22cda3606da5cad013b8074706d7e9e721a50c": { + "balance": "6816200000000000000000" + }, + "157559adc55764cc6df79323092534e3d6645a66": { + "balance": "6000000000000000000000" + }, + "4f52ad6170d25b2a2e850eadbb52413ff2303e7f": { + "balance": "3040000000000000000000" + }, + "eed28c3f068e094a304b853c950a6809ebcb03e0": { + "balance": "17300000000000000000000" + }, + "2e47f287f498233713850d3126823cc67dcee255": { + "balance": "14600000000000000000" + }, + "6c359e58a13d4578a9338e335c67e7639f5fb4d7": { + "balance": "218000000000000000000" + }, + "4968a2cedb457555a139295aea28776e54003c87": { + "balance": "10092310000000000000000" + }, + "4041374b0feef4792e4b33691fb86897a4ff560c": { + "balance": "365000000000000000000" + }, + "83e48055327c28b5936fd9f4447e73bdb2dd3376": { + "balance": "2674000000000000000000" + }, + "32b7feebc5c59bf65e861c4c0be42a7611a5541a": { + "balance": "2212000000000000000000" + }, + "21a6db6527467bc6dad54bc16e9fe2953b6794ed": { + "balance": "14000000000000000000000" + }, + "e8ead1bb90ccc3aea2b0dcc5b58056554655d1d5": { + "balance": "7760000000000000000000" + }, + "7a94b19992ceb8ce63bc92ee4b5aded10c4d9725": { + "balance": "16770000000000000000000" + }, + "90e93e4dc17121487952333614002be42356498e": { + "balance": "1910000000000000000000" + }, + "aab00abf5828d7ebf26b47ceaccdb8ba03325166": { + "balance": "10000000000000000000000" + }, + "0a9ab2638b1cfd654d25dab018a0aebddf85fd55": { + "balance": "21801000000000000000" + }, + "b12ed07b8a38ad5506363fc07a0b6d799936bdaf": { + "balance": "10000000000000000000000" + }, + "f4a9d00cefa97b7a58ef9417fc6267a5069039ee": { + "balance": "21800000000000000000" + }, + "04a1cada1cc751082ff8da928e3cfa000820a9e9": { + "balance": "40000000000000000000" + }, + "9018cc1f48d2308e252ab6089fb99a7c1d569410": { + "balance": "200000000000000000000" + }, + "895d694e880b13ccd0848a86c5ce411f88476bbf": { + "balance": "199955000000000000000" + }, + "40a7f72867a7dc86770b162b7557a434ed50cce9": { + "balance": "1000000000000000000000" + }, + "467ea10445827ef1e502daf76b928a209e0d4032": { + "balance": "2000000000000000000000" + }, + "7553aa23b68aa5f57e135fe39fdc235eaca8c98c": { + "balance": "1000000000000000000000" + }, + "31b43b015d0081643c6cda46a7073a6dfdbca825": { + "balance": "50019600000000000000000" + }, + "d82fd9fdf6996bedad2843159c06f37e0924337d": { + "balance": "1688800000000000000000" + }, + "24a4eb36a7e498c36f99975c1a8d729fd6b305d7": { + "balance": "258000000000000000000" + }, + "91d66ea6288faa4b3d606c2aa45c7b6b8a252739": { + "balance": "2000000000000000000000" + }, + "83a402438e0519773d5448326bfb61f8b20cf52d": { + "balance": "1520000000000000000000" + }, + "c2fafdd30acb6d6706e9293cb02641f9edbe07b5": { + "balance": "1494224000000000000000" + }, + "79dba256472db4e058f2e4cdc3ea4e8a42773833": { + "balance": "1460000000000000000000" + }, + "498abdeb14c26b7b7234d70fceaef361a76dff72": { + "balance": "3000000000000000000000" + }, + "7b73242d75ca9ad558d650290df17692d54cd8b8": { + "balance": "2000200000000000000000" + }, + "6ec3659571b11f889dd439bcd4d67510a25be57e": { + "balance": "123000000000000000000" + }, + "ab098633eeee0ccefdf632f9575456f6dd80fc86": { + "balance": "200000000000000000000000" + }, + "f4a51fce4a1d5b94b0718389ba4e7814139ca738": { + "balance": "300000000000000000000" + }, + "8f561b41b209f248c8a99f858788376250609cf3": { + "balance": "1700000000000000000000" + }, + "05d0f4d728ebe82e84bf597515ad41b60bf28b39": { + "balance": "4200000000000000000000" + }, + "dfdf43393c649caebe1bb18059decb39f09fb4e8": { + "balance": "400000000000000000000" + }, + "0089508679abf8c71bf6781687120e3e6a84584d": { + "balance": "1800000000000000000000" + }, + "80907f593148b57c46c177e23d25abc4aae18361": { + "balance": "100000000000000000000" + }, + "94fcceadfe5c109c5eaeaf462d43873142c88e22": { + "balance": "4800000000000000000000" + }, + "e89249738b7eced7cb666a663c49cbf6de8343ea": { + "balance": "2000000000000000000000" + }, + "23c99ba087448e19c9701df66e0cab52368331fa": { + "balance": "2000000000000000000000" + }, + "a68e0c30cba3bc5a883e540320f999c7cd558e5c": { + "balance": "1799869000000000000000" + }, + "88888a57bd9687cbf950aeeacf9740dcc4d1ef59": { + "balance": "1820000000000000000000" + }, + "e9b36fe9b51412ddca1a521d6e94bc901213dda8": { + "balance": "10000000000000000000000" + }, + "a9145046fa3628cf5fd4c613927be531e6db1fdd": { + "balance": "112000000000000000000" + }, + "e82c58c579431b673546b53a86459acaf1de9b93": { + "balance": "1000000000000000000000" + }, + "bd6a474d66345bcdd707594adb63b30c7822af54": { + "balance": "4000000000000000000000" + }, + "6a6159074ab573e0ee581f0f3df2d6a594629b74": { + "balance": "310000000000000000000" + }, + "2e7f465520ec35cc23d68e75651bb6689544a196": { + "balance": "1050049000000000000000" + }, + "ac6d02e9a46b379fac4ac9b1d7b5d47bc850ce16": { + "balance": "1760000000000000000000" + }, + "bd59094e074f8d79142ab1489f148e32151f2089": { + "balance": "20000000000000000000" + }, + "0ba6e46af25a13f57169255a34a4dac7ce12be04": { + "balance": "500000000000000000000" + }, + "35145f620397c69cb8e00962961f0f4886643989": { + "balance": "6000000000000000000000" + }, + "d84b922f7841fc5774f00e14604ae0df42c8551e": { + "balance": "4011000000000000000000" + }, + "44232ff66ddad1fd841266380036afd7cf7d7f42": { + "balance": "200000000000000000000" + }, + "516954025fca2608f47da81c215eedfd844a09ff": { + "balance": "382000000000000000000" + }, + "e5aa0b833bb916dc19a8dd683f0ede241d988eba": { + "balance": "3000000000000000000000" + }, + "80ea1acc136eca4b68c842a95adf6b7fee7eb8a2": { + "balance": "4000000000000000000000" + }, + "98a0e54c6d9dc8be96276cebf4fec460f6235d85": { + "balance": "1969803000000000000000" + }, + "91620f3eb304e813d28b0297556d65dc4e5de5aa": { + "balance": "3820000000000000000000" + }, + "7bb984c6dbb9e279966afafda59c01d02627c804": { + "balance": "8050000000000000000000" + }, + "41f489a1ec747bc29c3e5f9d8db97877d4d1b4e9": { + "balance": "133700000000000000000" + }, + "8dbc3e6cb433e194f40f82b40faadb1f8b856116": { + "balance": "1910000000000000000000" + }, + "889da40fb1b60f9ea9bd7a453e584cf7b1b4d9f7": { + "balance": "40000000000000000000" + }, + "debbdd831e0f20ae6e378252decdf92f7cf0c658": { + "balance": "2000000000000000000000" + }, + "a22ade0ddb5c6ef8d0cd8de94d82b11082cb2e91": { + "balance": "1020000000000000000000" + }, + "823219a25976bb2aa4af8bad41ac3526b493361f": { + "balance": "2000000000000000000000" + }, + "6d39a9e98f81f769d73aad2cead276ac1387babe": { + "balance": "394000000000000000000" + }, + "751abcb6cc033059911815c96fd191360ab0442d": { + "balance": "8000000000000000000000" + }, + "64d80c3b8ba68282290b75e65d8978a15a87782c": { + "balance": "1970000000000000000000" + }, + "6ba8f7e25fc2d871618e24e40184199137f9f6aa": { + "balance": "400020000000000000000" + }, + "25a74c2ac75dc8baa8b31a9c7cb4b7829b2456da": { + "balance": "2000000000000000000000" + }, + "0f7b61c59b016322e8226cafaee9d9e76d50a1b3": { + "balance": "4000000000000000000000" + }, + "7526e482529f0a14eec98871dddd0e721b0cd9a2": { + "balance": "20000000000000000000" + }, + "071dd90d14d41f4ff7c413c24238d3359cd61a07": { + "balance": "36400000000000000000000" + }, + "a986762f7a4f294f2e0b173279ad2c81a2223458": { + "balance": "20000000000000000000" + }, + "e667f652f957c28c0e66d0b63417c80c8c9db878": { + "balance": "601650000000000000000" + }, + "7b98e23cb96beee80a168069ebba8f20edd55ccf": { + "balance": "214500000000000000000" + }, + "2d8e5bb8d3521695c77e7c834e0291bfacee7408": { + "balance": "1970000000000000000000" + }, + "f23d01589eb12d439f7448ff54307529f191858d": { + "balance": "2000000000000000000000" + }, + "abd9605b3e91acfd777830d16463478ae0fc7720": { + "balance": "133700000000000000000" + }, + "eabb90d37989aab31feae547e0e6f3999ce6a35d": { + "balance": "2000000000000000000000" + }, + "0abfb39b11486d79572866195ba26c630b6784db": { + "balance": "121500000000000000000000" + }, + "d56a144d7af0ae8df649abae535a15983aa04d02": { + "balance": "5000000000000000000000" + }, + "998c1f93bcdb6ff23c10d0dc924728b73be2ff9f": { + "balance": "1002750000000000000000" + }, + "bc62b3096a91e7dc11a1592a293dd2542150d751": { + "balance": "1000000000000000000000" + }, + "0c8f66c6017bce5b20347204b602b743bad78d60": { + "balance": "2000000000000000000000" + }, + "4c5b3dc0e2b9360f91289b1fe13ce12c0fbda3e1": { + "balance": "2000000000000000000000" + }, + "b44605552471a6eee4daab71ff3bb41326d473e0": { + "balance": "839200000000000000000" + }, + "fc3d226bb36a58f526568857b0bb12d109ec9301": { + "balance": "2000000000000000000000" + }, + "adc8228ef928e18b2a807d00fb3c6c79cd1d9e96": { + "balance": "22800000000000000000" + }, + "9df32a501c0b781c0281022f42a1293ffd7b892a": { + "balance": "9000000000000000000000" + }, + "e7da609d40cde80f00ce5b4ffb6aa9d0b03494fc": { + "balance": "1000000000000000000000" + }, + "9b64d3cd8d2b73f66841b5c46bb695b88a9ab75d": { + "balance": "20769000000000000000" + }, + "8e9c08f738661f9676236eff82ba6261dd3f4822": { + "balance": "100000000000000000000" + }, + "deb97254474c0d2f5a7970dcdb2f52fb1098b896": { + "balance": "1000000000000000000000" + }, + "b4256273962bf631d014555cc1da0dcc31616b49": { + "balance": "2000000000000000000000" + }, + "23abd9e93e7957e5b636be6579051c15e5ce0b0e": { + "balance": "17188400000000000000000" + }, + "382591e7217b435e8e884cdbf415fe377a6fe29e": { + "balance": "8022000000000000000000" + }, + "f17adb740f45cbbde3094e7e13716f8103f563bd": { + "balance": "2000000000000000000000" + }, + "61ed5596c697207f3d55b2a51aa7d50f07fa09e8": { + "balance": "2000000000000000000000" + }, + "788e809741a3b14a22a4b1d937c82cfea489eebe": { + "balance": "7000000000000000000000" + }, + "992646ac1acaabf5ddaba8f9429aa6a94e7496a7": { + "balance": "1000110000000000000000" + }, + "51296f5044270d17707646129c86aad1645eadc1": { + "balance": "1337133000000000000000" + }, + "6ee8aad7e0a065d8852d7c3b9a6e5fdc4bf50c00": { + "balance": "20000000000000000000" + }, + "30db6b9b107e62102f434a9dd0960c2021f5ce4c": { + "balance": "599742000000000000000" + }, + "63fc93001305adfbc9b85d29d9291a05f8f1410b": { + "balance": "1000000000000000000000" + }, + "df6ed6006a6abe886ed33d95a4de28fc12183927": { + "balance": "910000000000000000000" + }, + "4745ab181a36aa8cbf2289d0c45165bc7ebe2381": { + "balance": "39400000000000000000" + }, + "7bb0fdf5a663b5fba28d9c902af0c811e252f298": { + "balance": "200000000000000000000" + }, + "e0ff0bd9154439c4a5b7233e291d7d868af53f33": { + "balance": "396110000000000000000" + }, + "09261f9acb451c3788844f0c1451a35bad5098e3": { + "balance": "8664000000000000000000" + }, + "2813d263fc5ff2479e970595d6b6b560f8d6d6d1": { + "balance": "2000000000000000000000" + }, + "2cd19694d1926a0fa9189edebafc671cf1b2caa5": { + "balance": "1000000000000000000000" + }, + "05336e9a722728d963e7a1cf2759fd0274530fca": { + "balance": "915583000000000000000" + }, + "e5b7af146986c0ff8f85d22e6cc334077d84e824": { + "balance": "2000000000000000000000" + }, + "3e4fbd661015f6461ed6735cefef01f31445de3a": { + "balance": "16200000000000000000000" + }, + "4f5df5b94357de948604c51b7893cddf6076baad": { + "balance": "3760000000000000000000" + }, + "9567a0de811de6ff095b7ee64e7f1b83c2615b80": { + "balance": "267400000000000000000" + }, + "955db3b74360b9a268677e73cea821668af6face": { + "balance": "30000000000000000000000" + }, + "3e040d40cb80ba0125f3b15fdefcc83f3005da1b": { + "balance": "1038000000000000000000" + }, + "43f470ed659e2991c375957e5ddec5bd1d382231": { + "balance": "100000000000000000000" + }, + "047f9bf1529daf87d407175e6f171b5e59e9ff3e": { + "balance": "650000000000000000000" + }, + "15e3b584056b62c973cf5eb096f1733e54c15c91": { + "balance": "936702000000000000000" + }, + "c03de42a109b657a64e92224c08dc1275e80d9b2": { + "balance": "20000000000000000000" + }, + "e4fc13cfcbac1b17ce7783acd423a845943f6b3a": { + "balance": "20000000000000000000" + }, + "65ff874fafce4da318d6c93d57e2c38a0d73e820": { + "balance": "1000160000000000000000" + }, + "8b997dbc078ad02961355da0a159f2927ed43d64": { + "balance": "197000000000000000000" + }, + "2f5080b83f7e2dc0a1dd11b092ad042bff788f4c": { + "balance": "3338355000000000000000" + }, + "1b3920d001c43e72b24e7ca46f0fd6e0c20a5ff2": { + "balance": "2000000000000000000000" + }, + "5ade77fd81c25c0af713b10702768c1eb2f975e7": { + "balance": "20000000000000000000" + }, + "acaaddcbf286cb0e215dda55598f7ff0f4ada5c6": { + "balance": "1000000000000000000000" + }, + "64e0217a5b38aa40583625967fa9883690388b6f": { + "balance": "200000000000000000000" + }, + "ae648155a658370f929be384f7e001047e49dd46": { + "balance": "13561000000000000000000" + }, + "f7c1b443968b117b5dd9b755572fcd39ca5ec04b": { + "balance": "456082000000000000000" + }, + "de027efbb38503226ed871099cb30bdb02af1335": { + "balance": "1000000000000000000000" + }, + "49cf1e54be363106b920729d2d0ba46f0867989a": { + "balance": "268000000000000000000" + }, + "e7f4d7fe6f561f7fa1da3005fd365451ad89df89": { + "balance": "200000000000000000000" + }, + "b036916bdacf94b69e5a8a65602975eb026104dd": { + "balance": "20000000000000000000" + }, + "e923c06177b3427ea448c0a6ff019b54cc548d95": { + "balance": "36281000000000000000" + }, + "ad927e03d1599a78ca2bf0cad2a183dceb71eac0": { + "balance": "1970000000000000000000" + }, + "ef39ca9173df15531d73e6b72a684b51ba0f2bb4": { + "balance": "1598000000000000000000" + }, + "6443b8ae639de91cf73c5ae763eeeed3ddbb9253": { + "balance": "2000000000000000000000" + }, + "8026435aac728d497b19b3e7e57c28c563954f2b": { + "balance": "1730000000000000000000" + }, + "ed327a14d5cfadd98103fc0999718d7ed70528ea": { + "balance": "1440000000000000000000" + }, + "38a3dccf2fcfe0c91a2624bd0cbf88ee4a076c33": { + "balance": "2000000000000000000000" + }, + "f0b1f9e27832c6de6914d70afc238c749995ace4": { + "balance": "2000000000000000000000" + }, + "770d98d31b4353fceee8560c4ccf803e88c0c4e0": { + "balance": "600000000000000000000" + }, + "ba1f0e03cb9aa021f4dcebfa94e5c889c9c7bc9e": { + "balance": "32200000000000000000000" + }, + "233842b1d0692fd11140cf5acda4bf9630bae5f8": { + "balance": "2000000000000000000000" + }, + "b5dd50a15da34968890a53b4f13fe1af081baaaa": { + "balance": "4000000000000000000000" + }, + "72072a0ef1cff3d567cdd260e708ddc11cbc9a31": { + "balance": "100000000000000000000" + }, + "81a88196fac5f23c3e12a69dec4b880eb7d97310": { + "balance": "2000000000000000000000" + }, + "6c63f84556d290bfcd99e434ee9997bfd779577a": { + "balance": "2000000000000000000000" + }, + "5f167aa242bc4c189adecb3ac4a7c452cf192fcf": { + "balance": "1999980000000000000000" + }, + "445cb8de5e3df520b499efc980f52bff40f55c76": { + "balance": "2000000000000000000000" + }, + "aec27ce2133e82d052520afb5c576d9f7eb93ed2": { + "balance": "65232380000000000000000" + }, + "07dc2bf83bc6af19a842ffea661af5b41b67fda1": { + "balance": "1500000000000000000000" + }, + "febd48d0ffdbd5656cd5e686363a61145228f279": { + "balance": "2800000000000000000000" + }, + "a86db07d9f812f4796622d40e03d135874a88a74": { + "balance": "20000000000000000000" + }, + "5413c97ffa4a6e2a7bba8961dc9fce8530a787d7": { + "balance": "1000000000000000000000" + }, + "e2ff9ee4b6ecc14141cc74ca52a9e7a2ee14d908": { + "balance": "1400000000000000000000" + }, + "2e8eb30a716e5fe15c74233e039bfb1106e81d12": { + "balance": "100000000000000000000" + }, + "fd88d114220f081cb3d5e15be8152ab07366576a": { + "balance": "300000000000000000000" + }, + "e408fceaa1b98f3c640f48fcba39f056066d6308": { + "balance": "10000000000000000000000" + }, + "057dd29f2d19aa3da42327ea50bce86ff5c911d9": { + "balance": "4000000000000000000000" + }, + "ed1065dbcf9d73c04ffc7908870d881468c1e132": { + "balance": "2000000000000000000000" + }, + "bbc9d8112e5beb02dd29a2257b1fe69b3536a945": { + "balance": "2000000000000000000000" + }, + "79c1be19711f73bee4e6316ae7549459aacea2e0": { + "balance": "400000000000000000000" + }, + "1bcf3441a866bdbe963009ce33c81cbb0261b02c": { + "balance": "182000000000000000000" + }, + "e2e26e4e1dcf30d048cc6ecf9d51ec1205a4e926": { + "balance": "4000000000000000000000" + }, + "77701e2c493da47c1b58f421b5495dee45bea39b": { + "balance": "6068279000000000000000" + }, + "37a05aceb9395c8635a39a7c5d266ae610d10bf2": { + "balance": "30000000000000000000000" + }, + "c6355ec4768c70a49af69513cd83a5bca7e3b9cd": { + "balance": "6000000000000000000000" + }, + "e3c0c128327a9ad80148139e269773428e638cb0": { + "balance": "2000000000000000000000" + }, + "f7f4898c4c526d955f21f055cb6e47b915e51964": { + "balance": "2288000000000000000000" + }, + "29824e94cc4348bc963279dcdf47391715324cd3": { + "balance": "1940000000000000000000" + }, + "eaa45cea02d87d2cc8fda9434e2d985bd4031584": { + "balance": "1920750000000000000000" + }, + "e08b9aba6bd9d28bc2056779d2fbf0f2855a3d9d": { + "balance": "2000000000000000000000" + }, + "87c498170934b8233d1ad1e769317d5c475f2f40": { + "balance": "1015200000000000000000" + }, + "352d29a26e8a41818181746467f582e6e84012e0": { + "balance": "6000000000000000000000" + }, + "403220600a36f73f24e190d1edb2d61be3f41354": { + "balance": "304000000000000000000" + }, + "0a48296f7631708c95d2b74975bc4ab88ac1392a": { + "balance": "5000000000000000000000" + }, + "ffe0e997f1977a615f5a315af413fd4869343ba0": { + "balance": "100076000000000000000" + }, + "ca66b2280fa282c5b67631ce552b62ee55ad8474": { + "balance": "1969488000000000000000" + }, + "2b6ed29a95753c3ad948348e3e7b1a251080ffb9": { + "balance": "250000000000000000000000" + }, + "492e70f04d18408cb41e25603730506b35a2876b": { + "balance": "39400000000000000000" + }, + "0e6baaa3deb989f289620076668618e9ac332865": { + "balance": "200000000000000000000" + }, + "b753a75f9ed10b21643a0a3dc0517ac96b1a4068": { + "balance": "401800000000000000000" + }, + "3ad915d550b723415620f5a9b5b88a85f382f035": { + "balance": "1000000000000000000000" + }, + "c992be59c6721caf4e028f9e8f05c25c55515bd4": { + "balance": "20000000000000000000" + }, + "02b643d6fabd437a851accbe79abb7fde126dccf": { + "balance": "7200000000000000000000" + }, + "88797e58675ed5cc4c19980783dbd0c956085153": { + "balance": "2000000000000000000000" + }, + "ac142eda1157b9a9a64390df7e6ae694fac98905": { + "balance": "200000000000000000000" + }, + "656579daedd29370d9b737ee3f5cd9d84bc2b342": { + "balance": "1430000000000000000000" + }, + "9bb9b02a26bfe1ccc3f0c6219e261c397fc5ca78": { + "balance": "1337000000000000000000" + }, + "bee8d0b008421954f92d000d390fb8f8e658eaee": { + "balance": "1000000000000000000000" + }, + "7989d09f3826c3e5af8c752a8115723a84d80970": { + "balance": "415554000000000000000" + }, + "7cd5d81eab37e11e6276a3a1091251607e0d7e38": { + "balance": "62856000000000000000" + }, + "6ce1b0f6adc47051e8ab38b39edb4186b03babcc": { + "balance": "1207800000000000000000" + }, + "abfcf5f25091ce57875fc674dcf104e2a73dd2f2": { + "balance": "19700000000000000000" + }, + "1c3ef05dae9dcbd489f3024408669de244c52a02": { + "balance": "20000000000000000000000" + }, + "cfa8b37127149bdbfee25c34d878510951ea10eb": { + "balance": "2000000000000000000000" + }, + "74863acec75d03d53e860e64002f2c165e538377": { + "balance": "1000000000000000000000" + }, + "59b9e733cba4be00429b4bd9dfa64732053a7d55": { + "balance": "20000000000000000000" + }, + "aeadfcd0978edad74a32bd01a0a51d37f246e661": { + "balance": "260000000000000000000" + }, + "08090876baadfee65c3d363ba55312748cfa873d": { + "balance": "1700170000000000000000" + }, + "e589fa76984db5ec4004b46ee8a59492c30744ce": { + "balance": "2800000000000000000000" + }, + "3485361ee6bf06ef6508ccd23d94641f814d3e2f": { + "balance": "2000000000000000000000" + }, + "5cb731160d2e8965670bde925d9de5510935347d": { + "balance": "40000000000000000000" + }, + "8ef4d8a2c23c5279187b64e96f741404085385f3": { + "balance": "299598000000000000000" + }, + "e246683cc99db7c4a52bcbacaab0b32f6bfc93d7": { + "balance": "2000000000000000000000" + }, + "7d273e637ef1eac481119413b91c989dc5eac122": { + "balance": "500000000000000000000" + }, + "6efba8fb2ac5b6730729a972ec224426a287c3ad": { + "balance": "283152000000000000000" + }, + "0773eeacc050f74720b4a1bd57895b1cceeb495d": { + "balance": "10000000000000000000000" + }, + "88a122a2382c523931fb51a0ccad3beb5b7259c3": { + "balance": "2000000000000000000000" + }, + "b0b779b94bfa3c2e1f587bcc9c7e21789222378f": { + "balance": "1550000000000000000000" + }, + "86f95c5b11a293940e35c0b898d8b75f08aab06d": { + "balance": "29605000000000000000000" + }, + "cf2288ef4ebf88e86db13d8a0e0bf52a056582c3": { + "balance": "2533000000000000000000" + }, + "71ea5b11ad8d29b1a4cb67bf58ca6c9f9c338c16": { + "balance": "1600000000000000000000" + }, + "9917d68d4af341d651e7f0075c6de6d7144e7409": { + "balance": "5660000000000000000000" + }, + "1e5800227d4dcf75e30f5595c5bed3f72e341e3b": { + "balance": "248300000000000000000" + }, + "123759f333e13e3069e2034b4f05398918119d36": { + "balance": "20000000000000000000000" + }, + "f798d16da4e460c460cd485fae0fa0599708eb82": { + "balance": "1000000000000000000000" + }, + "864bec5069f855a4fd5892a6c4491db07c88ff7c": { + "balance": "1000000000000000000000" + }, + "fa283299603d8758e8cab082125d2c8f7d445429": { + "balance": "6415633000000000000000" + }, + "c811c2e9aa1ac3462eba5e88fcb5120e9f6e2ca2": { + "balance": "1400140000000000000000" + }, + "61547d376e5369bcf978fc162c3c56ae453547e8": { + "balance": "200000000000000000000" + }, + "0d747ee5969bf79d57381d6fe3a2406cd0d8ce27": { + "balance": "100000000000000000000000" + }, + "f8962b75db5d24c7e8b7cef1068c3e67cebb30a5": { + "balance": "280000000000000000000" + }, + "35bf6688522f35467a7f75302314c02ba176800e": { + "balance": "17400000000000000000000" + }, + "05cb6c3b0072d3116761b532b218443b53e8f6c5": { + "balance": "141722000000000000000000" + }, + "91c80caa081b38351d2a0e0e00f80a34e56474c1": { + "balance": "1000000000000000000000" + }, + "d75a502a5b677287470f65c5aa51b87c10150572": { + "balance": "907400000000000000000" + }, + "3e194b4ecef8bb711ea2ff24fec4e87bd032f7d1": { + "balance": "2575465000000000000000" + }, + "736bf1402c83800f893e583192582a134eb532e9": { + "balance": "9999996000000000000000" + }, + "c2cb1ada5da9a0423873814793f16144ef36b2f3": { + "balance": "1334326000000000000000" + }, + "efcce06bd6089d0e458ef561f5a689480afe7000": { + "balance": "600000000000000000000" + }, + "bfe6bcb0f0c07852643324aa5df5fd6225abc3ca": { + "balance": "74500000000000000000" + }, + "9d799e943e306ba2e5b99c8a6858cbb52c0cf735": { + "balance": "300000000000000000000" + }, + "f45b1dcb2e41dc27ffa024daadf619c11175c087": { + "balance": "19700000000000000000" + }, + "08e38ee0ce48c9ca645c1019f73b5355581c56e6": { + "balance": "1600000000000000000000" + }, + "2cb4c3c16bb1c55e7c6b7a19b127a1ac9390cc09": { + "balance": "3397053000000000000000" + }, + "bdc02cd4330c93d6fbda4f6db2a85df22f43c233": { + "balance": "2000000000000000000000" + }, + "acec91ef6941cf630ba9a3e787a012f4a2d91dd4": { + "balance": "80000000000000000000000" + }, + "27ac073be79ce657a93aa693ee43bf0fa41fef04": { + "balance": "50000000000000000000000" + }, + "22fe884d9037291b4d52e6285ae68dea0be9ffb5": { + "balance": "2000000000000000000000" + }, + "c3107a9af3322d5238df0132419131629539577d": { + "balance": "492650000000000000000" + }, + "b5cac5ed03477d390bb267d4ebd46101fbc2c3da": { + "balance": "197000000000000000000" + }, + "58fb947364e7695765361ebb1e801ffb8b95e6d0": { + "balance": "200000000000000000000" + }, + "32860997d730b2d83b73241a25d3667d51c908ef": { + "balance": "499938000000000000000" + }, + "c79d5062c796dd7761f1f13e558d73a59f82f38b": { + "balance": "8000000000000000000000" + }, + "fa142fe47eda97e6503b386b18a2bedd73ccb5b1": { + "balance": "850080000000000000000" + }, + "6ca5de00817de0cedce5fd000128dede12648b3c": { + "balance": "20000000000000000000" + }, + "214b743955a512de6e0d886a8cbd0282bee6d2a2": { + "balance": "2000000000000000000000" + }, + "ede79ae1ff4f1606d59270216fa46ab2ddd4ecaa": { + "balance": "146000000000000000000" + }, + "528101ce46b720a2214dcdae6618a53177ffa377": { + "balance": "508876000000000000000" + }, + "b5870ce342d43343333673038b4764a46e925f3e": { + "balance": "1000000000000000000000" + }, + "843bd3502f45f8bc4da370b323bdac3fcf5f19a6": { + "balance": "1476000000000000000000" + }, + "5067f4549afbfe884c59cbc12b96934923d45db0": { + "balance": "1000000000000000000000" + }, + "6f2a42e6e033d01061131929f7a6ee1538021e52": { + "balance": "2000000000000000000000" + }, + "e9e1f7cb00a110edd0ebf8b377ef8a7bb856117f": { + "balance": "200000000000000000000" + }, + "a387ecde0ee4c8079499fd8e03473bd88ad7522a": { + "balance": "1970000000000000000000" + }, + "6dff90e6dc359d2590882b1483edbcf887c0e423": { + "balance": "1000000000000000000000" + }, + "22e512149a18d369b73c71efa43e86c9edabaf1d": { + "balance": "1455000000000000000000" + }, + "a3203095edb7028e6871ce0a84f548459f83300a": { + "balance": "4000000000000000000000" + }, + "93b4bf3fdff6de3f4e56ba6d7799dc4b93a6548f": { + "balance": "19100000000000000000" + }, + "8c75956e8fed50f5a7dd7cfd27da200f6746aea6": { + "balance": "1000000000000000000000" + }, + "afc8ebe8988bd4105acc4c018e546a1e8f9c7888": { + "balance": "500000000000000000000" + }, + "bf9acd4445d9c9554689cabbbab18800ff1741c2": { + "balance": "1000000000000000000000" + }, + "603f2fab7afb6e017b94766069a4b43b38964923": { + "balance": "1656954000000000000000" + }, + "a1f765c44fe45f790677944844be4f2d42165fbd": { + "balance": "3687750000000000000000" + }, + "4dc9d5bb4b19cecd94f19ec25d200ea72f25d7ed": { + "balance": "2000000000000000000000" + }, + "48f60a35484fe7792bcc8a7b6393d0dda1f6b717": { + "balance": "3600000000000000000000" + }, + "588ed990a2aff44a94105d58c305257735c868ac": { + "balance": "16100000000000000000000" + }, + "710be8fd5e2918468be2aabea80d828435d79612": { + "balance": "17600000000000000000" + }, + "03ea6d26d080e57aee3926b18e8ed73a4e5b2826": { + "balance": "200000000000000000000" + }, + "20824ba1dbebbef9846ef3d0f6c1b017e6912ec4": { + "balance": "7170194000000000000000" + }, + "f7500c166f8bea2f82347606e5024be9e4f4ce99": { + "balance": "20000000000000000000" + }, + "9d369165fb70b81a3a765f188fd60cbe5e7b0968": { + "balance": "2000000000000000000000" + }, + "6fddbd9bca66e28765c2162c8433548c1052ed11": { + "balance": "82720000000000000000000" + }, + "8b81156e698639943c01a75272ad3d35851ab282": { + "balance": "344946000000000000000" + }, + "75804aac64b4199083982902994d9c5ed8828f11": { + "balance": "557800000000000000000" + }, + "d6e8e97ae9839b9ee507eedb28edfb7477031439": { + "balance": "2000000000000000000000" + }, + "6c808cabb8ff5fbb6312d9c8e84af8cf12ef0875": { + "balance": "4000086000000000000000" + }, + "afa539586e4719174a3b46b9b3e663a7d1b5b987": { + "balance": "5000000000000000000000" + }, + "f8a065f287d91d77cd626af38ffa220d9b552a2b": { + "balance": "1910000000000000000000" + }, + "30e60900cacc7203f314dc604347255167fc2a0f": { + "balance": "2000000000000000000000" + }, + "796f87ba617a2930b1670be92ed1281fb0b346e1": { + "balance": "128400000000000000000" + }, + "f114ff0d0f24eff896edde5471dea484824a99b3": { + "balance": "13700000000000000000" + }, + "0b80fc70282cbdd5fde35bf78984db3bdb120188": { + "balance": "1000160000000000000000" + }, + "da7ad025ebde25d22243cb830ea1d3f64a566323": { + "balance": "500000000000000000000" + }, + "65a52141f56bef98991724c6e7053381da8b5925": { + "balance": "60140000000000000000" + }, + "bbc8eaff637e94fcc58d913c7770c88f9b479277": { + "balance": "200000000000000000000" + }, + "0469e8c440450b0e512626fe817e6754a8152830": { + "balance": "2000000000000000000000" + }, + "0727be0a2a00212048b5520fbefb953ebc9d54a0": { + "balance": "10000000000000000000000" + }, + "7d858493f07415e0912d05793c972113eae8ae88": { + "balance": "1818000000000000000000" + }, + "7091303116d5f2389b23238b4d656a8596d984d3": { + "balance": "1094014000000000000000" + }, + "3702e704cc21617439ad4ea27a5714f2fda1e932": { + "balance": "1000000000000000000000" + }, + "b87de1bcd29269d521b8761cc39cfb4319d2ead5": { + "balance": "1000000000000000000000" + }, + "f639ac31da9f67271bd10402b7654e5ce763bd47": { + "balance": "399996000000000000000" + }, + "e7735ec76518fc6aa92da8715a9ee3f625788f13": { + "balance": "1997803000000000000000" + }, + "51277fe7c81eebd252a03df69a6b9f326e272207": { + "balance": "59965000000000000000" + }, + "3b8098533f7d9bdcd307dbb23e1777ca18418936": { + "balance": "2000000000000000000000" + }, + "2cba6d5d0dc204ea8a25ada2e26f5675bd5f2fdc": { + "balance": "1330755000000000000000" + }, + "5c3c1c645b917543113b3e6c1c054da1fe742b9a": { + "balance": "800000000000000000000" + }, + "5ecdbaeab9106ffe5d7b519696609a05baeb85ad": { + "balance": "20000000000000000000" + }, + "45a820a0672f17dc74a08112bc643fd1167736c3": { + "balance": "199943000000000000000" + }, + "beef94213879e02622142bea61290978939a60d7": { + "balance": "5728109000000000000000" + }, + "6cd212aee04e013f3d2abad2a023606bfb5c6ac7": { + "balance": "1999944000000000000000" + }, + "92698e345378c62d8eda184d94366a144b0c105b": { + "balance": "1400000000000000000000" + }, + "2d5b42fc59ebda0dfd66ae914bc28c1b0a6ef83a": { + "balance": "206764195000000000000000" + }, + "b7a6791c16eb4e2162f14b6537a02b3d63bfc602": { + "balance": "780700000000000000000" + }, + "fa105f1a11b6e4b1f56012a27922e2ac2da4812f": { + "balance": "9550000000000000000000" + }, + "2306df931a940d58c01665fa4d0800802c02edfe": { + "balance": "1000000000000000000000" + }, + "f37bf78c5875154711cb640d37ea6d28cfcb1259": { + "balance": "200000000000000000000" + }, + "66201bd227ae6dc6bdfed5fbde811fecfe5e9dd9": { + "balance": "594808000000000000000" + }, + "2bafbf9e9ed2c219f7f2791374e7d05cb06777e7": { + "balance": "220000000000000000000" + }, + "8e9b35ad4a0a86f758446fffde34269d940ceacd": { + "balance": "4000000000000000000000" + }, + "1b43232ccd4880d6f46fa751a96cd82473315841": { + "balance": "80000000000000000000" + }, + "6eefdc850e87b715c72791773c0316c3559b58a4": { + "balance": "4000000000000000000000" + }, + "f2c03e2a38998c21648760f1e5ae7ea3077d8522": { + "balance": "2642456000000000000000" + }, + "0625d06056968b002206ff91980140242bfaa499": { + "balance": "1000000000000000000000" + }, + "6158e107c5eb54cb7604e0cd8dc1e07500d91c3c": { + "balance": "50000000000000000000" + }, + "02477212ffdd75e5155651b76506b1646671a1eb": { + "balance": "1760000000000000000000" + }, + "fa44a855e404c86d0ca8ef3324251dfb349c539e": { + "balance": "1552000000000000000000" + }, + "49897fe932bbb3154c95d3bce6d93b6d732904dd": { + "balance": "4000000000000000000000" + }, + "9b6641b13e172fc072ca4b8327a3bc28a15b66a9": { + "balance": "120000000000000000000" + }, + "a46b4387fb4dcce011e76e4d73547d4481e09be5": { + "balance": "1337000000000000000000" + }, + "72bb27cb99f3e2c2cf90a98f707d30e4a201a071": { + "balance": "1640000000000000000000" + }, + "b6bfe1c3ef94e1846fb9e3acfe9b50c3e9069233": { + "balance": "1999944000000000000000" + }, + "e6cb3f3124c9c9cc3834b1274bc3336456a38bac": { + "balance": "427382000000000000000" + }, + "fcbc5c71ace79741450b012cf6b8d3f17db68a70": { + "balance": "9550000000000000000000" + }, + "15dbb48c98309764f99ced3692dcca35ee306bac": { + "balance": "150000000000000000000000" + }, + "2e10910ba6e0bc17e055556614cb87090f4d7e5b": { + "balance": "200000000000000000000" + }, + "e5fbe34984b637196f331c679d0c0c47d83410e1": { + "balance": "2000050000000000000000" + }, + "6d120f0caae44fd94bcafe55e2e279ef96ba5c7a": { + "balance": "4000000000000000000000" + }, + "aa5afcfd8309c2df9d15be5e6a504e7d706624c5": { + "balance": "5846763000000000000000" + }, + "37959c20b7e9931d72f5a8ae869dafddad3b6d5c": { + "balance": "200000000000000000000" + }, + "b041310fe9eed6864cedd4bee58df88eb4ed3cac": { + "balance": "10000000000000000000000" + }, + "986df47e76e4d7a789cdee913cc9831650936c9d": { + "balance": "5000000000000000000000" + }, + "35aaa0465d1c260c420fa30e2629869fb6559207": { + "balance": "704976000000000000000" + }, + "7f655c6789eddf455cb4b88099720639389eebac": { + "balance": "6000000000000000000000" + }, + "9e3eb509278fe0dcd8e0bbe78a194e06b6803943": { + "balance": "940000000000000000000" + }, + "3e9410d3b9a87ed5e451a6b91bb8923fe90fb2b5": { + "balance": "200000000000000000000" + }, + "9e960dcd03d5ba99cb115d17ff4c09248ad4d0be": { + "balance": "200000000000000000000" + }, + "f057aa66ca767ede124a1c5b9cc5fc94ef0b0137": { + "balance": "2077730000000000000000" + }, + "f38a6ca80168537e974d14e1c3d13990a44c2c1b": { + "balance": "6000000000000000000000" + }, + "229e430de2b74f442651ddcdb70176bc054cad54": { + "balance": "13545000000000000000" + }, + "27bf9f44ba7d05c33540c3a53bb02cbbffe7c3c6": { + "balance": "2000000000000000000000" + }, + "10389858b800e8c0ec32f51ed61a355946cc409b": { + "balance": "200000000000000000000" + }, + "fd2929271e9d2095a264767e7b0df52ea0d1d400": { + "balance": "3000040000000000000000" + }, + "44250d476e062484e9080a3967bf3a4a732ad73f": { + "balance": "20000000000000000000" + }, + "0c67033dd8ee7f0c8ae534d42a51f7d9d4f7978f": { + "balance": "200000000000000000000" + }, + "e083d34863e0e17f926b7928edff317e998e9c4b": { + "balance": "400000000000000000000" + }, + "7f7192c0df1c7db6d9ed65d71184d8e4155a17ba": { + "balance": "79800000000000000000" + }, + "51e7b55c2f9820eed73884361b5066a59b6f45c6": { + "balance": "2000000000000000000000" + }, + "4fa983bb5e3073a8edb557effeb4f9fb1d60ef86": { + "balance": "1599800000000000000000" + }, + "5a5ee8e9bb0e8ab2fecb4b33d29478be50bbd44b": { + "balance": "776000000000000000000" + }, + "1f3959fc291110e88232c36b7667fc78a379613f": { + "balance": "18200000000000000000" + }, + "2d7d5c40ddafc450b04a74a4dabc2bb5d665002e": { + "balance": "2000000000000000000000" + }, + "5215183b8f80a9bc03d26ce91207832a0d39e620": { + "balance": "1000000000000000000000" + }, + "5607590059a9fec1881149a44b36949aef85d560": { + "balance": "2000000000000000000000" + }, + "f7c50f922ad16b61c6d1baa045ed816815bac48f": { + "balance": "12566370000000000000000" + }, + "da10978a39a46ff0bb848cf65dd9c77509a6d70e": { + "balance": "2000000000000000000000" + }, + "a7dcbba9b9bf6762c145416c506a71e3b497209c": { + "balance": "1999944000000000000000" + }, + "54e01283cc8b384538dd646770b357c960d6cacd": { + "balance": "5000000000000000000000" + }, + "78cf8336b328db3d87813a472b9e89b75e0cf3bc": { + "balance": "1000000000000000000000" + }, + "ba24fc436753a739db2c8d40e6d4d04c528e86fa": { + "balance": "13000000000000000000000" + }, + "dfe929a61c1b38eddbe82c25c2d6753cb1e12d68": { + "balance": "402500000000000000000" + }, + "2b49fba29830360fcdb6da23bbfea5c0bbac5281": { + "balance": "20000000000000000000" + }, + "76becae4a31d36f3cb577f2a43594fb1abc1bb96": { + "balance": "24860000000000000000000" + }, + "e0cf698a053327ebd16b7d7700092fe2e8542446": { + "balance": "95275000000000000000" + }, + "a3802d8a659e89a2c47e905430b2a827978950a7": { + "balance": "1000000000000000000000" + }, + "75636cdb109050e43d5d6ec47e359e218e857eca": { + "balance": "22886800000000000000000" + }, + "3d813ff2b6ed57b937dabf2b381d148a411fa085": { + "balance": "100000000000000000000" + }, + "a9252551a624ae513719dabe5207fbefb2fd7749": { + "balance": "40000000000000000000" + }, + "c749668042e71123a648975e08ed6382f83e05e2": { + "balance": "14000000000000000000000" + }, + "04eca501630abce35218b174956b891ba25efb23": { + "balance": "1000060000000000000000" + }, + "790f91bd5d1c5cc4739ae91300db89e1c1303c93": { + "balance": "2000000000000000000000" + }, + "009560a3de627868f91fa8bfe1c1b7afaf08186b": { + "balance": "524000000000000000000" + }, + "1329dd19cd4baa9fc64310efeceab22117251f12": { + "balance": "200000000000000000000" + }, + "7005a772282b1f62afda63f89b5dc6ab64c84cb9": { + "balance": "18000000000000000000000" + }, + "abfe936425dcc7b74b955082bbaaf2a11d78bc05": { + "balance": "1400000000000000000000" + }, + "97d0d9725e3b70e675843173938ed371b62c7fac": { + "balance": "170000000000000000000" + }, + "41ed2d8e7081482c919fc23d8f0091b3c82c4685": { + "balance": "1295460000000000000000" + }, + "992365d764c5ce354039ddfc912e023a75b8e168": { + "balance": "18200000000000000000" + }, + "e1c607c0a8a060da8f02a8eb38a013ea8cda5b8c": { + "balance": "805000000000000000000" + }, + "3b2c45990e21474451cf4f59f01955b331c7d7c9": { + "balance": "2000000000000000000000" + }, + "29ac2b458454a36c7e96c73a8667222a12242c71": { + "balance": "4000000000000000000000" + }, + "b8555010776e3c5cb311a5adeefe9e92bb9a64b9": { + "balance": "4000000000000000000000" + }, + "30380087786965149e81423b15e313ba32c5c783": { + "balance": "18200000000000000000" + }, + "a2f86bc061884e9eef05640edd51a2f7c0596c69": { + "balance": "2000050000000000000000" + }, + "9f98eb34d46979b0a6de8b05aa533a89b825dcf1": { + "balance": "86500000000000000000" + }, + "c81fb7d20fd2800192f0aac198d6d6a37d3fcb7d": { + "balance": "259500000000000000000" + }, + "a4035ab1e5180821f0f380f1131b7387c8d981cd": { + "balance": "20000000000000000000" + }, + "782f52f0a676c77716d574c81ec4684f9a020a97": { + "balance": "850055000000000000000" + }, + "261e0fa64c51137465eecf5b90f197f7937fdb05": { + "balance": "18000000000000000000000" + }, + "276fd7d24f8f883f5a7a28295bf17151c7a84b03": { + "balance": "2000000000000000000000" + }, + "a1f5b840140d5a9acef402ac3cc3886a68cad248": { + "balance": "2000000000000000000000" + }, + "d2bf67a7f3c6ce56b7be41675dbbadfe7ea93a33": { + "balance": "400000000000000000000" + }, + "8ee584337ddbc80f9e3498df55f0a21eacb57fb1": { + "balance": "20000000000000000000" + }, + "34393c5d91b9de597203e75bac4309b5fa3d28c3": { + "balance": "194000000000000000000" + }, + "114cbbbf6fb52ac414be7ec61f7bb71495ce1dfa": { + "balance": "3000000000000000000000" + }, + "ab7c42c5e52d641a07ad75099c62928b7f86622f": { + "balance": "335940000000000000000" + }, + "80bf995ed8ba92701d10fec49f9e7d014dbee026": { + "balance": "572153000000000000000" + }, + "4a192035e2619b24b0709d56590e9183ccf2c1d9": { + "balance": "10000000000000000000000" + }, + "376cd7577383e902951b60a2017ba7ea29e33576": { + "balance": "2000000000000000000000" + }, + "f5437e158090b2a2d68f82b54a5864b95dd6dbea": { + "balance": "4010732000000000000000" + }, + "13a5eecb38305df94971ef2d9e179ae6cebab337": { + "balance": "330000000000000000000" + }, + "efc8cf1963c9a95267b228c086239889f4dfd467": { + "balance": "10000000000000000000000" + }, + "db77b88dcb712fd17ee91a5b94748d720c90a994": { + "balance": "2000000000000000000000" + }, + "9aaafa0067647ed999066b7a4ca5b4b3f3feaa6f": { + "balance": "1000000000000000000000" + }, + "ae36f7452121913e800e0fcd1a65a5471c23846f": { + "balance": "164000000000000000000" + }, + "b124bcb6ffa430fcae2e86b45f27e3f21e81ee08": { + "balance": "2000000000000000000000" + }, + "f2813a64c5265d020235cb9c319b6c96f906c41e": { + "balance": "350000000000000000000" + }, + "e848ca7ebff5c24f9b9c316797a43bf7c356292d": { + "balance": "114000000000000000000" + }, + "21a6feb6ab11c766fdd977f8df4121155f47a1c0": { + "balance": "57200000000000000000" + }, + "e95e92bbc6de07bf3a660ebf5feb1c8a3527e1c5": { + "balance": "18200000000000000000" + }, + "0b369e002e1b4c7913fcf00f2d5e19c58165478f": { + "balance": "64520000000000000000" + }, + "0909648c18a3ce5bae7a047ec2f868d24cdda81d": { + "balance": "3820000000000000000000" + }, + "d32b45564614516c91b07fa9f72dcf787cce4e1c": { + "balance": "291000000000000000000" + }, + "cf1bdb799b2ea63ce134668bdc198b54840f180b": { + "balance": "18200000000000000000" + }, + "ae062c448618643075de7a0030342dced63dbad7": { + "balance": "825982000000000000000" + }, + "99dfd0504c06c743e46534fd7b55f1f9c7ec3329": { + "balance": "2000000000000000000000" + }, + "87fc4635263944ce14a46c75fa4a821f39ce7f72": { + "balance": "20000000000000000000" + }, + "27c2d7ca504daa3d9066dc09137dc42f3aaab452": { + "balance": "600000000000000000000" + }, + "cc60f836acdef3548a1fefcca13ec6a937db44a0": { + "balance": "86500000000000000000" + }, + "c910a970556c9716ea53af66ddef93143124913d": { + "balance": "1580000000000000000000" + }, + "8173c835646a672e0152be10ffe84162dd256e4c": { + "balance": "492000000000000000000" + }, + "e989733ca1d58d9e7b5029ba5d444858bec03172": { + "balance": "581595000000000000000" + }, + "86806474c358047d9406e6a07f40945bc8328e67": { + "balance": "6884000000000000000000" + }, + "5395a4455d95d178b4532aa4725b193ffe512961": { + "balance": "1000000000000000000000" + }, + "56397638bb3cebf1f62062794b5eb942f916171d": { + "balance": "2000000000000000000000" + }, + "6958f83bb2fdfb27ce0409cd03f9c5edbf4cbedd": { + "balance": "20000000000000000000000" + }, + "26ff0a51e7cece8400276978dbd6236ef162c0e6": { + "balance": "100020000000000000000000" + }, + "4ca783b556e5bf53aa13c8116613d65782c9b642": { + "balance": "25200000000000000000000" + }, + "15a0aec37ff9ff3d5409f2a4f0c1212aaccb0296": { + "balance": "1000000000000000000000" + }, + "50378af7ef54043f892ab7ce97d647793511b108": { + "balance": "19700000000000000000" + }, + "e7c6b5fc05fc748e5b4381726449a1c0ad0fb0f1": { + "balance": "2000000000000000000000" + }, + "5317ecb023052ca7f5652be2fa854cfe4563df4d": { + "balance": "499986000000000000000" + }, + "c94f7c35c027d47df8ef4f9df85a9248a17dd23b": { + "balance": "29944000000000000000" + }, + "6a63fc89abc7f36e282d80787b7b04afd6553e71": { + "balance": "160000000000000000000" + }, + "5fd3d6777ec2620ae83a05528ed425072d3ca8fd": { + "balance": "2000000000000000000000" + }, + "29adcf83b6b20ac6a434abb1993cbd05c60ea2e4": { + "balance": "10000000000000000000000" + }, + "8c6f9f4e5b7ae276bf58497bd7bf2a7d25245f64": { + "balance": "2730000000000000000000" + }, + "d94a57882a52739bbe2a0647c80c24f58a2b4f1c": { + "balance": "1341230000000000000000" + }, + "7286e89cd9de8f7a8a00c86ffdb53992dd9251d1": { + "balance": "1940000000000000000000" + }, + "5773b6026721a1dd04b7828cd62b591bfb34534c": { + "balance": "27000000000000000000000" + }, + "11fefb5dc1a4598aa712640c517775dfa1d91f8c": { + "balance": "10000000000000000000000" + }, + "c6e324beeb5b36765ecd464260f7f26006c5c62e": { + "balance": "2000000000000000000000" + }, + "118fbd753b9792395aef7a4d78d263cdcaabd4f7": { + "balance": "999800000000000000000" + }, + "f8298591523e50b103f0b701d623cbf0f74556f6": { + "balance": "200000000000000000000" + }, + "ab0ced762e1661fae1a92afb1408889413794825": { + "balance": "1910000000000000000000" + }, + "fa67b67b4f37a0150915110ede073b05b853bda2": { + "balance": "647490000000000000000" + }, + "ca122cf0f2948896b74843f49afed0ba1618eed7": { + "balance": "560000000000000000000" + }, + "186b95f8e5effddcc94f1a315bf0295d3b1ea588": { + "balance": "1999944000000000000000" + }, + "2915624bcb679137b8dae9ab57d11b4905eaee4b": { + "balance": "20000000000000000000" + }, + "0c6845bf41d5ee273c3ee6b5b0d69f6fd5eabbf7": { + "balance": "3000026000000000000000" + }, + "cb7479109b43b26657f4465f4d18c6f974be5f42": { + "balance": "1820000000000000000000" + }, + "8dd6a9bae57f518549ada677466fea8ab04fd9b4": { + "balance": "4000000000000000000000" + }, + "34958a46d30e30b273ecc6e5d358a212e5307e8c": { + "balance": "2000000000000000000000" + }, + "2003717907a72560f4307f1beecc5436f43d21e7": { + "balance": "500000000000000000000" + }, + "55ab99b0e0e55d7bb874b7cfe834de631c97ec23": { + "balance": "1031400000000000000000" + }, + "79b48d2d6137c3854d611c01ea42427a0f597bb7": { + "balance": "191000000000000000000" + }, + "d609ec0be70d0ad26f6e67c9d4762b52ee51122c": { + "balance": "1000000000000000000000" + }, + "e8c3f045bb7d38c9d2f395b0ba8492b253230901": { + "balance": "9000000000000000000000" + }, + "aaca60d9d700e78596bbbbb1f1e2f70f4627f9d8": { + "balance": "999996000000000000000" + }, + "89d75b8e0831e46f80bc174188184e006fde0eae": { + "balance": "1000000000000000000000" + }, + "b3667894b7863c068ad344873fcff4b5671e0689": { + "balance": "20000000000000000000000" + }, + "bc1609d685b76b48ec909aa099219022f89b2ccd": { + "balance": "1182000000000000000000" + }, + "88ee7f0efc8f778c6b687ec32be9e7d6f020b674": { + "balance": "2000000000000000000000" + }, + "470ac5d1f3efe28f3802af925b571e63868b397d": { + "balance": "2000000000000000000000" + }, + "abf8ffe0708a99b528cc1ed4e9ce4b0d0630be8c": { + "balance": "2263600000000000000000" + }, + "8cee38d6595788a56e3fb94634b3ffe1fbdb26d6": { + "balance": "20000000000000000000000" + }, + "19798cbda715ea9a9b9d6aab942c55121e98bf91": { + "balance": "1200000000000000000000" + }, + "e25a167b031e84616d0f013f31bda95dcc6350b9": { + "balance": "10560000000000000000000" + }, + "6196c3d3c0908d254366b7bca55745222d9d4db1": { + "balance": "4000000000000000000000" + }, + "e8e9850586e94f5299ab494bb821a5f40c00bd04": { + "balance": "3820000000000000000000" + }, + "1059cbc63e36c43e88f30008aca7ce058eeaa096": { + "balance": "100000000000000000000000" + }, + "c4f2913b265c430fa1ab8adf26c333fc1d9b66f2": { + "balance": "20000000000000000000" + }, + "26e9e2ad729702626417ef25de0dc800f7a779b3": { + "balance": "1000000000000000000000" + }, + "0dfbd4817050d91d9d625c02053cf61a3ee28572": { + "balance": "340000000000000000000" + }, + "709fe9d2c1f1ce42207c9585044a60899f35942f": { + "balance": "2000000000000000000000" + }, + "7ad82caea1a8b4ed05319b9c9870173c814e06ee": { + "balance": "616000000000000000000" + }, + "2a595f16eee4cb0c17d9a2d939b3c10f6c677243": { + "balance": "1100000000000000000000" + }, + "a8f89dd5cc6e64d7b1eeace00702022cd7d2f03d": { + "balance": "700000000000000000000" + }, + "c0a6cbad77692a3d88d141ef769a99bb9e3c9951": { + "balance": "100000000000000000000" + }, + "868c23be873466d4c74c220a19b245d1787e807f": { + "balance": "1366481000000000000000" + }, + "2905b192e83ce659aa355b9d0c204e3e95f9bb9a": { + "balance": "2160817000000000000000" + }, + "50b9fef0a1329b02d16506255f5a2db71ec92d1f": { + "balance": "1325464000000000000000" + }, + "fc10b7a67b3268d5331bfb6a14def5ea4a162ca3": { + "balance": "200000000000000000000" + }, + "85eb256b51c819d60ea61a82d12c9358d59c1cae": { + "balance": "460000000000000000000" + }, + "75de7e9352e90b13a59a5878ffecc7831cac4d82": { + "balance": "2740000000000000000000" + }, + "d32b2c79c36478c5431901f6d700b04dbe9b8810": { + "balance": "396000000000000000000" + }, + "2d0326b23f0409c0c0e9236863a133075a94ba18": { + "balance": "210380000000000000000" + }, + "d2e21ed56868fab28e0947927adaf29f23ebad6c": { + "balance": "1994000000000000000000" + }, + "2ad6c9d10c261819a1a0ca2c48d8c7b2a71728df": { + "balance": "1000000000000000000000" + }, + "7d445267c59ab8d2a2d9e709990e09682580c49f": { + "balance": "1000000000000000000000" + }, + "b6047cdf932db3e4045f4976122341537ed5961e": { + "balance": "20000000000000000000" + }, + "2b3cf97311ff30f460945a9d8099f4a88e26d456": { + "balance": "2000000000000000000000" + }, + "7f4f593b618c330ba2c3d5f41eceeb92e27e426c": { + "balance": "2775000000000000000000" + }, + "72a2fc8675feb972fa41b50dffdbbae7fa2adfb7": { + "balance": "2853840000000000000000" + }, + "076561a856455d7ef86e63f87c73dbb628a55f45": { + "balance": "900000000000000000000" + }, + "03d1724fd00e54aabcd2de2a91e8462b1049dd3a": { + "balance": "2640000000000000000000" + }, + "7ea0f96ee0a573a330b56897761f3d4c0130a8e3": { + "balance": "1337000000000000000000" + }, + "fe65c4188d7922576909642044fdc52395560165": { + "balance": "4000000000000000000000" + }, + "57883010b4ac857fedac03eab2551723a8447ffb": { + "balance": "1000000000000000000000" + }, + "0729a8a4a5ba23f579d0025b1ad0f8a0d35cdfd2": { + "balance": "9700000000000000000000" + }, + "e75c1fb177089f3e58b1067935a6596ef1737fb5": { + "balance": "99910000000000000000" + }, + "e0e978753d982f7f9d1d238a18bd4889aefe451b": { + "balance": "9700000000000000000000" + }, + "5620f46d1451c2353d6243a5d4b427130be2d407": { + "balance": "60000000000000000000" + }, + "f3d688f06bbdbf50f9932c4145cbe48ecdf68904": { + "balance": "20000000000000000000" + }, + "3aa948ea02397755effb2f9dc9392df1058f7e33": { + "balance": "850000000000000000000" + }, + "20d1417f99c569e3beb095856530fe12d0fceaaa": { + "balance": "1182175000000000000000" + }, + "ac77bdf00fd5985b5db12bbef800380abc2a0677": { + "balance": "1000000000000000000000" + }, + "267a7e6e82e1b91d51deddb644f0e96dbb1f7f7e": { + "balance": "20000000000000000000" + }, + "4bbcbf38b3c90163a84b1cd2a93b58b2a3348d87": { + "balance": "8000000000000000000000" + }, + "4c6b93a3bec16349540cbfcae96c9621d6645010": { + "balance": "2000000000000000000000" + }, + "c9308879056dfe138ef8208f79a915c6bc7e70a8": { + "balance": "10000000000000000000000" + }, + "c48b693cacefdbd6cb5d7895a42e3196327e261c": { + "balance": "1000000000000000000000" + }, + "a0951970dfd0832fb83bda12c23545e79041756c": { + "balance": "600000000000000000000" + }, + "7cdf74213945953db39ad0e8a9781add792e4d1d": { + "balance": "2000000000000000000000" + }, + "75621865b6591365606ed378308c2d1def4f222c": { + "balance": "3100000000000000000000" + }, + "67d6a8aa1bf8d6eaf7384e993dfdf10f0af68a61": { + "balance": "198067000000000000000" + }, + "8f0af37566d152802f1ae8f928b25af9b139b448": { + "balance": "200000000000000000000" + }, + "2c6afcd4037c1ed14fa74ff6758e0945a185a8e8": { + "balance": "17600000000000000000" + }, + "c1b2aa8cb2bf62cdc13a47ecc4657facaa995f98": { + "balance": "1000129000000000000000" + }, + "9e8144e08e89647811fe6b72d445d6a5f80ad244": { + "balance": "10000000000000000000000" + }, + "e04ff5e5a7e2af995d8857ce0290b53a2b0eda5d": { + "balance": "1000000000000000000000" + }, + "03dedfcd0b3c2e17c705da248790ef98a6bd5751": { + "balance": "1337000000000000000000" + }, + "698a8a6f01f9ab682f637c7969be885f6c5302bf": { + "balance": "19400000000000000000" + }, + "d82c6fedbdac98af2eed10b00f32b00056ca5a6d": { + "balance": "200000000000000000000" + }, + "2697b339813b0c2d964b2471eb1c606f4ecb9616": { + "balance": "1154000000000000000000" + }, + "987c9bcd6e3f3990a52be3eda4710c27518f4f72": { + "balance": "400000000000000000000" + }, + "c5d48ca2db2f85d8c555cb0e9cfe826936783f9e": { + "balance": "200000000000000000000" + }, + "da214c023e2326ff696c00393168ce46ffac39ec": { + "balance": "1000000000000000000000" + }, + "86570ab259c9b1c32c9729202f77f590c07dd612": { + "balance": "200000000000000000000" + }, + "a646a95c6d6f59f104c6541d7760757ab392b08c": { + "balance": "4200000000000000000000" + }, + "1933e334c40f3acbad0c0b851158206924beca3a": { + "balance": "7551541000000000000000" + }, + "3552a496eba67f12be6eedab360cd13661dc7480": { + "balance": "300000000000000000000" + }, + "2a9c96c19151ffcbe29a4616d0c52b3933b4659f": { + "balance": "69263000000000000000" + }, + "3b7b8e27de33d3ce7961b98d19a52fe79f6c25be": { + "balance": "100000000000000000000000" + }, + "a1911405cf6e999ed011f0ddcd2a4ff7c28f2526": { + "balance": "40000000000000000000" + }, + "0cae108e6db99b9e637876b064c6303eda8a65c8": { + "balance": "3000000000000000000000" + }, + "3883becc08b9be68ad3b0836aac3b620dc0017ef": { + "balance": "2000000000000000000000" + }, + "d0abcc70c0420e0e172f97d43b87d5e80c336ea9": { + "balance": "10000000000000000000000" + }, + "cbf16a0fe2745258cd52db2bf21954c975fc6a15": { + "balance": "300000000000000000000" + }, + "1b23cb8663554871fbbe0d9e60397efb6faedc3e": { + "balance": "200000000000000000000" + }, + "fbede32c349f3300ef4cd33b4de7dc18e443d326": { + "balance": "3160000000000000000000" + }, + "5e806e845730f8073e6cc9018ee90f5c05f909a3": { + "balance": "9480000000000000000000" + }, + "425c338a1325e3a1578efa299e57d986eb474f81": { + "balance": "2000000000000000000000" + }, + "8bf297f8f453523ed66a1acb7676856337b93bf0": { + "balance": "4000000000000000000000" + }, + "38e8a31af2d265e31a9fff2d8f46286d1245a467": { + "balance": "20000000000000000000" + }, + "7edafba8984baf631a820b6b92bbc2c53655f6bd": { + "balance": "2000000000000000000000" + }, + "aa0200f1d17e9c54da0647bb96395d57a78538d8": { + "balance": "1056000000000000000000" + }, + "433eb94a339086ed12d9bde9cd1d458603c97dd6": { + "balance": "100000000000000000000000" + }, + "cd7e47909464d871b9a6dc76a8e9195db3485e7a": { + "balance": "9850000000000000000000" + }, + "5975d78d974ee5bb9e4d4ca2ae77c84b9c3b4b82": { + "balance": "1370000000000000000000" + }, + "cea2896623f4910287a2bdc5be83aea3f2e6de08": { + "balance": "9359000000000000000000" + }, + "cb4ad0c723da46ab56d526da0c1d25c73daff10a": { + "balance": "510000000000000000000" + }, + "e2cf360aa2329eb79d2bf7ca04a27a17c532e4d8": { + "balance": "102000000000000000000" + }, + "ea60549ec7553f511d2149f2d4666cbd9243d93c": { + "balance": "2000000000000000000000" + }, + "cbb7be17953f2ccc93e1bc99805bf45511434e4c": { + "balance": "50440000000000000000000" + }, + "3549bd40bbbc2b30095cac8be2c07a0588e0aed6": { + "balance": "20000000000000000000" + }, + "6510df42a599bcb0a519cca961b488759a6f6777": { + "balance": "2000000000000000000000" + }, + "ed12a1ba1fb8adfcb20dfa19582e525aa3b74524": { + "balance": "6685000000000000000000" + }, + "135eb8c0e9e101deedec11f2ecdb66ae1aae8867": { + "balance": "20000000000000000000000" + }, + "ee906d7d5f1748258174be4cbc38930302ab7b42": { + "balance": "200000000000000000000" + }, + "253f1e742a2cec86b0d7b306e5eacb6ccb2f8554": { + "balance": "20040000000000000000000" + }, + "ecd1a62802351a41568d23033004acc6c005a5d3": { + "balance": "50000000000000000000" + }, + "558c54649a8a6e94722bd6d21d14714f71780534": { + "balance": "2000000000000000000000" + }, + "ca657ec06fe5bc09cf23e52af7f80cc3689e6ede": { + "balance": "900000000000000000000" + }, + "74bf7a5ab59293149b5c60cf364263e5ebf1aa0d": { + "balance": "115800000000000000000" + }, + "7a6d781c77c4ba1fcadf687341c1e31799e93d27": { + "balance": "274000000000000000000" + }, + "77028e409cc43a3bd33d21a9fc53ec606e94910e": { + "balance": "3880000000000000000000" + }, + "4781a10a4df5eebc82f4cfe107ba1d8a7640bd66": { + "balance": "1790000000000000000000" + }, + "78e08bc533413c26e291b3143ffa7cc9afb97b78": { + "balance": "200000000000000000000" + }, + "03ef6ad20ff7bd4f002bac58d47544cf879ae728": { + "balance": "6895000000000000000000" + }, + "0e3696cf1f4217b163d1bc12a5ea730f1c32a14a": { + "balance": "4000000000000000000000" + }, + "825135b1a7fc1605614c8aa4d0ac6dbad08f480e": { + "balance": "1430000000000000000000" + }, + "286b186d61ea1fd78d9930fe12b06537b05c3d51": { + "balance": "1000000000000000000000" + }, + "8d6657f59711b1f803c6ebef682f915b62f92dc9": { + "balance": "2000000000000000000000" + }, + "da8bbee182e455d2098acb338a6d45b4b17ed8b6": { + "balance": "2000000000000000000000" + }, + "3f2da093bb16eb064f8bfa9e30b929d15f8e1c4c": { + "balance": "2000000000000000000000" + }, + "f5d9cf00d658dd45517a48a9d3f5f633541a533d": { + "balance": "116400000000000000000" + }, + "c5f64babb7033142f20e46d7aa6201ed86f67103": { + "balance": "2000000000000000000000" + }, + "a2e2b5941e0c01944bfe1d5fb4e8a34b922ccfb1": { + "balance": "200000000000000000000" + }, + "6114b0eae5576903f80bfb98842d24ed92237f1e": { + "balance": "100000000000000000000" + }, + "38df0c4abe7ded5fe068eadf154ac691774324a4": { + "balance": "1790000000000000000000" + }, + "1c2010bd662df417f2a271879afb13ef4c88a3ae": { + "balance": "4000000000000000000000" + }, + "918967918cd897dd0005e36dc6c883ef438fc8c7": { + "balance": "140000000000000000000" + }, + "a522de7eb6ae1250522a513133a93bd42849475c": { + "balance": "20000000000000000000000" + }, + "7de442c82386154d2e993cbd1280bb7ca6b12ada": { + "balance": "4002000000000000000000" + }, + "66424bd8785b8cb461102a900283c35dfa07ef6a": { + "balance": "40221000000000000000" + }, + "7bbbec5e70bdead8bb32b42805988e9648c0aa97": { + "balance": "1000076000000000000000" + }, + "fec06fe27b44c784b2396ec92f7b923ad17e9077": { + "balance": "2000000000000000000000" + }, + "95d550427b5a514c751d73a0f6d29fb65d22ed10": { + "balance": "300000000000000000000" + }, + "8dde60eb08a099d7daa356daaab2470d7b025a6b": { + "balance": "197000000000000000000" + }, + "81bccbff8f44347eb7fca95b27ce7c952492aaad": { + "balance": "152240000000000000000" + }, + "3995e096b08a5a726800fcd17d9c64c64e088d2b": { + "balance": "200000000000000000000" + }, + "4ee13c0d41200b46d19dee5c4bcec71d82bb8e38": { + "balance": "7893915000000000000000" + }, + "c41461a3cfbd32c9865555a4813137c076312360": { + "balance": "999999000000000000000" + }, + "3300fb149aded65bcba6c04e9cd6b7a03b893bb1": { + "balance": "18200000000000000000" + }, + "29f9286c0e738d1721a691c6b95ab3d9a797ede8": { + "balance": "200000000000000000000000" + }, + "34c8e5f1330fcb4b14ca75cb2580a4b93d204e36": { + "balance": "2000000000000000000000" + }, + "ec5df227bfa85d7ad76b426e1cee963bc7f519dd": { + "balance": "1000000000000000000000" + }, + "797510e386f56393ced8f477378a444c484f7dad": { + "balance": "1000000000000000000000" + }, + "0191eb547e7bf6976b9b1b577546761de65622e2": { + "balance": "1999980000000000000000" + }, + "615a6f36777f40d6617eb5819896186983fd3731": { + "balance": "5910000000000000000000" + }, + "17580b766f7453525ca4c6a88b01b50570ea088c": { + "balance": "100000000000000000000" + }, + "945d96ea573e8df7262bbfa572229b4b16016b0f": { + "balance": "209300000000000000000" + }, + "2de0964400c282bdd78a919c6bf77c6b5f796179": { + "balance": "200000000000000000000" + }, + "304ec69a74545721d7316aef4dcfb41ac59ee2f0": { + "balance": "200000000000000000000" + }, + "be2b326e78ed10e550fee8efa8f8070396522f5a": { + "balance": "39400000000000000000000" + }, + "1a0841b92a7f7075569dc4627e6b76cab05ade91": { + "balance": "1520000000000000000000" + }, + "5fa61f152de6123516c751242979285f796ac791": { + "balance": "204000000000000000000" + }, + "68c8791dc342c373769ea61fb7b510f251d32088": { + "balance": "1000000000000000000000" + }, + "4167cd48e733418e8f99ffd134121c4a4ab278c4": { + "balance": "3640000000000000000000" + }, + "598aaabae9ed833d7bc222e91fcaa0647b77580b": { + "balance": "1800000000000000000000" + }, + "979f30158b574b999aab348107b9eed85b1ff8c1": { + "balance": "970000000000000000000" + }, + "3ad06149b21c55ff867cc3fb9740d2bcc7101231": { + "balance": "197000000000000000000000" + }, + "7133843a78d939c69d4486e10ebc7b602a349ff7": { + "balance": "329000000000000000000" + }, + "8bdfda6c215720eda2136f91052321af4e936c1f": { + "balance": "1000008000000000000000" + }, + "3e1c53300e4c168912163c7e99b95da268ad280a": { + "balance": "1003200000000000000000" + }, + "e07ebbc7f4da416e42c8d4f842aba16233c12580": { + "balance": "2000000000000000000000" + }, + "bac8922c4acc7d2cb6fd59a14eb45cf3e702214b": { + "balance": "800000000000000000000" + }, + "bb6c284aac8a69b75cddb00f28e145583b56bece": { + "balance": "2000000000000000000000" + }, + "0372ee5508bf8163ed284e5eef94ce4d7367e522": { + "balance": "100000000000000000000" + }, + "17125b59ac51cee029e4bd78d7f5947d1ea49bb2": { + "balance": "22000000000000000000000" + }, + "c88ca1e6e5f4d558d13780f488f10d4ad3130d34": { + "balance": "1550000000000000000000" + }, + "a825fd5abb7926a67cf36ba246a24bd27be6f6ed": { + "balance": "17600000000000000000" + }, + "04241b41ecbd0bfdf1295e9d4fa59ea09e6c6186": { + "balance": "1870000000000000000000" + }, + "6de4d15219182faf3aa2c5d4d2595ff23091a727": { + "balance": "1580000000000000000000" + }, + "b203d29e6c56b92699c4b92d1f6f84648dc4cfbc": { + "balance": "400000000000000000000" + }, + "80b42de170dbd723f454e88f7716452d92985092": { + "balance": "300202000000000000000" + }, + "0a5b79d8f23b6483dbe2bdaa62b1064cc76366ae": { + "balance": "1969803000000000000000" + }, + "32034e8581d9484e8af42a28df190132ec29c466": { + "balance": "3460000000000000000000" + }, + "7ee604c7a9dc2909ce321de6b9b24f5767577555": { + "balance": "5533575000000000000000" + }, + "a387ce4e961a7847f560075c64e1596b5641d21c": { + "balance": "668500000000000000000" + }, + "fcc9d4a4262e7a027ab7519110d802c495ceea39": { + "balance": "6370000000000000000000" + }, + "ff8a2ca5a81333f19998255f203256e1a819c0aa": { + "balance": "224000000000000000000" + }, + "f9811fa19dadbf029f8bfe569adb18228c80481a": { + "balance": "200000000000000000000" + }, + "0d1f2a57713ebc6e94de29846e8844d376665763": { + "balance": "5000000000000000000000" + }, + "eab0bd148309186cf8cbd13b7232d8095acb833a": { + "balance": "10691800000000000000000" + }, + "36928b55bc861509d51c8cf1d546bfec6e3e90af": { + "balance": "1970000000000000000000" + }, + "30480164bcd84974ebc0d90c9b9afab626cd1c73": { + "balance": "800000000000000000000" + }, + "36339f84a5c2b44ce53dfdb6d4f97df78212a7df": { + "balance": "321600000000000000000" + }, + "cfeacaaed57285e0ac7268ce6a4e35ecfdb242d7": { + "balance": "1086400000000000000000" + }, + "572dd8cd3fe399d1d0ec281231b7cefc20b9e4bb": { + "balance": "10400000000000000000000" + }, + "5dded049a6e1f329dc4b971e722c9c1f2ade83f0": { + "balance": "1000000000000000000000" + }, + "9756e176c9ef693ee1eec6b9f8b151d313beb099": { + "balance": "1200000000000000000000" + }, + "01e6415d587b065490f1ed7f21d6e0f386ee6747": { + "balance": "2000000000000000000000" + }, + "b4413576869c08f9512ad311fe925988a52d3414": { + "balance": "10000000000000000000000" + }, + "da9f55460946d7bfb570ddec757ca5773b58429a": { + "balance": "507600000000000000000" + }, + "7180b83ee5574317f21c8072b191d895d46153c3": { + "balance": "460000000000000000000" + }, + "0aca9a5626913b08cfc9a66d40508dce52b60f87": { + "balance": "1910000000000000000000" + }, + "5cd0e475b54421bdfc0c12ea8e082bd7a5af0a6a": { + "balance": "59000000000000000000" + }, + "7edb02c61a227287611ad950696369cc4e647a68": { + "balance": "274000000000000000000" + }, + "b2676841ee9f2d31c172e82303b0fe9bbf9f1e09": { + "balance": "200000000000000000000" + }, + "a2222259dd9c3e3ded127084f808e92a1887302c": { + "balance": "162000000000000000000" + }, + "4b3a7cc3a7d7b00ed5282221a60259f25bf6538a": { + "balance": "1000000000000000000000" + }, + "e33ff987541dde5cdee0a8a96dcc3f33c3f24cc2": { + "balance": "200000000000000000000000" + }, + "1e1a4828119be309bd88236e4d482b504dc55711": { + "balance": "2955000000000000000000" + }, + "9b1811c3051f46e664ae4bc9c824d18592c4574a": { + "balance": "199955000000000000000" + }, + "59fe00696dbd87b7976b29d1156c8842a2e17914": { + "balance": "2000000000000000000000" + }, + "48010ef3b8e95e3f308f30a8cb7f4eb4bf60d965": { + "balance": "2000000000000000000000" + }, + "c90300cb1d4077e6a6d7e169a460468cf4a492d7": { + "balance": "2000000000000000000000" + }, + "6dedf62e743f4d2c2a4b87a787f5424a7aeb393c": { + "balance": "180000000000000000000" + }, + "fb744b951d094b310262c8f986c860df9ab1de65": { + "balance": "52009000000000000000" + }, + "193ac65183651800e23580f8f0ead3bb597eb8a4": { + "balance": "50020000000000000000" + }, + "bf05ff5ecf0df2df887759fb8274d93238ac267d": { + "balance": "800000000000000000000" + }, + "6c0e712f405c59725fe829e9774bf4df7f4dd965": { + "balance": "57413800000000000000000" + }, + "2744ff67464121e35afc2922177164fa2fcb0267": { + "balance": "100000000000000000000" + }, + "d09cb2e6082d693a13e8d2f68dd1dd8461f55840": { + "balance": "1000000000000000000000" + }, + "bc171e53d17ac9b61241ae436deec7af452e7496": { + "balance": "5348000000000000000000" + }, + "71fa22cc6d33206b7d701a163a0dab31ae4d31d6": { + "balance": "1610000000000000000000" + }, + "4da8030769844bc34186b85cd4c7348849ff49e9": { + "balance": "10000000000000000000000" + }, + "c8616b4ec09128cdff39d6e4b9ac86eec471d5f2": { + "balance": "19400000000000000000" + }, + "407295ebd94b48269c2d569c9b9af9aa05e83e5e": { + "balance": "10000000000000000000000" + }, + "d45d5daa138dd1d374c71b9019916811f4b20a4e": { + "balance": "576000000000000000000" + }, + "42c6edc515d35557808d13cd44dcc4400b2504e4": { + "balance": "197876000000000000000" + }, + "0bc95cb32dbb574c832fa8174a81356d38bc92ac": { + "balance": "2000000000000000000000" + }, + "5a6071bcebfcba4ab57f4db96fc7a68bece2ba5b": { + "balance": "2000000000000000000000" + }, + "54c93e03a9b2e8e4c3672835a9ee76f9615bc14e": { + "balance": "19400000000000000000" + }, + "3c03bbc023e1e93fa3a3a6e428cf0cd8f95e1ec6": { + "balance": "1520000000000000000000" + }, + "ba1531fb9e791896bcf3a80558a359f6e7c144bd": { + "balance": "3940000000000000000000" + }, + "aa56a65dc4abb72f11bae32b6fbb07444791d5c9": { + "balance": "748600000000000000000" + }, + "e437acbe0f6227b0e36f36e4bcf7cf613335fb68": { + "balance": "200000000000000000000" + }, + "39d4a931402c0c79c457186f24df8729cf957031": { + "balance": "4000000000000000000000" + }, + "e22b20c77894463baf774cc256d5bddbbf7ddd09": { + "balance": "1000000000000000000000" + }, + "70a4067d448cc25dc8e70e651cea7cf84e92109e": { + "balance": "176000000000000000000" + }, + "aa3925dc220bb4ae2177b2883078b6dc346ca1b2": { + "balance": "8000000000000000000000" + }, + "ad57aa9d00d10c439b35efcc0becac2e3955c313": { + "balance": "200000000000000000000" + }, + "e93d47a8ca885d540c4e526f25d5c6f2c108c4b8": { + "balance": "112640000000000000000000" + }, + "232ce782506225fd9860a2edc14a7a3047736da2": { + "balance": "20000000000000000000" + }, + "49a645e0667dfd7b32d075cc2467dd8c680907c4": { + "balance": "129560000000000000000" + }, + "cf2e734042a355d05ffb2e3915b16811f45a695e": { + "balance": "2000000000000000000000" + }, + "39b1c471ae94e12164452e811fbbe2b3cd7275ac": { + "balance": "2000000000000000000000" + }, + "ffad3dd74e2c1f796ac640de56dc99b4c792a402": { + "balance": "5000000000000000000000" + }, + "a69d7cd17d4842fe03f62a90b2fbf8f6af7bb380": { + "balance": "100000000000000000000" + }, + "2001bef77b66f51e1599b02fb110194a0099b78d": { + "balance": "2000000000000000000000" + }, + "95e7616424cd0961a71727247437f0069272280e": { + "balance": "400000000000000000000" + }, + "c04f4bd4049f044685b883b62959ae631d667e35": { + "balance": "5820000000000000000000" + }, + "ede0147ec032c3618310c1ff25690bf172193dac": { + "balance": "2000000000000000000000" + }, + "66719c0682b2ac7f9e27abebec7edf8decf0ae0d": { + "balance": "20000000000000000000" + }, + "45272b8f62e9f9fa8ce04420e1aea3eba9686eac": { + "balance": "4000000000000000000000" + }, + "d1da0c8fb7c210e0f2ec618f85bdae7d3e734b1c": { + "balance": "1970000000000000000000" + }, + "e9133e7d31845d5f2b66a2618792e869311acf66": { + "balance": "24050000000000000000000" + }, + "ebb62cf8e22c884b1b28c6fa88fbbc17938aa787": { + "balance": "798000000000000000000" + }, + "6205c2d5647470848a3840f3887e9b015d34755c": { + "balance": "1800000000000000000000" + }, + "76ca22bcb8799e5327c4aa2a7d0949a1fcce5f29": { + "balance": "1524180000000000000000" + }, + "6b925dd5d8ed6132ab6d0860b82c44e1a51f1fee": { + "balance": "1480000000000000000000" + }, + "797bb7f157d9feaa17f76da4f704b74dc1038341": { + "balance": "3340000000000000000000" + }, + "ae8954f8d6166de507cf61297d0fc7ca6b9e7128": { + "balance": "300000000000000000000" + }, + "75c1ad23d23f24b384d0c3149177e86697610d21": { + "balance": "6426082000000000000000" + }, + "805d846fb0bc02a7337226d685be9ee773b9198a": { + "balance": "19999800000000000000000" + }, + "c3cb6b36af443f2c6e258b4a39553a818747811f": { + "balance": "1610000000000000000000" + }, + "cea43f7075816b60bbfce68b993af0881270f6c4": { + "balance": "2000000000000000000000" + }, + "e0388aeddd3fe2ad56f85748e80e710a34b7c92e": { + "balance": "500000000000000000000" + }, + "e131f87efc5ef07e43f0f2f4a747b551d750d9e6": { + "balance": "19999000000000000000000" + }, + "c2b2cbe65bc6c2ee7a3c75b2e47c189c062e8d8b": { + "balance": "20000000000000000000000" + }, + "bd8765f41299c7f479923c4fd18f126d7229047d": { + "balance": "4000000000000000000000" + }, + "c83ba6dd9549be1d3287a5a654d106c34c6b5da2": { + "balance": "7000000000000000000000" + }, + "f870995fe1e522321d754337a45c0c9d7b38951c": { + "balance": "20000000000000000000" + }, + "0d8ed7d0d15638330ed7e4eaccab8a458d75737e": { + "balance": "2000000000000000000000" + }, + "36c510bf8d6e569bf2f37d47265dbcb502ff2bce": { + "balance": "30000000000000000000000" + }, + "0eccf617844fd61fba62cb0e445b7ac68bcc1fbe": { + "balance": "387260000000000000000" + }, + "ae10e27a014f0d306baf266d4897c89aeee2e974": { + "balance": "20000000000000000000000" + }, + "1827039f09570294088fddf047165c33e696a492": { + "balance": "9550000000000000000000" + }, + "23378f42926d0184b793b0c827a6dd3e3d334fcd": { + "balance": "56000000000000000000" + }, + "467124ae7f452f26b3d574f6088894fa5d1cfb3b": { + "balance": "2700000000000000000000" + }, + "aae61e43cb0d0c96b30699f77e00d711d0a3979b": { + "balance": "1000000000000000000000" + }, + "15c7edb8118ee27b342285eb5926b47a855bc7a5": { + "balance": "20000000000000000000" + }, + "0d5d98565c647ca5f177a2adb9d3022fac287f21": { + "balance": "200000000000000000000" + }, + "7222fec7711781d26eaa4e8485f7aa3fac442483": { + "balance": "456000000000000000000" + }, + "dc44275b1715baea1b0345735a29ac42c9f51b4f": { + "balance": "1164000000000000000000" + }, + "04d82af9e01a936d97f8f85940b970f9d4db9936": { + "balance": "200000000000000000000" + }, + "45533390e340fe0de3b3cf5fb9fc8ea552e29e62": { + "balance": "1460000000000000000000" + }, + "1284f0cee9d2ff2989b65574d06ffd9ab0f7b805": { + "balance": "400000000000000000000" + }, + "ed9ebccba42f9815e78233266dd6e835b6afc31b": { + "balance": "6000000000000000000000" + }, + "e4324912d64ea3aef76b3c2ff9df82c7e13ae991": { + "balance": "2000000000000000000000" + }, + "94c742fd7a8b7906b3bfe4f8904fc0be5c768033": { + "balance": "20000000000000000000000" + }, + "62fb8bd1f0e66b90533e071e6cbe6111fef0bc63": { + "balance": "17600000000000000000000" + }, + "2c83aeb02fcf067d65a47082fd977833ab1cec91": { + "balance": "150400000000000000000" + }, + "06cbfa08cdd4fba737bac407be8224f4eef35828": { + "balance": "593459000000000000000" + }, + "67ee406ea4a7ae6a3a381eb4edd2f09f174b4928": { + "balance": "1036000000000000000000" + }, + "83c23d8a502124ee150f08d71dc6727410a0f901": { + "balance": "33999600000000000000000" + }, + "f7c00cdb1f020310d5acab7b496aaa44b779085e": { + "balance": "1670000000000000000000" + }, + "d096565b7c7407d06536580355fdd6d239144aa1": { + "balance": "250000000000000000000" + }, + "f8d52dcc5f96cc28007b3ecbb409f7e22a646caa": { + "balance": "149200000000000000000" + }, + "0c222c7c41c9b048efcce0a232434362e12d673b": { + "balance": "10007600000000000000000" + }, + "503bdbd8bc421c32a443032deb2e3e4cd5ba8b4e": { + "balance": "2000000000000000000000" + }, + "77da5e6c72fb36bce1d9798f7bcdf1d18f459c2e": { + "balance": "22380000000000000000" + }, + "e62f98650712eb158753d82972b8e99ca3f61877": { + "balance": "2000000000000000000000" + }, + "87a7c508ef71582dd9a54372f89cb01f252fb180": { + "balance": "200000000000000000000" + }, + "f61283b4bd8504058ca360e993999b62cbc8cd67": { + "balance": "255000000000000000000" + }, + "9ccddcb2cfc2b25b08729a0a98d9e6f0202ea2c1": { + "balance": "100000000000000000000" + }, + "d460a4b908dd2b056759b488850b66a838fc77a8": { + "balance": "1970000000000000000000" + }, + "5431b1d18751b98fc9e2888ac7759f1535a2db47": { + "balance": "2000000000000000000000" + }, + "da2a14f9724015d79014ed8e5909681d596148f1": { + "balance": "48499000000000000000" + }, + "c989434f825aaf9c552f685eba7c11db4a5fc73a": { + "balance": "501000000000000000000" + }, + "2b701d16c0d3cc1e4cd85445e6ad02eea4ac012d": { + "balance": "600000000000000000000" + }, + "78b978a9d7e91ee529ea4fc4b76feaf8762f698c": { + "balance": "32000000000000000000000" + }, + "c89cf504b9f3f835181fd8424f5ccbc8e1bddf7d": { + "balance": "10000000000000000000000" + }, + "e94941b6036019b4016a30c1037d5a6903babaad": { + "balance": "780000000000000000000" + }, + "95d98d0c1069908f067a52acac2b8b534da37afd": { + "balance": "2054053000000000000000" + }, + "8284923b62e68bbf7c2b9f3414d13ef6c812a904": { + "balance": "3880000000000000000000" + }, + "3e5a39fdda70df1126ab0dc49a7378311a537a1f": { + "balance": "2400000000000000000000" + }, + "a2ace4c993bb1e5383f8ac74e179066e814f0591": { + "balance": "100000000000000000000" + }, + "0609d83a6ce1ffc9b690f3e9a81e983e8bdc4d9d": { + "balance": "70000000000000000000000" + }, + "d119417c46732cf34d1a1afb79c3e7e2cd8eece4": { + "balance": "2000000000000000000000" + }, + "fdb33944f2360615e5be239577c8a19ba52d9887": { + "balance": "601650000000000000000" + }, + "dd95dbe30f1f1877c5dd7684aeef302ab6885192": { + "balance": "8372000000000000000000" + }, + "413f4b02669ccff6806bc826fcb7deca3b0ea9bc": { + "balance": "20000000000000000000" + }, + "5800cd8130839e94495d2d8415a8ea2c90e0c5cb": { + "balance": "200000000000000000000" + }, + "65053191319e067a25e6361d47f37f6318f83419": { + "balance": "394000000000000000000" + }, + "9bc573bcda23b8b26f9073d90c230e8e71e0270b": { + "balance": "999544000000000000000" + }, + "97f7760657c1e202759086963eb4211c5f8139b9": { + "balance": "49770000000000000000000" + }, + "126897a311a14ad43b78e0920100c4426bfd6bdd": { + "balance": "973581000000000000000" + }, + "d5276f0cd5ffd5ffb63f98b5703d5594ede0838b": { + "balance": "400000000000000000000" + }, + "e9c35c913ca1fceab461582fe1a5815164b4fd21": { + "balance": "8000000000000000000000" + }, + "b43067fe70d9b55973ba58dc64dd7f311e554259": { + "balance": "200000000000000000000" + }, + "6f8f0d15cc96fb7fe94f1065bc6940f8d12957b2": { + "balance": "1000000000000000000000" + }, + "b1dba5250ba9625755246e067967f2ad2f0791de": { + "balance": "80000000000000000000000" + }, + "72b7a03dda14ca9c661a1d469fd33736f673c8e8": { + "balance": "2000000000000000000000" + }, + "e792349ce9f6f14f81d0674096befa1f9221cdea": { + "balance": "1685365000000000000000" + }, + "1815279dff9952da3be8f77249dbe22243377be7": { + "balance": "4749800000000000000000" + }, + "33481e856ebed48ea708a27426ef28e867f57cd1": { + "balance": "200000000000000000000" + }, + "8eb8c71982a00fb84275293253f8044544b66b49": { + "balance": "400000000000000000000" + }, + "65f5870f26bce089677dfc23b5001ee492483428": { + "balance": "5067230000000000000000" + }, + "8e23facd12c765c36ab81a6dd34d8aa9e68918ae": { + "balance": "167310000000000000000" + }, + "4912d902931676ff39fc34fe3c3cc8fb2182fa7a": { + "balance": "20000000000000000000" + }, + "c09a66172aea370d9a63da04ff71ffbbfcff7f94": { + "balance": "2000000000000000000000" + }, + "e969ea1595edc5c4a707cfde380929633251a2b0": { + "balance": "200000000000000000000" + }, + "4f2b47e2775a1fa7178dad92985a5bbe493ba6d6": { + "balance": "200000000000000000000" + }, + "cab9a97ada065c87816e6860a8f1426fe6b3d775": { + "balance": "1000000000000000000000" + }, + "cdfd8217339725d7ebac11a63655f265eff1cc3d": { + "balance": "4999962000000000000000" + }, + "ab4004c0403f7eabb0ea586f212156c4203d67f1": { + "balance": "1999944000000000000000" + }, + "1c7cb2fe6bf3e09cbcdc187af38fa8f5053a70b6": { + "balance": "9970823000000000000000" + }, + "a951b244ff50cfae591d5e1a148df6a938ef2a1a": { + "balance": "1734000000000000000000" + }, + "b158db43fa62d30e65f3d09bf781c7b67372ebaa": { + "balance": "1999000000000000000000" + }, + "25e037f00a18270ba5ec3420229ddb0a2ce38fa2": { + "balance": "10000000000000000000000" + }, + "2aaea1f1046f30f109faec1c63ef5c7594eb08da": { + "balance": "4000000000000000000000" + }, + "73d7269ff06c9ffd33754ce588f74a966abbbbba": { + "balance": "6600000000000000000000" + }, + "4c767b65fd91161f4fbdcc6a69e2f6ad711bb918": { + "balance": "720000000000000000000" + }, + "92ae5b7c7eb492ff1ffa16dd42ad9cad40b7f8dc": { + "balance": "865000000000000000000" + }, + "a04f2ae02add14c12faf65cb259022d0830a8e26": { + "balance": "100000000000000000000000" + }, + "63ef2fbc3daf5edaf4a295629ccf31bcdf4038e5": { + "balance": "1460000000000000000000" + }, + "749ad6f2b5706bbe2f689a44c4b640b58e96b992": { + "balance": "100000000000000000000" + }, + "4d836d9d3b0e2cbd4de050596faa490cffb60d5d": { + "balance": "300000000000000000000" + }, + "59f6247b0d582aaa25e5114765e4bf3c774f43c2": { + "balance": "50000000000000000000" + }, + "1293c78c7d6a443b9d74b0ba5ee7bb47fd418588": { + "balance": "6685000000000000000000" + }, + "67bc85e87dc34c4e80aafa066ba8d29dbb8e438e": { + "balance": "402500000000000000000" + }, + "a09f4d5eaa65a2f4cb750a49923401dae59090af": { + "balance": "140000000000000000000" + }, + "ebbd4db9019952d68b1b0f6d8cf0683c00387bb5": { + "balance": "332330000000000000000" + }, + "b16479ba8e7df8f63e1b95d149cd8529d735c2da": { + "balance": "846477000000000000000" + }, + "e1b2aca154b8e0766c4eba30bc10c7f35036f368": { + "balance": "19980000000000000000" + }, + "5c464197791c8a3da3c925436f277ab13bf2faa2": { + "balance": "8000000000000000000000" + }, + "170a88a8997f92d238370f1affdee6347050b013": { + "balance": "3000800000000000000000" + }, + "dadbfafd8b62b92a24efd75256dd83abdbd7bbdb": { + "balance": "19700000000000000000" + }, + "bb993b96ee925ada7d99d786573d3f89180ce3aa": { + "balance": "2000000000000000000000" + }, + "f2c362b0ef991bc82fb36e66ff75932ae8dd8225": { + "balance": "74000000000000000000" + }, + "7f2382ffd8f83956467937f9ba72374623f11b38": { + "balance": "600000000000000000000" + }, + "74d1a4d0c7524e018d4e06ed3b648092b5b6af2c": { + "balance": "50000000000000000000" + }, + "24a750eae5874711116dd7d47b7186ce990d3103": { + "balance": "200000000000000000000" + }, + "a8e42a4e33d7526cca19d9a36dcd6e8040d0ea73": { + "balance": "1080000000000000000000" + }, + "3e1b2230afbbd310b4926a4c776d5ae7819c661d": { + "balance": "30000000000000000000000" + }, + "6af9f0dfeeaebb5f64bf91ab771669bf05295553": { + "balance": "400000000000000000000" + }, + "41e4a20275e39bdcefeb655c0322744b765140c2": { + "balance": "10000000000000000000000" + }, + "ceb089ec8a78337e8ef88de11b49e3dd910f748f": { + "balance": "1000000000000000000000" + }, + "e6bcd30a8fa138c5d9e5f6c7d2da806992812dcd": { + "balance": "260000000000000000000000" + }, + "e08c60313106e3f9334fe6f7e7624d211130c077": { + "balance": "40000000000000000000" + }, + "f5cffbba624e7eb321bc83c60ca68199b4e36671": { + "balance": "2000000000000000000000" + }, + "d7c2803ed7b0e0837351411a8e6637d168bc5b05": { + "balance": "29549015000000000000000" + }, + "0f3665d48e9f1419cd984fc7fa92788710c8f2e4": { + "balance": "2000000000000000000000" + }, + "b48921c9687d5510744584936e8886bdbf2df69b": { + "balance": "1000000000000000000000" + }, + "a94bbb8214cf8da0c2f668a2ac73e86248528d4b": { + "balance": "960000000000000000000" + }, + "be0c2a80b9de084b172894a76cf4737a4f529e1a": { + "balance": "1999944000000000000000" + }, + "fcf199f8b854222f182e4e1d099d4e323e2aae01": { + "balance": "1000000000000000000000" + }, + "b52dfb45de5d74e3df208332bc571c809b8dcf32": { + "balance": "6000000000000000000000" + }, + "704819d2e44d6ed1da25bfce84c49fcca25613e5": { + "balance": "400000000000000000000" + }, + "6ff6cc90d649de4e96cffee1077a5b302a848dcb": { + "balance": "28600000000000000000" + }, + "4d9c77d0750c5e6fbc247f2fd79274686cb353d6": { + "balance": "20000000000000000000" + }, + "68e8022740f4af29eb48db32bcecddfd148d3de3": { + "balance": "1000000000000000000000" + }, + "2cb615073a40dcdb99faa848572e987b3b056efb": { + "balance": "799600000000000000000" + }, + "64adcceec53dd9d9dd15c8cc1a9e736de4241d2c": { + "balance": "56000000000000000000" + }, + "2aec809df9325b9f483996e99f7331097f08aa0e": { + "balance": "4000000000000000000000" + }, + "438c2f54ff8e629bab36b1442b760b12a88f02ae": { + "balance": "2000000000000000000000" + }, + "9e35399071a4a101e9194daa3f09f04a0b5f9870": { + "balance": "4000000000000000000000" + }, + "a5c336083b04f9471b8c6ed73679b74d66c363ec": { + "balance": "3014100000000000000000" + }, + "7ad3f307616f19dcb143e6444dab9c3c33611f52": { + "balance": "50000000000000000000" + }, + "455cb8ee39ffbc752331e5aefc588ef0ee593454": { + "balance": "999963000000000000000" + }, + "c4c01afc3e0f045221da1284d7878574442fb9ac": { + "balance": "7419944000000000000000" + }, + "99268327c373332e06c3f6164287d455b9d5fa4b": { + "balance": "2000000000000000000000" + }, + "4367ae4b0ce964f4a54afd4b5c368496db169e9a": { + "balance": "2000000000000000000000" + }, + "2cd79eb52027b12c18828e3eaab2969bfcd287e9": { + "balance": "20000000000000000000" + }, + "b96841cabbc7dbd69ef0cf8f81dff3c8a5e21570": { + "balance": "12000000000000000000000" + }, + "d7ebddb9f93987779b680155375438db65afcb6a": { + "balance": "100600000000000000000" + }, + "0631d18bbbbd30d9e1732bf36edae2ce8901ab80": { + "balance": "3024800000000000000000" + }, + "5fad960f6b2c84569c9f4d47bf1985fcb2c65da6": { + "balance": "999972000000000000000" + }, + "01d599ee0d5f8c38ab2d392e2c65b74c3ce31820": { + "balance": "510000000000000000000" + }, + "ff0cc8dac824fa24fc3caa2169e6e057cf638ad6": { + "balance": "4000000000000000000000" + }, + "c25266c7676632f13ef29be455ed948add567792": { + "balance": "1337000000000000000000" + }, + "9c344098ba615a398f11d009905b177c44a7b602": { + "balance": "1000000000000000000000" + }, + "3b0accaf4b607cfe61d17334c214b75cdefdbd89": { + "balance": "2000000000000000000000" + }, + "6d6634b5b8a40195d949027af4828802092ceeb6": { + "balance": "3000000000000000000000" + }, + "208c45732c0a378f17ac8324926d459ba8b658b4": { + "balance": "2955000000000000000000" + }, + "c24399b4bf86f7338fbf645e3b22b0e0b7973912": { + "balance": "2000000000000000000000" + }, + "29763dd6da9a7c161173888321eba6b63c8fb845": { + "balance": "328000000000000000000" + }, + "9c2fd54089af665df5971d73b804616039647375": { + "balance": "1000000000000000000000" + }, + "0e09646c99af438e99fa274cb2f9c856cb65f736": { + "balance": "1910000000000000000000" + }, + "be73274d8c5aa44a3cbefc8263c37ba121b20ad3": { + "balance": "500000000000000000000" + }, + "ecfd004d02f36cd4d8b4a8c1a9533b6af85cd716": { + "balance": "5003800000000000000000" + }, + "f978b025b64233555cc3c19ada7f4199c9348bf7": { + "balance": "400000000000000000000000" + }, + "705ddd38355482b8c7d3b515bda1500dd7d7a817": { + "balance": "400000000000000000000" + }, + "2b8a0dee5cb0e1e97e15cfca6e19ad21f995efad": { + "balance": "504206000000000000000" + }, + "1098cc20ef84bad5146639c4cd1ca6c3996cb99b": { + "balance": "18200000000000000000" + }, + "afdac5c1cb56e245bf70330066a817eaafac4cd1": { + "balance": "20000000000000000000" + }, + "910e996543344c6815fb97cda7af4b8698765a5b": { + "balance": "103400000000000000000" + }, + "94612781033b57b146ee74e753c672017f5385e4": { + "balance": "3600000000000000000000" + }, + "d03fc165576aaed525e5502c8e140f8b2e869639": { + "balance": "6850000000000000000000" + }, + "293384c42b6f8f2905ce52b7205c2274376c612b": { + "balance": "1400000000000000000000" + }, + "09ee12b1b42b05af9cf207d5fcac255b2ec411f2": { + "balance": "58929000000000000000" + }, + "dbd71efa4b93c889e76593de609c3b04cbafbe08": { + "balance": "20000000000000000000" + }, + "fa86ca27bf2854d98870837fb6f6dfe4bf6453fc": { + "balance": "322061000000000000000" + }, + "61ff8e67b34d9ee6f78eb36ffea1b9f7c15787af": { + "balance": "1640000000000000000000" + }, + "6d4cbf3d8284833ae99344303e08b4d614bfda3b": { + "balance": "12000000000000000000000" + }, + "2ff160c44f72a299b5ec2d71e28ce5446d2fcbaf": { + "balance": "360000000000000000000" + }, + "94a7cda8f481f9d89d42c303ae1632b3b709db1d": { + "balance": "300000000000000000000" + }, + "7566496162ba584377be040a4f87777a707acaeb": { + "balance": "4000000000000000000000" + }, + "bdc461462b6322b462bdb33f22799e8108e2417d": { + "balance": "668500000000000000000" + }, + "7e47637e97c14622882be057bea229386f4052e5": { + "balance": "440000000000000000000" + }, + "3b5c251d7fd7893ba209fe541cecd0ce253a990d": { + "balance": "30000000000000000000000" + }, + "0e498800447177b8c8afc3fdfa7f69f4051bb629": { + "balance": "2140234000000000000000" + }, + "b71623f35107cf7431a83fb3d204b29ee0b1a7f4": { + "balance": "19700000000000000000" + }, + "1d395b30adda1cf21f091a4f4a7b753371189441": { + "balance": "100000000000000000000000" + }, + "2c2428e4a66974edc822d5dbfb241b2728075158": { + "balance": "2000000000000000000000" + }, + "a575f2891dcfcda83c5cf01474af11ee01b72dc2": { + "balance": "100076000000000000000" + }, + "ad728121873f0456d0518b80ab6580a203706595": { + "balance": "500000000000000000000" + }, + "48669eb5a801d8b75fb6aa58c3451b7058c243bf": { + "balance": "30940000000000000000000" + }, + "b3ae54fba09d3ee1d6bdd1e957923919024c35fa": { + "balance": "65513000000000000000" + }, + "0d35408f226566116fb8acdaa9e2c9d59b76683f": { + "balance": "940000000000000000000" + }, + "df211cd21288d6c56fae66c3ff54625dd4b15427": { + "balance": "2500024000000000000000" + }, + "8a746c5d67064711bfca685b95a4fe291a27028e": { + "balance": "40000000000000000000" + }, + "1cf105ab23023b554c583e86d7921179ee83169f": { + "balance": "1970000000000000000000" + }, + "8cfedef198db0a9143f09129b3fd64dcbb9b4956": { + "balance": "2000000000000000000000" + }, + "1e381adcf801a3bf9fd7bfac9ccc2b8482ad5e66": { + "balance": "600200000000000000000" + }, + "e74608f506866ada6bfbfdf20fea440be76989ef": { + "balance": "1999944000000000000000" + }, + "27e63989ca1e903bc620cf1b9c3f67b9e2ae6581": { + "balance": "1337000000000000000000" + }, + "bb0857f1c911b24b86c8a70681473fe6aaa1cce2": { + "balance": "100000000000000000000" + }, + "4f8e8d274fb22a3fd36a47fe72980471544b3434": { + "balance": "200000000000000000000" + }, + "127d3fc5003bf63c0d83e93957836515fd279045": { + "balance": "111890000000000000000" + }, + "95809e8da3fbe4b7f281f0b8b1715f420f7d7d63": { + "balance": "2000000000000000000000" + }, + "28904bb7c4302943b709b14d7970e42b8324e1a1": { + "balance": "10027500000000000000000" + }, + "c07e3867ada096807a051a6c9c34cc3b3f4ad34a": { + "balance": "1788210000000000000000" + }, + "f0b469eae89d400ce7d5d66a9695037036b88903": { + "balance": "20000000000000000000000" + }, + "7445202f0c74297a004eb3726aa6a82dd7c02fa1": { + "balance": "2000000000000000000000" + }, + "c58f62fee9711e6a05dc0910b618420aa127f288": { + "balance": "3980000000000000000000" + }, + "801d65c518b11d0e3f4f470221417013c8e53ec5": { + "balance": "4000000000000000000000" + }, + "41010fc8baf8437d17a04369809a168a17ca56fb": { + "balance": "100000000000000000000" + }, + "a1998144968a5c70a6415554cefec2824690c4a5": { + "balance": "20000000000000000000" + }, + "e9559185f166fc9513cc71116144ce2deb0f1d4b": { + "balance": "20000000000000000000000" + }, + "ed5b4c41e762d942404373caf21ed4615d25e6c1": { + "balance": "2013960000000000000000" + }, + "665b000f0b772750cc3c217a5ef429a92bf1ccbb": { + "balance": "4000000000000000000000" + }, + "febd9f81cf78bd5fb6c4b9a24bd414bb9bfa4c4e": { + "balance": "1990019000000000000000" + }, + "a072691c8dd7cd4237ff72a75c1a9506d0ce5b9e": { + "balance": "370000000000000000000" + }, + "6765df25280e8e4f38d4b1cf446fc5d7eb659e34": { + "balance": "100000000000000000000" + }, + "524fb210522c5e23bb67dfbf8c26aa616da49955": { + "balance": "999971000000000000000" + }, + "e987e6139e6146a717fef96bc24934a5447fe05d": { + "balance": "2000000000000000000000" + }, + "d6110276cfe31e42825a577f6b435dbcc10cf764": { + "balance": "1000000000000000000000" + }, + "5e51b8a3bb09d303ea7c86051582fd600fb3dc1a": { + "balance": "20000000000000000000" + }, + "5c4f24e994ed8f850ea7818f471c8fac3bcf0452": { + "balance": "1724800000000000000000" + }, + "85b2998d0c73302cb2ba13f489313301e053be15": { + "balance": "10000000000000000000000" + }, + "0af6c8d539c96d50259e1ba6719e9c8060f388c2": { + "balance": "1000000000000000000000" + }, + "7d901b28bf7f88ef73d8f73cca97564913ea8a24": { + "balance": "955000000000000000000" + }, + "e01859f242f1a0ec602fa8a3b0b57640ec89075e": { + "balance": "555000000000000000000" + }, + "c66ae4cee87fb3353219f77f1d6486c580280332": { + "balance": "29550000000000000000" + }, + "2d40558b06f90a3923145592123b6774e46e31f4": { + "balance": "1000000000000000000000" + }, + "ccf43975b76bfe735fec3cb7d4dd24f805ba0962": { + "balance": "60000000000000000000" + }, + "1703b4b292b8a9deddede81bb25d89179f6446b6": { + "balance": "19690000000000000000000" + }, + "0e9096d343c060db581a120112b278607ec6e52b": { + "balance": "20000000000000000000" + }, + "f65819ac4cc14c137f05dd7977c7dae08d1a4ab5": { + "balance": "102000000000000000000" + }, + "ca373fe3c906b8c6559ee49ccd07f37cd4fb5266": { + "balance": "1790000000000000000000" + }, + "d28298524df5ec4b24b0ffb9df85170a145a9eb5": { + "balance": "287700000000000000000" + }, + "5fcda847aaf8d7fa8bca08029ca2849166aa15a3": { + "balance": "623350000000000000000" + }, + "bdc739a699700b2e8e2c4a4c7b058a0e513ddebe": { + "balance": "2000000000000000000000" + }, + "0bb05f7224bb5804856556c07eeadbed87ba8f7c": { + "balance": "401100000000000000000" + }, + "ab416fe30d58afe5d9454c7fce7f830bcc750356": { + "balance": "114515000000000000000" + }, + "3eee6f1e96360b7689b3069adaf9af8eb60ce481": { + "balance": "1000000000000000000000" + }, + "9a0d3cee3d9892ea3b3700a27ff84140d9025493": { + "balance": "60000000000000000000" + }, + "5dc36de5359450a1ec09cb0c44cf2bb42b3ae435": { + "balance": "1117500000000000000000" + }, + "35c8adc11125432b3b77acd64625fe58ebee9d66": { + "balance": "2000000000000000000000" + }, + "a5e9cd4b74255d22b7d9b27ae8dd43ed6ed0252b": { + "balance": "766527000000000000000" + }, + "31ea12d49a35a740780ddeeaece84c0835b26270": { + "balance": "200000000000000000000" + }, + "7aef7b551f0b9c46e755c0f38e5b3a73fe1199f5": { + "balance": "1490000000000000000000" + }, + "cc6d7b12061bc96d104d606d65ffa32b0036eb07": { + "balance": "10000000000000000000000" + }, + "322021022678a0166d204b3aaa7ad4ec4b88b7d0": { + "balance": "400000000000000000000" + }, + "b31196714a48dff726ea9433cd2912f1a414b3b3": { + "balance": "2680000000000000000000" + }, + "0f2fb884c8aaff6f543ac6228bd08e4f60b0a5fd": { + "balance": "3145000000000000000000" + }, + "7d9d221a3df89ddd7b5f61c1468c6787d6b333e6": { + "balance": "138000000000000000000" + }, + "367f59cc82795329384e41e1283115e791f26a01": { + "balance": "2000000000000000000000" + }, + "fd9579f119bbc819a02b61e38d8803c942f24d32": { + "balance": "105600000000000000000" + }, + "3e2f26235e137a7324e4dc154b5df5af46ea1a49": { + "balance": "22458000000000000000" + }, + "4c1579af3312e4f88ae93c68e9449c2e9a68d9c4": { + "balance": "2000000000000000000000" + }, + "ffb04726dfa41afdc819168418610472970d7bfc": { + "balance": "4000000000000000000000" + }, + "403c64896a75cad816a9105e18d8aa5bf80f238e": { + "balance": "985000000000000000000" + }, + "5cd588a14ec648ccf64729f9167aa7bf8be6eb3d": { + "balance": "1000000000000000000000" + }, + "24b2be118b16d8b2174769d17b4cf84f07ca946d": { + "balance": "2000000000000000000000" + }, + "d3bb59fa31258be62f8ed232f1a7d47b4a0b41ee": { + "balance": "100000000000000000000" + }, + "cc9ac715cd6f2610c52b58676456884297018b29": { + "balance": "13370000000000000000" + }, + "6f2a31900e240395b19f159c1d00dfe4d898ebdf": { + "balance": "1999600000000000000000" + }, + "d60b247321a32a5affb96b1e279927cc584de943": { + "balance": "2265500000000000000000" + }, + "f7a1ade2d0f529123d1055f19b17919f56214e67": { + "balance": "500000000000000000000" + }, + "bea00df17067a43a82bc1daecafb6c14300e89e6": { + "balance": "1820000000000000000000" + }, + "a2968fc1c64bac0b7ae0d68ba949874d6db253f4": { + "balance": "20000000000000000000000" + }, + "92d8ad9a4d61683b80d4a6672e84c20d62421e80": { + "balance": "20000000000000000000" + }, + "6ed2a12b02f8c688c7b5d3a6ea14d63687dab3b6": { + "balance": "2000000000000000000000" + }, + "7a63869fc767a4c6b1cd0e0649f3634cb121d24b": { + "balance": "77500000000000000000" + }, + "84f522f0520eba52dd18ad21fa4b829f2b89cb97": { + "balance": "4949566000000000000000" + }, + "d6234aaf45c6f22e66a225ffb93add629b4ef80f": { + "balance": "1000000000000000000000" + }, + "e3d8bf4efe84b1616d1b89e427ddc6c8830685ae": { + "balance": "2000000000000000000000" + }, + "a3db364a332d884ba93b2617ae4d85a1489bea47": { + "balance": "1700000000000000000000" + }, + "9f7986924aeb02687cd64189189fb167ded2dd5c": { + "balance": "985000000000000000000" + }, + "2eaf4e2a46b789ccc288c8d1d9294e3fb0853896": { + "balance": "2000000000000000000000" + }, + "a02dc6aa328b880de99eac546823fccf774047fb": { + "balance": "1970000000000000000000" + }, + "873b7f786d3c99ff012c4a7cae2677270240b9c5": { + "balance": "1730000000000000000000" + }, + "1d69c83d28ff0474ceebeacb3ad227a144ece7a3": { + "balance": "5474937000000000000000" + }, + "7b827cae7ff4740918f2e030ab26cb98c4f46cf5": { + "balance": "7460000000000000000000" + }, + "3083ef0ed4c4401196774a95cf4edc83edc1484f": { + "balance": "170000000000000000000000" + }, + "40ad74bc0bce2a45e52f36c3debb1b3ada1b7619": { + "balance": "6790000000000000000000" + }, + "05423a54c8d0f9707e704173d923b946edc8e700": { + "balance": "127543000000000000000" + }, + "22eb7db0ba56b0f8b816ccb206e615d929185b0d": { + "balance": "80500000000000000000" + }, + "66082c75a8de31a53913bbd44de3a0374f7faa41": { + "balance": "1460000000000000000000" + }, + "e3d3eaa299887865569e88be219be507189be1c9": { + "balance": "456156000000000000000" + }, + "ae57cc129a96a89981dac60d2ffb877d5dc5e432": { + "balance": "1110994000000000000000" + }, + "1a2434cc774422d48d53d59c5d562cce8407c94b": { + "balance": "30000000000000000000" + }, + "21546914dfd3af2add41b0ff3e83ffda7414e1e0": { + "balance": "5969100000000000000000" + }, + "4dcf62a3de3f061db91498fd61060f1f6398ff73": { + "balance": "1999944000000000000000" + }, + "6fd98e563d12ce0fd60f4f1f850ae396a9823c02": { + "balance": "1261000000000000000000" + }, + "edf8a3e1d40f13b79ec8e3e1ecf262fd92116263": { + "balance": "158000000000000000000" + }, + "c09e3cfc19f605ff3ec9c9c70e2540d7ee974366": { + "balance": "500000000000000000000" + }, + "953572f0ea6df9b197cae40e4b8ecc056c4371c5": { + "balance": "1000000000000000000000" + }, + "163cc8be227646cb09719159f28ed09c5dc0dce0": { + "balance": "1337000000000000000000" + }, + "a3932a31d6ff75fb3b1271ace7caa7d5e1ff1051": { + "balance": "20000000000000000000000" + }, + "f9a94bd56198da245ed01d1e6430b24b2708dcc0": { + "balance": "749938000000000000000" + }, + "3eb8b33b21d23cda86d8288884ab470e164691b5": { + "balance": "500000000000000000000" + }, + "84bcbf22c09607ac84341d2edbc03bfb1739d744": { + "balance": "500000000000000000000" + }, + "961c59adc74505d1864d1ecfcb8afa0412593c93": { + "balance": "40000000000000000000000" + }, + "f068dfe95d15cd3a7f98ffa688b4346842be2690": { + "balance": "1255160000000000000000" + }, + "291efe0081dce8c14799f7b2a43619c0c3b3fc1f": { + "balance": "1200000000000000000000" + }, + "be4fd073617022b67f5c13499b827f763639e4e3": { + "balance": "2000000000000000000000" + }, + "e40a7c82e157540a0b00901dbb86c716e1a062da": { + "balance": "49800000000000000000" + }, + "6635b46f711d2da6f0e16370cd8ee43efb2c2d52": { + "balance": "2000000000000000000000" + }, + "43748928e8c3ec4436a1d092fbe43ac749be1251": { + "balance": "400000000000000000000" + }, + "b557ab9439ef50d237b553f02508364a466a5c03": { + "balance": "200000000000000000000" + }, + "11928378d27d55c520ceedf24ceb1e822d890df0": { + "balance": "8000000000000000000000" + }, + "61518464fdd8b73c1bb6ac6db600654938dbf17a": { + "balance": "200000000000000000000" + }, + "004bfbe1546bc6c65b5c7eaa55304b38bbfec6d3": { + "balance": "2000000000000000000000" + }, + "a5e0fc3c3affed3db6710947d1d6fb017f3e276d": { + "balance": "2000000000000000000000" + }, + "8ecbcfacbfafe9f00c3922a24e2cf0026756ca20": { + "balance": "5640000000000000000000" + }, + "fb5ffaa0f7615726357891475818939d2037cf96": { + "balance": "20000000000000000000" + }, + "ae222865799079aaf4f0674a0cdaab02a6d570ff": { + "balance": "2000000000000000000000" + }, + "9edc90f4be210865214ab5b35e5a8dd77415279d": { + "balance": "4000000000000000000000" + }, + "9d7831e834c20b1baa697af1d8e0c621c5afff9a": { + "balance": "86500000000000000000" + }, + "046d274b1af615fb505a764ad8dda770b1db2f3d": { + "balance": "2000000000000000000000" + }, + "eaea23aa057200e7c9c15e8ff190d0e66c0c0e83": { + "balance": "2000000000000000000000" + }, + "417a3cd19496530a6d4204c3b5a17ce0f207b1a5": { + "balance": "8000000000000000000000" + }, + "a035a3652478f82dbd6d115faa8ca946ec9e681d": { + "balance": "109880000000000000000" + }, + "4f5801b1eb30b712d8a0575a9a71ff965d4f34eb": { + "balance": "300000000000000000000" + }, + "91dbb6aaad149585be47375c5d6de5ff09191518": { + "balance": "20000000000000000000000" + }, + "d043a011ec4270ee7ec8b968737515e503f83028": { + "balance": "500000000000000000000" + }, + "bb371c72c9f0316cea2bd9c6fbb4079e775429ef": { + "balance": "1760000000000000000000" + }, + "aa1df92e51dff70b1973e0e924c66287b494a178": { + "balance": "534400000000000000000" + }, + "bd5f46caab2c3d4b289396bbb07f203c4da82530": { + "balance": "80000000000000000000" + }, + "4d29fc523a2c1629532121da9998e9b5ab9d1b45": { + "balance": "15800000000000000000" + }, + "addb26317227f45c87a2cb90dc4cfd02fb23caf8": { + "balance": "1000000000000000000000" + }, + "52e46783329a769301b175009d346768f4c87ee4": { + "balance": "2000000000000000000000" + }, + "caad9dc20d589ce428d8fda3a9d53a607b7988b5": { + "balance": "4000000000000000000000" + }, + "95034e1621865137cd4739b346dc17da3a27c34e": { + "balance": "1580000000000000000000" + }, + "0c3239e2e841242db989a61518c22247e8c55208": { + "balance": "263656000000000000000" + }, + "5a0d609aae2332b137ab3b2f26615a808f37e433": { + "balance": "160000000000000000000000" + }, + "2334c590c7a48769103045c5b6534c8a3469f44a": { + "balance": "17443200000000000000000" + }, + "ddfcca13f934f0cfbe231da13039d70475e6a1d0": { + "balance": "1000169000000000000000" + }, + "ee7288d91086d9e2eb910014d9ab90a02d78c2a0": { + "balance": "2000000000000000000000" + }, + "fb91fb1a695553f0c68e21276decf0b83909b86d": { + "balance": "100016000000000000000" + }, + "38695fc7e1367ceb163ebb053751f9f68ddb07a0": { + "balance": "2000000000000000000000" + }, + "65093b239bbfba23c7775ca7da5a8648a9f54cf7": { + "balance": "400000000000000000000" + }, + "73d8fee3cb864dce22bb26ca9c2f086d5e95e63b": { + "balance": "1000000000000000000000" + }, + "f7155213449892744bc60f2e04400788bd041fdd": { + "balance": "66850000000000000000" + }, + "d1a71b2d0858e83270085d95a3b1549650035e23": { + "balance": "14900000000000000000000" + }, + "eac17b81ed5191fb0802aa54337313834107aaa4": { + "balance": "8000000000000000000000" + }, + "bb076aac92208069ea318a31ff8eeb14b7e996e3": { + "balance": "149000000000000000000" + }, + "9f46e7c1e9078cae86305ac7060b01467d6685ee": { + "balance": "668500000000000000000" + }, + "1598127982f2f8ad3b6b8fc3cf27bf617801ba2b": { + "balance": "173000000000000000000" + }, + "e91dac0195b19e37b59b53f7c017c0b2395ba44c": { + "balance": "1880000000000000000000" + }, + "a436c75453ccca4a1f1b62e5c4a30d86dde4be68": { + "balance": "2000000000000000000000" + }, + "11001b89ed873e3aaec1155634b4681643986323": { + "balance": "1000000000000000000000" + }, + "ab93b26ece0a0aa21365afed1fa9aea31cd54468": { + "balance": "1608000000000000000000" + }, + "e77febabdf080f0f5dca1d3f5766f2a79c0ffa7c": { + "balance": "1386000000000000000000" + }, + "1c4af0e863d2656c8635bc6ffec8dd9928908cb5": { + "balance": "2000000000000000000000" + }, + "0c48ae62d1539788eba013d75ea60b64eeba4e80": { + "balance": "2213311000000000000000" + }, + "423cc4594cf4abb6368de59fd2b1230734612143": { + "balance": "2000000000000000000000" + }, + "7f6b28c88421e4857e459281d78461692489d3fb": { + "balance": "2000000000000000000000" + }, + "806854588ecce541495f81c28a290373df0274b2": { + "balance": "582000000000000000000" + }, + "dc76e85ba50b9b31ec1e2620bce6e7c8058c0eaf": { + "balance": "20000000000000000000" + }, + "b00996b0566ecb3e7243b8227988dcb352c21899": { + "balance": "12000000000000000000000" + }, + "f5d14552b1dce0d6dc1f320da6ffc8a331cd6f0c": { + "balance": "1337000000000000000000" + }, + "55a61b109480b5b2c4fcfdef92d90584160c0d35": { + "balance": "44700000000000000000" + }, + "b8947822d5ace7a6ad8326e95496221e0be6b73d": { + "balance": "20000000000000000000" + }, + "492de46aaf8f1d708d59d79af1d03ad2cb60902f": { + "balance": "2000000000000000000000" + }, + "0e0d6633db1e0c7f234a6df163a10e0ab39c200f": { + "balance": "200000000000000000000" + }, + "f8bf9c04874e5a77f38f4c38527e80c676f7b887": { + "balance": "2000000000000000000000" + }, + "15528350e0d9670a2ea27f7b4a33b9c0f9621d21": { + "balance": "4000086000000000000000" + }, + "eccf7a0457b566b346ca673a180f444130216ac3": { + "balance": "100000000000000000000" + }, + "10cf560964ff83c1c9674c783c0f73fcd89943fc": { + "balance": "40000000000000000000000" + }, + "e7f06f699be31c440b43b4db0501ec0e25261644": { + "balance": "500000000000000000000" + }, + "b6ce4dc560fc73dc69fb7a62e388db7e72ea764f": { + "balance": "966000000000000000000" + }, + "f456055a11ab91ff668e2ec922961f2a23e3db25": { + "balance": "18200000000000000000" + }, + "8dfbafbc0e5b5c86cd1ad697feea04f43188de96": { + "balance": "390060000000000000000" + }, + "085b4ab75d8362d914435cedee1daa2b1ee1a23b": { + "balance": "3880000000000000000000" + }, + "e400d651bb3f2d23d5f849e6f92d9c5795c43a8a": { + "balance": "2674000000000000000000" + }, + "851aa91c82f42fad5dd8e8bb5ea69c8f3a5977d1": { + "balance": "148607000000000000000" + }, + "4c935bb250778b3c4c7f7e07fc251fa630314aab": { + "balance": "1500000000000000000000" + }, + "ebd356156a383123343d48843bffed6103e866b3": { + "balance": "1970000000000000000000" + }, + "da0b48e489d302b4b7bf204f957c1c9be383b0df": { + "balance": "2000000000000000000000" + }, + "7085ae7e7e4d932197b5c7858c00a3674626b7a5": { + "balance": "6000000000000000000000" + }, + "5b06d1e6930c1054692b79e3dbe6ecce53966420": { + "balance": "205400000000000000000" + }, + "8df53d96191471e059de51c718b983e4a51d2afd": { + "balance": "32000000000000000000000" + }, + "0678654ac6761db904a2f7e8595ec1eaac734308": { + "balance": "878000000000000000000" + }, + "89fee30d1728d96cecc1dab3da2e771afbcfaa41": { + "balance": "1999944000000000000000" + }, + "59c5d06b170ee4d26eb0a0eb46cb7d90c1c91019": { + "balance": "10000000000000000000000" + }, + "2b129c26b75dde127f8320bd0f63410c92a9f876": { + "balance": "2200000000000000000000" + }, + "3d6ae053fcbc318d6fd0fbc353b8bf542e680d27": { + "balance": "14300000000000000000" + }, + "755a60bf522fbd8fff9723446b7e343a7068567e": { + "balance": "20000000000000000000000" + }, + "947e11e5ea290d6fc3b38048979e0cd44ec7c17f": { + "balance": "2000000000000000000000" + }, + "711ecf77d71b3d0ea95ce4758afecdb9c131079d": { + "balance": "760000000000000000000" + }, + "de9eff4c798811d968dccb460d9b069cf30278e0": { + "balance": "400000000000000000000" + }, + "4e892e8081bf36e488fddb3b2630f3f1e8da30d2": { + "balance": "12003800000000000000000" + }, + "8ede7e3dc50749c6c50e2e28168478c34db81946": { + "balance": "19999800000000000000000" + }, + "0c30cacc3f72269f8b4f04cf073d2b05a83d9ad1": { + "balance": "2001000000000000000000" + }, + "e51eb87e7fb7311f5228c479b48ec9878831ac4c": { + "balance": "2000000000000000000000" + }, + "8b01da34d470c1d115acf4d8113c4dd8a8c338e4": { + "balance": "25220000000000000000000" + }, + "4329fc0931cbeb033880fe4c9398ca45b0e2d11a": { + "balance": "2000400000000000000000" + }, + "540c072802014ef0d561345aec481e8e11cb3570": { + "balance": "8000000000000000000000" + }, + "21e5d2bae995ccfd08a5c16bb524e1f630448f82": { + "balance": "2800000000000000000000" + }, + "5cf8c03eb3e872e50f7cfd0c2f8d3b3f2cb5183a": { + "balance": "200000000000000000000" + }, + "5c0f2e51378f6b0d7bab617331580b6e39ad3ca5": { + "balance": "9600000000000000000000" + }, + "d2f241255dd7c3f73c07043071ec08ddd9c5cde5": { + "balance": "500000000000000000000" + }, + "cbe1b948864d8474e765145858fca4550f784b92": { + "balance": "10000000000000000000000" + }, + "30742ccdf4abbcd005681f8159345c9e79054b1a": { + "balance": "668500000000000000000" + }, + "6aeb9f74742ea491813dbbf0d6fcde1a131d4db3": { + "balance": "440800000000000000000" + }, + "821eb90994a2fbf94bdc3233910296f76f9bf6e7": { + "balance": "10000000000000000000000" + }, + "25c1a37ee5f08265a1e10d3d90d5472955f97806": { + "balance": "1820000000000000000000" + }, + "7ef98b52bee953bef992f305fda027f8911c5851": { + "balance": "514717000000000000000" + }, + "8adc53ef8c18ed3051785d88e996f3e4b20ecd51": { + "balance": "42000000000000000000000" + }, + "007f4a23ca00cd043d25c2888c1aa5688f81a344": { + "balance": "773658000000000000000" + }, + "4a735d224792376d331367c093d31c8794341582": { + "balance": "1900000000000000000000" + }, + "05440c5b073b529b4829209dff88090e07c4f6f5": { + "balance": "1288000000000000000000" + }, + "5e772e27f28800c50dda973bb33e10762e6eea20": { + "balance": "1790000000000000000000" + }, + "a429fa88731fdd350e8ecd6ea54296b6484fe695": { + "balance": "1969606000000000000000" + }, + "e0d76b7166b1f3a12b4091ee2b29de8caa7d07db": { + "balance": "2000000000000000000000" + }, + "7ebd95e9c470f7283583dc6e9d2c4dce0bea8f84": { + "balance": "14000000000000000000000" + }, + "883a78aeabaa50d8ddd8570bcd34265f14b19363": { + "balance": "3879951000000000000000" + }, + "51f9c432a4e59ac86282d6adab4c2eb8919160eb": { + "balance": "530000000000000000000000" + }, + "b86607021b62d340cf2652f3f95fd2dc67698bdf": { + "balance": "5000000000000000000000" + }, + "acc0909fda2ea6b7b7a88db7a0aac868091ddbf6": { + "balance": "22155000000000000000" + }, + "69b80ed90f84834afa3ff82eb964703b560977d6": { + "balance": "26740000000000000000" + }, + "ca4ca9e4779d530ecbacd47e6a8058cfde65d98f": { + "balance": "800000000000000000000" + }, + "5d6c5c720d66a6abca8397142e63d26818eaab54": { + "balance": "40000000000000000000" + }, + "c2c13e72d268e7150dc799e7c6cf03c88954ced7": { + "balance": "700000000000000000000" + }, + "6bbd1e719390e6b91043f8b6b9df898ea8001b34": { + "balance": "2000053000000000000000" + }, + "a9ba6f413b82fcddf3affbbdd09287dcf50415ca": { + "balance": "4000000000000000000000" + }, + "ced3c7be8de7585140952aeb501dc1f876ecafb0": { + "balance": "4000000000000000000000" + }, + "1c63fa9e2cbbf23c49fcdef1cbabfe6e0d1e14c1": { + "balance": "1000000000000000000000" + }, + "7d6e990daa7105de2526339833f77b5c0b85d84f": { + "balance": "20000000000000000000000" + }, + "68addf019d6b9cab70acb13f0b3117999f062e12": { + "balance": "49941000000000000000" + }, + "a77428bcb2a0db76fc8ef1e20e461a0a32c5ac15": { + "balance": "401100000000000000000" + }, + "26048fe84d9b010a62e731627e49bc2eb73f408f": { + "balance": "4000000000000000000000" + }, + "ff26138330274df4e0a3081e6df7dd983ec6e78f": { + "balance": "2000000000000000000000" + }, + "b7382d37db0398ac72410cf9813de9f8e1ec8dad": { + "balance": "1000070000000000000000" + }, + "44f62f2aaabc29ad3a6b04e1ff6f9ce452d1c140": { + "balance": "17000000000000000000000" + }, + "47fef58584465248a0810d60463ee93e5a6ee8d3": { + "balance": "283100000000000000000" + }, + "bd2b70fecc37640f69514fc7f3404946aad86b11": { + "balance": "1200000000000000000000" + }, + "649a85b93653075fa6562c409a565d087ba3e1ba": { + "balance": "2000000000000000000000" + }, + "55866486ec168f79dbe0e1abb18864d98991ae2c": { + "balance": "16100000000000000000" + }, + "d7e74afdbad55e96cebc5a374f2c8b768680f2b0": { + "balance": "99000000000000000000" + }, + "a8c1d6aa41fe3d65f67bd01de2a866ed1ed9ae52": { + "balance": "30000000000000000000" + }, + "744c0c77ba7f236920d1e434de5da33e48ebf02c": { + "balance": "1970000000000000000000" + }, + "9445ba5c30e98961b8602461d0385d40fbd80311": { + "balance": "10000000000000000000000" + }, + "eb835c1a911817878a33d167569ea3cdd387f328": { + "balance": "1000000000000000000000" + }, + "761a6e362c97fbbd7c5977acba2da74687365f49": { + "balance": "183840000000000000000" + }, + "38202c5cd7078d4f887673ab07109ad8ada89720": { + "balance": "1000000000000000000000" + }, + "5abfec25f74cd88437631a7731906932776356f9": { + "balance": "11901484239480000000000000" + }, + "28e4af30cd93f686a122ad7bb19f8a8785eee342": { + "balance": "2101000000000000000000" + }, + "3a9b111029ce1f20c9109c7a74eeeef34f4f2eb2": { + "balance": "4000000000000000000000" + }, + "7bb9571f394b0b1a8eba5664e9d8b5e840677bea": { + "balance": "19700000000000000000" + }, + "50fb36c27107ee2ca9a3236e2746cca19ace6b49": { + "balance": "2000000000000000000000" + }, + "a3bc979b7080092fa1f92f6e0fb347e28d995045": { + "balance": "2800000000000000000000" + }, + "d04b861b3d9acc563a901689941ab1e1861161a2": { + "balance": "20000000000000000000" + }, + "58c555bc293cdb16c6362ed97ae9550b92ea180e": { + "balance": "20000000000000000000" + }, + "8bf02bd748690e1fd1c76d270833048b66b25fd3": { + "balance": "11800000000000000000000" + }, + "fbc01db54e47cdc3c438694ab717a856c23fe6e9": { + "balance": "8456774000000000000000" + }, + "9c9a07a8e57c3172a919ef64789474490f0d9f51": { + "balance": "10000000000000000000000" + }, + "fc7e22a503ec5abe9b08c50bd14999f520fa4884": { + "balance": "6387725000000000000000" + }, + "9b773669e87d76018c090f8255e54409b9dca8b2": { + "balance": "20000000000000000000" + }, + "ffe8cbc1681e5e9db74a0f93f8ed25897519120f": { + "balance": "1507000000000000000000" + }, + "4d4cf5807429615e30cdface1e5aae4dad3055e6": { + "balance": "600000000000000000000" + }, + "cfde0fc75d6f16c443c3038217372d99f5d907f7": { + "balance": "2419000000000000000000" + }, + "818ffe271fc3973565c303f213f6d2da89897ebd": { + "balance": "5734655000000000000000" + }, + "ba1fcaf223937ef89e85675503bdb7ca6a928b78": { + "balance": "640000000000000000000" + }, + "a30a45520e5206d9004070e6af3e7bb2e8dd5313": { + "balance": "400000000000000000000" + }, + "a747439ad0d393b5a03861d77296326de8bb9db9": { + "balance": "1000000000000000000000" + }, + "14d00aad39a0a7d19ca05350f7b03727f08dd82e": { + "balance": "500000000000000000000" + }, + "551999ddd205563327b9b530785acff9bc73a4ba": { + "balance": "6000000000000000000000" + }, + "a4670731175893bbcff4fa85ce97d94fc51c4ba8": { + "balance": "8000000000000000000000" + }, + "f858171a04d357a13b4941c16e7e55ddd4941329": { + "balance": "41984000000000000000" + }, + "a6484cc684c4c91db53eb68a4da45a6a6bda3067": { + "balance": "6000000000000000000000" + }, + "00d75ed60c774f8b3a5a5173fb1833ad7105a2d9": { + "balance": "2005500000000000000000" + }, + "bf92418a0c6c31244d220260cb3e867dd7b4ef49": { + "balance": "99800000000000000000" + }, + "716d50cca01e938500e6421cc070c3507c67d387": { + "balance": "2000000000000000000000" + }, + "82a8b96b6c9e13ebec1e9f18ac02a60ea88a48ff": { + "balance": "1999998000000000000000" + }, + "5a565285374a49eedd504c957d510874d00455bc": { + "balance": "100000000000000000000" + }, + "778c79f4de1953ebce98fe8006d53a81fb514012": { + "balance": "999800000000000000000" + }, + "41b2d34fde0b1029262b4172c81c1590405b03ae": { + "balance": "1000000000000000000000" + }, + "4039bd50a2bde15ffe37191f410390962a2b8886": { + "balance": "200000000000000000000" + }, + "c033be10cb48613bd5ebcb33ed4902f38b583003": { + "balance": "3000000000000000000000" + }, + "5d5751819b4f3d26ed0c1ac571552735271dbefa": { + "balance": "1000000000000000000000" + }, + "b600429752f399c80d0734744bae0a022eca67c6": { + "balance": "20000000000000000000" + }, + "f875619d8a23e45d8998d184d480c0748970822a": { + "balance": "4000000000000000000000" + }, + "71c7230a1d35bdd6819ed4b9a88e94a0eb0786dd": { + "balance": "4365000000000000000000" + }, + "b2f9c972c1e9737755b3ff1b3088738396395b26": { + "balance": "20000000000000000000000" + }, + "a66a4963b27f1ee1932b172be5964e0d3ae54b51": { + "balance": "173000000000000000000" + }, + "53ce88e66c5af2f29bbd8f592a56a3d15f206c32": { + "balance": "140840000000000000000" + }, + "433e3ba1c51b810fc467d5ba4dea42f7a9885e69": { + "balance": "40000000000000000000000" + }, + "c7837ad0a0bf14186937ace06c5546a36aa54f46": { + "balance": "4000000000000000000000" + }, + "c3f8f67295a5cd049364d05d23502623a3e52e84": { + "balance": "6000000000000000000000" + }, + "3fd0bb47798cf44cdfbe4d333de637df4a00e45c": { + "balance": "100040000000000000000" + }, + "a1ae8d4540d4db6fdde7146f415b431eb55c7983": { + "balance": "197000000000000000000" + }, + "5cccf1508bfd35c20530aa642500c10dee65eaed": { + "balance": "850000000000000000000" + }, + "a53ead54f7850af21438cbe07af686279a315b86": { + "balance": "10000000000000000000000" + }, + "8cf6da0204dbc4860b46ad973fc111008d9e0c46": { + "balance": "200000000000000000000" + }, + "8e7936d592008fdc7aa04edeeb755ab513dbb89d": { + "balance": "20000000000000000000" + }, + "4a53dcdb56ce4cdce9f82ec0eb13d67352e7c88b": { + "balance": "4200000000000000000000" + }, + "2b4f4507bb6b9817942ce433781b708fbcd166fd": { + "balance": "18200000000000000000" + }, + "026432af37dc5113f1f46d480a4de0b28052237e": { + "balance": "355800000000000000000" + }, + "e780a56306ba1e6bb331952c22539b858af9f77d": { + "balance": "50000000000000000000000" + }, + "d1f1694d22671b5aad6a94995c369fbe6133676f": { + "balance": "1000000000000000000000" + }, + "7c45f0f8442a56dbd39dbf159995415c52ed479b": { + "balance": "2000000000000000000000" + }, + "b65941d44c50d24666670d364766e991c02e11c2": { + "balance": "600000000000000000000" + }, + "45e68db8dbbaba5fc2cb337c62bcd0d61b059189": { + "balance": "2000000000000000000000" + }, + "05f3631f5664bdad5d0132c8388d36d7d8920918": { + "balance": "20000000000000000000" + }, + "5475d7f174bdb1f789017c7c1705989646079d49": { + "balance": "9400000000000000000000" + }, + "c7bf2ed1ed312940ee6aded1516e268e4a604856": { + "balance": "6000000000000000000000" + }, + "39aaf0854db6eb39bc7b2e43846a76171c0445de": { + "balance": "1850000000000000000000" + }, + "c817df1b91faf30fe3251571727c9711b45d8f06": { + "balance": "1999944000000000000000" + }, + "7d13d6705884ab2157dd8dcc7046caf58ee94be4": { + "balance": "137200000000000000000000" + }, + "478dc09a1311377c093f9cc8ae74111f65f82f39": { + "balance": "4000000000000000000000" + }, + "8043ed22f997e5a2a4c16e364486ae64975692c4": { + "balance": "1130513000000000000000" + }, + "b9a985501ee950829b17fae1c9cf348c3156542c": { + "balance": "294100000000000000000" + }, + "d5cba5b26bea5d73fabb1abafacdef85def368cc": { + "balance": "200000000000000000000" + }, + "6776e133d9dc354c12a951087b639650f539a433": { + "balance": "120000000000000000000" + }, + "804ca94972634f633a51f3560b1d06c0b293b3b1": { + "balance": "200000000000000000000" + }, + "0be1fdf626ee6189102d70d13b31012c95cd1cd6": { + "balance": "2000000000000000000000" + }, + "f848fce9ab611c7d99206e23fac69ad488b94fe1": { + "balance": "48500000000000000000" + }, + "f01195d657ef3c942e6cb83949e5a20b5cfa8b1e": { + "balance": "25760000000000000000000" + }, + "78a5e89900bd3f81dd71ba869d25fec65261df15": { + "balance": "51900000000000000000000" + }, + "d6f1e55b1694089ebcb4fe7d7882aa66c8976176": { + "balance": "19998846000000000000000" + }, + "d5294b666242303b6df0b1c88d37429bc8c965aa": { + "balance": "300700000000000000000" + }, + "3171877e9d820cc618fc0919b29efd333fda4934": { + "balance": "1000000000000000000000" + }, + "2901f8077f34190bb47a8e227fa29b30ce113b31": { + "balance": "100000000000000000000" + }, + "6b2284440221ce16a8382de5ff0229472269deec": { + "balance": "1000000000000000000000" + }, + "1bba03ff6b4ad5bf18184acb21b188a399e9eb4a": { + "balance": "1790000000000000000000" + }, + "80744618de396a543197ee4894abd06398dd7c27": { + "balance": "2000000000000000000000" + }, + "1b799033ef6dc7127822f74542bb22dbfc09a308": { + "balance": "100000000000000000000" + }, + "d513a45080ff2febe62cd5854abe29ee4467f996": { + "balance": "153200000000000000000" + }, + "e761d27fa3502cc76bb1a608740e1403cf9dfc69": { + "balance": "280000000000000000000" + }, + "53989ed330563fd57dfec9bd343c3760b0799390": { + "balance": "6208000000000000000000" + }, + "ccf7110d1bd9a74bfd1d7d7d2d9d55607e7b837d": { + "balance": "900000000000000000000" + }, + "f373e9daac0c8675f53b797a160f6fc034ae6b23": { + "balance": "100000000000000000000" + }, + "abc9a99e8a2148a55a6d82bd51b98eb5391fdbaf": { + "balance": "6000000000000000000000" + }, + "ffec0913c635baca2f5e57a37aa9fb7b6c9b6e26": { + "balance": "805000000000000000000" + }, + "581a3af297efa4436a29af0072929abf9826f58b": { + "balance": "2000000000000000000000" + }, + "924efa6db595b79313277e88319625076b580a10": { + "balance": "2000000000000000000000" + }, + "65d8dd4e251cbc021f05b010f2d5dc520c3872e0": { + "balance": "834956000000000000000" + }, + "6c67d6db1d03516c128b8ff234bf3d49b26d2941": { + "balance": "100000000000000000000000" + }, + "496d365534530a5fc1577c0a5241cb88c4da7072": { + "balance": "1790000000000000000000" + }, + "b85ff03e7b5fc422981fae5e9941dacbdaba7584": { + "balance": "1337000000000000000000" + }, + "e13540ecee11b212e8b775dc8e71f374aae9b3f8": { + "balance": "2000000000000000000000" + }, + "a02e3f8f5959a7aab7418612129b701ca1b80010": { + "balance": "20000000000000000000" + }, + "a7a3f153cdc38821c20c5d8c8241b294a3f82b24": { + "balance": "500000000000000000000" + }, + "366175403481e0ab15bb514615cbb989ebc68f82": { + "balance": "2000000000000000000000" + }, + "5104ecc0e330dd1f81b58ac9dbb1a9fbf88a3c85": { + "balance": "100000000000000000000000" + }, + "a466d770d898d8c9d405e4a0e551efafcde53cf9": { + "balance": "492500000000000000000" + }, + "5fa8a54e68176c4fe2c01cf671c515bfbdd528a8": { + "balance": "330000000000000000000000" + }, + "e2e15c60dd381e3a4be25071ab249a4c5c5264da": { + "balance": "2350502000000000000000" + }, + "0628bfbe5535782fb588406bc96660a49b011af5": { + "balance": "1520000000000000000000" + }, + "04d6b8d4da867407bb997749debbcdc0b358538a": { + "balance": "1000000000000000000000" + }, + "0e6ec313376271dff55423ab5422cc3a8b06b22b": { + "balance": "4000000000000000000000" + }, + "8787d12677a5ec291e57e31ffbfad105c3324b87": { + "balance": "12438777000000000000000" + }, + "58e2f11223fc8237f69d99c6289c148c0604f742": { + "balance": "24000000000000000000000" + }, + "5600730a55f6b20ebd24811faa3de96d1662abab": { + "balance": "1880000000000000000000" + }, + "fce089635ce97abac06b44819be5bb0a3e2e0b37": { + "balance": "92491000000000000000" + }, + "fa0c1a988c8a17ad3528eb28b3409daa58225f26": { + "balance": "200000000000000000000" + }, + "7ae1c19e53c71cee4c73fae2d7fc73bf9ab5e392": { + "balance": "1000000000000000000000" + }, + "bd17eed82b9a2592019a1b1b3c0fbad45c408d22": { + "balance": "250000000000000000000" + }, + "884a7a39d0916e05f1c242df55607f37df8c5fda": { + "balance": "23400000000000000000000" + }, + "ca70f4ddbf069d2143bd6bbc7f696b52789b32e7": { + "balance": "3000000000000000000000" + }, + "7b25bb9ca8e702217e9333225250e53c36804d48": { + "balance": "1880000000000000000000" + }, + "ea8317197959424041d9d7c67a3ece1dbb78bb55": { + "balance": "394000000000000000000" + }, + "5cb953a0e42f5030812226217fffc3ce230457e4": { + "balance": "100000000000000000000" + }, + "d1f4dc1ddb8abb8848a8b14e25f3b55a8591c266": { + "balance": "250000000000000000000" + }, + "6a42ca971c6578d5ade295c3e7f4ad331dd3424e": { + "balance": "6000000000000000000000" + }, + "07e1162ceae3cf21a3f62d105990302e307f4e3b": { + "balance": "1530000000000000000000" + }, + "5d1dc3387b47b8451e55106c0cc67d6dc72b7f0b": { + "balance": "2000000000000000000000" + }, + "5d2819e8d57821922ee445650ccaec7d40544a8d": { + "balance": "200000000000000000000" + }, + "4c24b78baf2bafc7fcc69016426be973e20a50b2": { + "balance": "3000000000000000000000" + }, + "630c5273126d517ce67101811cab16b8534cf9a8": { + "balance": "9422595000000000000000" + }, + "291f929ca59b54f8443e3d4d75d95dee243cef78": { + "balance": "499938000000000000000" + }, + "2dd325fdffb97b19995284afa5abdb574a1df16a": { + "balance": "500000000000000000000" + }, + "4fce8429ba49caa0369d1e494db57e89eab2ad39": { + "balance": "200000000000000000000000" + }, + "712b76510214dc620f6c3a1dd29aa22bf6d214fb": { + "balance": "6000000000000000000000" + }, + "266f2da7f0085ef3f3fa09baee232b93c744db2e": { + "balance": "60000000000000000000000" + }, + "0770c61be78772230cb5a3bb2429a72614a0b336": { + "balance": "6767695000000000000000" + }, + "02dfcb17a1b87441036374b762a5d3418b1cb4d4": { + "balance": "1340860000000000000000" + }, + "5e67df8969101adabd91accd6bb1991274af8df2": { + "balance": "500000000000000000000" + }, + "7d9c59631e2ba2e8e82891f3979922aaa3b567a1": { + "balance": "8000000000000000000000" + }, + "949f8c107bc7f0aceaa0f17052aadbd2f9732b2e": { + "balance": "2000000000000000000000" + }, + "ea4e809e266ae5f13cdbe38f9d0456e6386d1274": { + "balance": "4500000000000000000000" + }, + "cd5510a242dfb0183de925fba866e312fabc1657": { + "balance": "2400000000000000000000" + }, + "a36e0d94b95364a82671b608cb2d373245612909": { + "balance": "150011000000000000000" + }, + "0ec46696ffac1f58005fa8439824f08eed1df89b": { + "balance": "10000000000000000000000" + }, + "c6fb1ee37417d080a0d048923bdabab095d077c6": { + "balance": "200000000000000000000" + }, + "53c9eca40973f63bb5927be0bc6a8a8be1951f74": { + "balance": "2000000000000000000000" + }, + "ea14bfda0a6e76668f8788321f07df37824ec5df": { + "balance": "200000000000000000000000" + }, + "dfb4d4ade52fcc818acc7a2c6bb2b00224658f78": { + "balance": "7750000000000000000000" + }, + "5997ffefb3c1d9d10f1ae2ac8ac3c8e2d2292783": { + "balance": "1000000000000000000000" + }, + "8eceb2e124536c5b5ffc640ed14ff15ed9a8cb71": { + "balance": "2000000000000000000000" + }, + "8f02bda6c36922a6be6a509be51906d393f7b99b": { + "balance": "1019835000000000000000" + }, + "530077c9f7b907ff9cec0c77a41a70e9029add4a": { + "balance": "2000000000000000000000" + }, + "08936a37df85b3a158cafd9de021f58137681347": { + "balance": "18200000000000000000" + }, + "8e9c429266df057efa78dd1d5f77fc40742ad466": { + "balance": "300061000000000000000" + }, + "acc59f3b30ceffc56461cc5b8df48902240e0e7b": { + "balance": "2000000000000000000000" + }, + "f5534815dc635efa5cc84b2ac734723e21b29372": { + "balance": "1580000000000000000000" + }, + "f873e57a65c93b6e18cb75f0dc077d5b8933dc5c": { + "balance": "197000000000000000000" + }, + "25b78c9fad85b43343f0bfcd0fac11c9949ca5eb": { + "balance": "2000000000000000000000" + }, + "aad2b7f8106695078e6c138ec81a7486aaca1eb2": { + "balance": "200000000000000000000" + }, + "509c8668036d143fb8ae70b11995631f3dfcad87": { + "balance": "1000000000000000000000" + }, + "3602458da86f6d6a9d9eb03daf97fe5619d442fa": { + "balance": "2000000000000000000000" + }, + "9f607b3f12469f446121cebf3475356b71b4328c": { + "balance": "4000000000000000000000" + }, + "fe3827d57630cf8761d512797b0b858e478bbd12": { + "balance": "20000000000000000000" + }, + "9d9c4efe9f433989e23be94049215329fa55b4cb": { + "balance": "256215000000000000000" + }, + "9bd905f1719fc7acd0159d4dc1f8db2f21472338": { + "balance": "1000000000000000000000" + }, + "7d82e523cc2dc591da3954e8b6bb2caf6461e69c": { + "balance": "2316058000000000000000" + }, + "74afe54902d615782576f8baac13ac970c050f6e": { + "balance": "177670000000000000000" + }, + "aff11ccf699304d5f5862af86083451c26e79ae5": { + "balance": "1999000000000000000000" + }, + "3885fee67107dc3a3c741ee290c98918c9b99397": { + "balance": "20000000000000000000" + }, + "36343aeca07b6ed58a0e62fa4ecb498a124fc971": { + "balance": "300000000000000000000" + }, + "c94a28fb3230a9ddfa964e770f2ce3c253a7be4f": { + "balance": "200000000000000000000" + }, + "9882967cee68d2a839fad8ab4a7c3dddf6c0adc8": { + "balance": "1336866000000000000000" + }, + "95df4e3445d7662624c48eba74cf9e0a53e9f732": { + "balance": "56000000000000000000000" + }, + "ca9faa17542fafbb388eab21bc4c94e8a7b34788": { + "balance": "1999999000000000000000" + }, + "c8b1850525d946f2ae84f317b15188c536a5dc86": { + "balance": "2685000000000000000000" + }, + "39bac68d947859f59e9226089c96d62e9fbe3cde": { + "balance": "40000000000000000000" + }, + "a9bfc410dddb20711e45c07387eab30a054e19ac": { + "balance": "1154750000000000000000" + }, + "540a1819bd7c35861e791804e5fbb3bc97c9abb1": { + "balance": "1454400000000000000000" + }, + "667b61c03bb937a9f5d0fc5a09f1ea3363c77035": { + "balance": "4250000000000000000000" + }, + "010df1df4bed23760d2d1c03781586ddf7918e54": { + "balance": "60000000000000000000" + }, + "bd51ee2ea143d7b1d6b77e7e44bdd7da12f485ac": { + "balance": "1318800000000000000000" + }, + "fb5125bf0f5eb0b6f020e56bfc2fdf3d402c097e": { + "balance": "5910000000000000000000" + }, + "3f0c83aac5717962734e5ceaeaecd39b28ad06be": { + "balance": "2000000000000000000000" + }, + "f10661ff94140f203e7a482572437938bec9c3f7": { + "balance": "20000000000000000000000" + }, + "bd3097a79b3c0d2ebff0e6e86ab0edadbed47096": { + "balance": "1670000000000000000000" + }, + "edeb4894aadd0081bbddd3e8846804b583d19f27": { + "balance": "2000000000000000000000" + }, + "49c9771fca19d5b9d245c891f8158fe49f47a062": { + "balance": "10000000000000000000000" + }, + "6405dd13e93abcff377e700e3c1a0086eca27d29": { + "balance": "18200000000000000000" + }, + "ce5e04f0184369bcfa06aca66ffa91bf59fa0fb9": { + "balance": "40000000000000000000" + }, + "4364309a9fa07095600f79edc65120cdcd23dc64": { + "balance": "10000000000000000000000" + }, + "b749b54e04d5b19bdcedfb84da7701ab478c27ae": { + "balance": "2680000000000000000000" + }, + "f593c65285ee6bbd6637f3be8f89ad40d489f655": { + "balance": "3000000000000000000000" + }, + "d224f880f9479a89d32f09e52be990b288135cef": { + "balance": "17300000000000000000000" + }, + "85bb51bc3bfe9a1b2a2f6b1cda95bca8b38c8d5e": { + "balance": "321750000000000000000" + }, + "caf4481d9db78dc4f25f7b4ac8bd3b1ca0106b31": { + "balance": "5000000000000000000000" + }, + "51ca8bd4dc644fac47af675563d5804a0da21eeb": { + "balance": "788000000000000000000" + }, + "19f643e1a8fa04ae16006028138333a59a96de87": { + "balance": "20000000000000000000" + }, + "58b808a65b51e6338969afb95ec70735e451d526": { + "balance": "39998000000000000000000" + }, + "574921838cc77d6c98b17d903a3ae0ee0da95bd0": { + "balance": "53480000000000000000000" + }, + "7c6924d07c3ef5891966fe0a7856c87bef9d2034": { + "balance": "2000000000000000000000" + }, + "f9767e4ecb4a5980527508d7bec3d45e4c649c13": { + "balance": "1910000000000000000000" + }, + "f3be99b9103ce7550aa74ff1db18e09dfe32e005": { + "balance": "2000000000000000000000" + }, + "625644c95a873ef8c06cdb9e9f6d8d7680043d62": { + "balance": "1800000000000000000000" + }, + "6a44af96b3f032ae641beb67f4b6c83342d37c5d": { + "balance": "29000000000000000000" + }, + "d3a10ec7a5c9324999dd9e9b6bde7c911e584bda": { + "balance": "600000000000000000000" + }, + "e8ddbed732ebfe754096fde9086b8ea4a4cdc616": { + "balance": "2000000000000000000000" + }, + "235fa66c025ef5540070ebcf0d372d8177c467ab": { + "balance": "33400000000000000000000" + }, + "4d08471d68007aff2ae279bc5e3fe4156fbbe3de": { + "balance": "40000000000000000000000" + }, + "dadc00ab7927603c2fcf31cee352f80e6c4d6351": { + "balance": "1999664000000000000000" + }, + "7393cbe7f9ba2165e5a7553500b6e75da3c33abf": { + "balance": "100000000000000000000" + }, + "77617ebc4bebc5f5ddeb1b7a70cdeb6ae2ffa024": { + "balance": "1970000000000000000000" + }, + "7fea1962e35d62059768c749bedd96cab930d378": { + "balance": "2000000000000000000000" + }, + "243b3bca6a299359e886ce33a30341fafe4d573d": { + "balance": "20000000000000000000000" + }, + "b94d47b3c052a5e50e4261ae06a20f45d8eee297": { + "balance": "2000000000000000000000" + }, + "e727e67ef911b81f6cf9c73fcbfebc2b02b5bfc6": { + "balance": "2000000000000000000000" + }, + "e510d6797fba3d6693835a844ea2ad540691971b": { + "balance": "17381000000000000000000" + }, + "0cdc960b998c141998160dc179b36c15d28470ed": { + "balance": "500038000000000000000" + }, + "3e76a62db187aa74f63817533b306cead0e8cebe": { + "balance": "31200000000000000000000" + }, + "495b641b1cdea362c3b4cbbd0f5cc50b1e176b9c": { + "balance": "1000000000000000000000" + }, + "5126460d692c71c9af6f05574d93998368a23799": { + "balance": "52000000000000000000" + }, + "a008019863c1a77c1499eb39bbd7bf2dd7a31cb9": { + "balance": "137000000000000000000" + }, + "65ee20b06d9ad589a7e7ce04b9f5f795f402aece": { + "balance": "2000000000000000000000" + }, + "f432b9dbaf11bdbd73b6519fc0a904198771aac6": { + "balance": "152000000000000000000" + }, + "85946d56a4d371a93368539690b60ec825107454": { + "balance": "1730000000000000000000" + }, + "26f9f7cefd7e394b9d3924412bf2c2831faf1f85": { + "balance": "4000000000000000000000" + }, + "d4ebb1929a23871cf77fe049ab9602be08be0a73": { + "balance": "1910000000000000000000" + }, + "4fdac1aa517007e0089430b3316a1badd12c01c7": { + "balance": "500000000000000000000" + }, + "05e671de55afec964b074de574d5158d5d21b0a3": { + "balance": "3940000000000000000000" + }, + "20181c4b41f6f972b66958215f19f570c15ddff1": { + "balance": "1600000000000000000000" + }, + "cc9519d1f3985f6b255eaded12d5624a972721e1": { + "balance": "1000000000000000000000" + }, + "169bbefc41cfd7d7cbb8dfc63020e9fb06d49546": { + "balance": "2000000000000000000000" + }, + "175a183a3a235ffbb03ba835675267229417a091": { + "balance": "16000000000000000000000" + }, + "8dde3cb8118568ef4503fe998ccdf536bf19a098": { + "balance": "4000000000000000000000" + }, + "6a05b21c4f17f9d73f5fb2b0cb89ff5356a6cc7e": { + "balance": "1500000000000000000000" + }, + "5cc4cba621f220637742057f6055b80dffd77e13": { + "balance": "39997692000000000000000" + }, + "ecb94c568bfe59ade650645f4f26306c736cace4": { + "balance": "267400000000000000000" + }, + "dfa6b8b8ad3184e357da282951d79161cfb089bc": { + "balance": "400000000000000000000" + }, + "a3058c51737a4e96c55f2ef6bd7bb358167ec2a7": { + "balance": "606093000000000000000" + }, + "051d424276b21239665186133d653bb8b1862f89": { + "balance": "1000000000000000000000" + }, + "d05ffb2b74f867204fe531653b0248e21c13544e": { + "balance": "1000000000000000000000" + }, + "e1f63ebbc62c7b7444040eb99623964f7667b376": { + "balance": "20000000000000000000" + }, + "e5a3d7eb13b15c100177236d1beb30d17ee15420": { + "balance": "2000000000000000000000" + }, + "18fa8625c9dc843c78c7ab259ff87c9599e07f10": { + "balance": "1000000000000000000000" + }, + "64264aedd52dcae918a012fbcd0c030ee6f71821": { + "balance": "1000000000000000000000" + }, + "6f1f4907b8f61f0c51568d692806b382f50324f5": { + "balance": "2000000000000000000000" + }, + "becef61c1c442bef7ce04b73adb249a8ba047e00": { + "balance": "1000400000000000000000" + }, + "7b893286427e72db219a21fc4dcd5fbf59283c31": { + "balance": "10000000000000000000000" + }, + "ce5eb63a7bf4fbc2f6e4baa0c68ab1cb4cf98fb4": { + "balance": "2000000000000000000000" + }, + "66ec16ee9caab411c55a6629e318de6ee216491d": { + "balance": "865000000000000000000" + }, + "30b66150f1a63457023fdd45d0cc6cb54e0c0f06": { + "balance": "1000000000000000000000" + }, + "87183160d172d2e084d327b86bcb7c1d8e6784ef": { + "balance": "4000086000000000000000" + }, + "c420388fbee84ad656dd68cdc1fbaa9392780b34": { + "balance": "187767000000000000000" + }, + "90f774c9147dde90853ddc43f08f16d455178b8c": { + "balance": "4000000000000000000000" + }, + "1e1d7a5f2468b94ea826982dbf2125793c6e4a5a": { + "balance": "999940000000000000000" + }, + "8043fdd0bc4c973d1663d55fc135508ec5d4f4fa": { + "balance": "20000000000000000000" + }, + "7bca1da6c80a66baa5db5ac98541c4be276b447d": { + "balance": "679000000000000000000" + }, + "73550beb732ba9ddafda7ae406e18f7feb0f8bb2": { + "balance": "2800000000000000000000" + }, + "adc19ec835afe3e58d87dc93a8a9213c90451326": { + "balance": "1971200000000000000000" + }, + "821d798af19989c3ae5b84a7a7283cd7fda1fabe": { + "balance": "20000000000000000000000" + }, + "4c4e6f13fb5e3f70c3760262a03e317982691d10": { + "balance": "100000000000000000000" + }, + "664e43119870af107a448db1278b044838ffcdaf": { + "balance": "400000000000000000000" + }, + "8da1178f55d97772bb1d24111a404a4f8715b95d": { + "balance": "878149000000000000000" + }, + "5e6e9747e162f8b45c656e0f6cae7a84bac80e4e": { + "balance": "2000000000000000000000" + }, + "c7eac31abce6d5f1dea42202b6a674153db47a29": { + "balance": "591000000000000000000" + }, + "d96711540e2e998343d4f590b6fc8fac3bb8b31d": { + "balance": "1758944000000000000000" + }, + "9da4ec407077f4b9707b2d9d2ede5ea5282bf1df": { + "balance": "4000000000000000000000" + }, + "f60c1b45f164b9580e20275a5c39e1d71e35f891": { + "balance": "2000000000000000000000" + }, + "eb6394a7bfa4d28911d5a5b23e93f35e340c2294": { + "balance": "78000000000000000000" + }, + "a89ac93b23370472daac337e9afdf642543f3e57": { + "balance": "10000000000000000000000" + }, + "bb618e25221ad9a740b299ed1406bc3934b0b16d": { + "balance": "1000000000000000000000" + }, + "817ac33bd8f847567372951f4a10d7a91ce3f430": { + "balance": "200015000000000000000" + }, + "fe6a895b795cb4bf85903d3ce09c5aa43953d3bf": { + "balance": "3400000000000000000000" + }, + "3673954399f6dfbe671818259bb278e2e92ee315": { + "balance": "200000000000000000000000" + }, + "df0ff1f3d27a8ec9fb8f6b0cb254a63bba8224a5": { + "balance": "4367636000000000000000" + }, + "ff12e49d8e06aa20f886293c0b98ed7eff788805": { + "balance": "4000000000000000000000" + }, + "5aef16a226dd68071f2483e1da42598319f69b2c": { + "balance": "2000000000000000000000" + }, + "0266ab1c6b0216230b9395443d5fa75e684568c6": { + "balance": "1000000000000000000000" + }, + "14a7352066364404db50f0d0d78d754a22198ef4": { + "balance": "1880000000000000000000" + }, + "444caf79b71338ee9aa7c733b02acaa7dc025948": { + "balance": "40000000000000000000" + }, + "64e2de21200b1899c3a0c0653b5040136d0dc842": { + "balance": "20000000000000000000000" + }, + "36e156610cd8ff64e780d89d0054385ca76755aa": { + "balance": "14000000000000000000000" + }, + "0a6ebe723b6ed1f9a86a69ddda68dc47465c2b1b": { + "balance": "1185000000000000000000" + }, + "38bf2a1f7a69de0e2546adb808b36335645da9ff": { + "balance": "2000320000000000000000" + }, + "39f44663d92561091b82a70dcf593d754005973a": { + "balance": "199999000000000000000" + }, + "24b9e6644f6ba4cde126270d81f6ab60f286dff4": { + "balance": "133700000000000000000" + }, + "9b59eb213b1e7565e45047e04ea0374f10762d16": { + "balance": "2000000000000000000000" + }, + "309544b6232c3dd737f945a03193d19b5f3f65b9": { + "balance": "1087440000000000000000" + }, + "b28bb39f3466517cd46f979cf59653ee7d8f152e": { + "balance": "450000000000000000000" + }, + "9da8e22ca10e67fea44e525e4751eeac36a31194": { + "balance": "260000000000000000000" + }, + "4f8ae80238e60008557075ab6afe0a7f2e74d729": { + "balance": "100000000000000000000" + }, + "74ed33acf43f35b98c9230b9e6642ecb5330839e": { + "balance": "681872000000000000000" + }, + "22842ab830da509913f81dd1f04f10af9edd1c55": { + "balance": "2000000000000000000000" + }, + "a8f37f0ab3a1d448a9e3ce40965f97a646083a34": { + "balance": "329800000000000000000" + }, + "582b70669c97aab7d68148d8d4e90411e2810d56": { + "balance": "999972000000000000000" + }, + "d5e55100fbd1956bbed2ca518d4b1fa376032b0b": { + "balance": "100000000000000000000" + }, + "b7cc6b1acc32d8b295df68ed9d5e60b8f64cb67b": { + "balance": "300000000000000000000" + }, + "e081ca1f4882db6043d5a9190703fde0ab3bf56d": { + "balance": "400000000000000000000" + }, + "c02077449a134a7ad1ef7e4d927affeceeadb5ae": { + "balance": "18200000000000000000" + }, + "e09fea755aee1a44c0a89f03b5deb762ba33006f": { + "balance": "1100070000000000000000" + }, + "b3717731dad65132da792d876030e46ac227bb8a": { + "balance": "1000000000000000000000" + }, + "157eb3d3113bd3b597714d3a954edd018982a5cb": { + "balance": "2000000000000000000000" + }, + "dc57345b38e0f067c9a31d9deac5275a10949321": { + "balance": "200000000000000000000" + }, + "40ea5044b204b23076b1a5803bf1d30c0f88871a": { + "balance": "14000000000000000000000" + }, + "2bab0fbe28d58420b52036770a12f9952aea6911": { + "balance": "3820000000000000000000" + }, + "adaa0e548c035affed64ca678a963fabe9a26bfd": { + "balance": "70000000000000000000" + }, + "bb48eaf516ce2dec3e41feb4c679e4957641164f": { + "balance": "3820000000000000000000" + }, + "7693bdeb6fc82b5bca721355223175d47a084b4d": { + "balance": "22000000000000000000000" + }, + "03cb98d7acd817de9d886d22fab3f1b57d92a608": { + "balance": "1600000000000000000000" + }, + "f88900db737955b1519b1a7d170a18864ce590eb": { + "balance": "18200000000000000000" + }, + "757fa55446c460968bb74b5ebca96c4ef2c709c5": { + "balance": "1015200000000000000000" + }, + "da855d53477f505ec4c8d5e8bb9180d38681119c": { + "balance": "5600000000000000000000" + }, + "e41aea250b877d423a63ba2bce2f3a61c0248d56": { + "balance": "260000000000000000000" + }, + "8262169b615870134eb4ac6c5f471c6bf2f789fc": { + "balance": "462500000000000000000" + }, + "66b0c100c49149935d14c0dc202cce907cea1a3d": { + "balance": "1970000000000000000000" + }, + "854c0c469c246b83b5d1b3eca443b39af5ee128a": { + "balance": "1600000000000000000000" + }, + "eb6810691d1ae0d19e47bd22cebee0b3ba27f88a": { + "balance": "2499922000000000000000" + }, + "24dcc24bd9c7210ceacfb30da98ae04a4d7b8ab9": { + "balance": "1000000000000000000000" + }, + "e31b4eef184c24ab098e36c802714bd4743dd0d4": { + "balance": "200000000000000000000" + }, + "99b8c824869de9ed24f3bff6854cb6dd45cc3f9f": { + "balance": "1880000000000000000000" + }, + "2ae73a79aea0278533accf21070922b1613f8f32": { + "balance": "3097417000000000000000" + }, + "ddbd2b932c763ba5b1b7ae3b362eac3e8d40121a": { + "balance": "10000000000000000000000" + }, + "1b4bbcb18165211b265b280716cb3f1f212176e8": { + "balance": "472325000000000000000" + }, + "e177e0c201d335ba3956929c571588b51c5223ae": { + "balance": "2000000000000000000000" + }, + "1945fe377fe6d4b71e3e791f6f17db243c9b8b0f": { + "balance": "2185500000000000000000" + }, + "3e9b34a57f3375ae59c0a75e19c4b641228d9700": { + "balance": "17900000000000000000" + }, + "a4d6c82eddae5947fbe9cdfbd548ae33d91a7191": { + "balance": "8000000000000000000000" + }, + "bad4425e171c3e72975eb46ac0a015db315a5d8f": { + "balance": "2000000000000000000000" + }, + "a2d2aa626b09d6d4e4b13f7ffc5a88bd7ad36742": { + "balance": "4639390000000000000000" + }, + "b61c34fcacda701a5aa8702459deb0e4ae838df8": { + "balance": "35000000000000000000000" + }, + "145e0600e2a927b2dd8d379356b45a2e7d51d3ae": { + "balance": "2545843000000000000000" + }, + "8df339214b6ad1b24663ce716034749d6ef838d9": { + "balance": "11000000000000000000000" + }, + "8fd9a5c33a7d9edce0997bdf77ab306424a11ea9": { + "balance": "2000000000000000000000" + }, + "097da12cfc1f7c1a2464def08c29bed5e2f851e9": { + "balance": "20000000000000000000" + }, + "ddabf13c3c8ea4e3d73d78ec717afafa430e5479": { + "balance": "41600000000000000000000" + }, + "9eeb07bd2b7890195e7d46bdf2071b6617514ddb": { + "balance": "2000000000000000000000" + }, + "819af9a1c27332b1c369bbda1b3de1c6e933d640": { + "balance": "314308000000000000000" + }, + "d7d2c6fca8ad1f75395210b57de5dfd673933909": { + "balance": "340000000000000000000" + }, + "cdd5d881a7362c9070073bdfbc75e72453ac510e": { + "balance": "842000000000000000000" + }, + "e9ac36376efa06109d40726307dd1a57e213eaa9": { + "balance": "194000000000000000000" + }, + "1bea4df5122fafdeb3607eddda1ea4ffdb9abf2a": { + "balance": "346000000000000000000" + }, + "3e5e93fb4c9c9d1246f8f247358e22c3c5d17b6a": { + "balance": "150000000000000000000" + }, + "6c1ddd33c81966dc8621776071a4129482f2c65f": { + "balance": "40000000000000000000000" + }, + "2ccb66494d0af689abf9483d365d782444e7dead": { + "balance": "1000000000000000000000" + }, + "19571a2b8f81c6bcf66ab3a10083295617150003": { + "balance": "492500000000000000000" + }, + "38ac664ee8e0795e4275cb852bcba6a479ad9c8d": { + "balance": "20000000000000000000" + }, + "c4803bb407c762f90b7596e6fde194931e769590": { + "balance": "4000000000000000000000" + }, + "93507e9e8119cbceda8ab087e7ecb071383d6981": { + "balance": "14000000000000000000000" + }, + "b672734afcc224e2e609fc51d4f059732744c948": { + "balance": "295500000000000000000" + }, + "fbbbebcfbe235e57dd2306ad1a9ec581c7f9f48f": { + "balance": "40000000000000000000" + }, + "8c81410ea8354cc5c65c41be8bd5de733c0b111d": { + "balance": "9550000000000000000000" + }, + "942c6b8c955bc0d88812678a236725b32739d947": { + "balance": "1550000000000000000000" + }, + "d2e817738abf1fb486583f80c350318bed860c80": { + "balance": "240010000000000000000" + }, + "bff5df769934b8943ca9137d0efef2fe6ebbb34e": { + "balance": "100000000000000000000" + }, + "6c4e426e8dc005dfa3516cb8a680b02eea95ae8e": { + "balance": "1337000000000000000000" + }, + "f645dd7c890093e8e4c8aa92a6bb353522d3dc98": { + "balance": "134000000000000000000" + }, + "4bac846af4169f1d95431b341d8800b22180af1a": { + "balance": "20000000000000000000" + }, + "0514954c3c2fb657f9a06f510ea22748f027cdd3": { + "balance": "400000000000000000000" + }, + "163dca73d7d6ea3f3e6062322a8734180c0b78ef": { + "balance": "2941400000000000000000" + }, + "feaca2ac74624bf348dac9985143cfd652a4be55": { + "balance": "26148245000000000000000" + }, + "fe80e9232deaff19baf99869883a4bdf0004e53c": { + "balance": "855680000000000000000" + }, + "17108dab2c50f99de110e1b3b3b4cd82f5df28e7": { + "balance": "980000000000000000000" + }, + "837a645dc95c49549f899c4e8bcf875324b2f57c": { + "balance": "600400000000000000000" + }, + "762998e1d75227fced7a70be109a4c0b4ed86414": { + "balance": "20000000000000000000" + }, + "c0a7e8435dff14c25577739db55c24d5bf57a3d9": { + "balance": "49250000000000000000000" + }, + "aead88d689416b1c91f2364421375b7d3c70fb2e": { + "balance": "2000000000000000000000" + }, + "9279b2228cec8f7b4dda3f320e9a0466c2f585ca": { + "balance": "5000000000000000000000" + }, + "36726f3b885a24f92996da81625ec8ad16d8cbe6": { + "balance": "1543723000000000000000" + }, + "3951e48e3c869e6b72a143b6a45068cdb9d466d0": { + "balance": "20000000000000000000" + }, + "f5d61ac4ca95475e5b7bffd5f2f690b316759615": { + "balance": "31040000000000000000000" + }, + "158a0d619253bf4432b5cd02c7b862f7c2b75636": { + "balance": "135733000000000000000" + }, + "e56d431324c92911a1749df292709c14b77a65cd": { + "balance": "8200000000000000000000" + }, + "9976947eff5f6ae5da08dd541192f378b428ff94": { + "balance": "8000000000000000000000" + }, + "83210583c16a4e1e1dac84ebd37e3d0f7c57eba4": { + "balance": "2000000000000000000000" + }, + "dcb64df43758c7cf974fa660484fbb718f8c67c1": { + "balance": "20000000000000000000000" + }, + "d4205592844055b3c7a1f80cefe3b8eb509bcde7": { + "balance": "178973000000000000000" + }, + "d0648a581b3508e135a2935d12c9657045d871ca": { + "balance": "8022000000000000000000" + }, + "e7d17524d00bad82497c0f27156a647ff51d2792": { + "balance": "20000000000000000000" + }, + "21582e99e502cbf3d3c23bdffb76e901ac6d56b2": { + "balance": "100000000000000000000" + }, + "e61f280915c774a31d223cf80c069266e5adf19b": { + "balance": "880000000000000000000" + }, + "03c91d92943603e752203e05340e566013b90045": { + "balance": "802200000000000000000" + }, + "22561c5931143536309c17e832587b625c390b9a": { + "balance": "4000000000000000000000" + }, + "e399c81a1d701b44f0b66f3399e66b275aaaf8c1": { + "balance": "1000000000000000000000" + }, + "7f8dbce180ed9c563635aad2d97b4cbc428906d9": { + "balance": "2674000000000000000000" + }, + "9f61beb46f5e853d0a8521c7446e68e34c7d0973": { + "balance": "560000000000000000000" + }, + "6d3f2ba856ccbb0237fa7661156b14b013f21240": { + "balance": "1000000000000000000000" + }, + "5f742e487e3ab81af2f94afdbe1b9b8f5ccc81bc": { + "balance": "2172412000000000000000" + }, + "b600feab4aa96c537504d96057223141692c193a": { + "balance": "400000000000000000000" + }, + "fab487500df20fb83ebed916791d561772adbebf": { + "balance": "1999980000000000000000" + }, + "f8704c16d2fd5ba3a2c01d0eb20484e6ecfa3109": { + "balance": "200000000000000000000" + }, + "3f1bc420c53c002c9e90037c44fe6a8ef4ddc962": { + "balance": "173000000000000000000" + }, + "82e577b515cb2b0860aafe1ce09a59e09fe7d040": { + "balance": "600000000000000000000" + }, + "bc999e385c5aebcac8d6f3f0d60d5aa725336d0d": { + "balance": "2000000000000000000000" + }, + "e16ce35961cd74bd590d04c4ad4a1989e05691c6": { + "balance": "146000000000000000000" + }, + "eb76424c0fd597d3e341a9642ad1ee118b2b579d": { + "balance": "4000000000000000000000" + }, + "c440c7ca2f964b6972ef664a2261dde892619d9c": { + "balance": "20000000000000000000000" + }, + "460d5355b2ceeb6e62107d81e51270b26bf45620": { + "balance": "2005500000000000000000" + }, + "fcada300283f6bcc134a91456760b0d77de410e0": { + "balance": "2000000000000000000000" + }, + "be8d7f18adfe5d6cc775394989e1930c979d007d": { + "balance": "1000000000000000000000" + }, + "a7f9220c8047826bd5d5183f4e676a6d77bfed36": { + "balance": "153368000000000000000" + }, + "98d204f9085f8c8e7de23e589b64c6eff692cc63": { + "balance": "2000000000000000000000" + }, + "5a2916b8d2e8cc12e207ab464d433e2370d823d9": { + "balance": "2000000000000000000000" + }, + "c42d6aeb710e3a50bfb44d6c31092969a11aa7f3": { + "balance": "150052000000000000000" + }, + "04ce45f600db18a9d0851b29d9393ebdaafe3dc5": { + "balance": "20000000000000000000" + }, + "7a1370a742ec2687e761a19ac5a794329ee67404": { + "balance": "2999988000000000000000" + }, + "da2ad58e77deddede2187646c465945a8dc3f641": { + "balance": "660000000000000000000" + }, + "ec58bc0d0c20d8f49465664153c5c196fe59e6be": { + "balance": "400000000000000000000" + }, + "f8063af4cc1dd9619ab5d8bff3fcd1faa8488221": { + "balance": "2000000000000000000000" + }, + "b9231eb26e5f9e4b4d288f03906704fab96c87d6": { + "balance": "19700000000000000000000" + }, + "6e5c2d9b1c546a86eefd5d0a5120c9e4e730190e": { + "balance": "199600000000000000000" + }, + "e49936a92a8ccf710eaac342bc454b9b14ebecb1": { + "balance": "2000000000000000000000" + }, + "21dbdb817a0d8404c6bdd61504374e9c43c9210e": { + "balance": "9999917000000000000000" + }, + "5cebe30b2a95f4aefda665651dc0cf7ef5758199": { + "balance": "18200000000000000000" + }, + "597038ff91a0900cbbab488af483c790e6ec00a0": { + "balance": "10000000000000000000000" + }, + "0fa5d8c5b3f294efd495ab69d768f81872508548": { + "balance": "2000000000000000000000" + }, + "feef3b6eabc94affd3310c1c4d0e65375e131119": { + "balance": "20000000000000000000" + }, + "1ce81d31a7923022e125bf48a3e03693b98dc9dd": { + "balance": "2000000000000000000000" + }, + "5887dc6a33dfed5ac1edefe35ef91a216231ac96": { + "balance": "250000000000000000000" + }, + "4e8e47ae3b1ef50c9d54a38e14208c1abd3603c2": { + "balance": "2235000000000000000000" + }, + "e845e387c4cbdf982280f6aa01c40e4be958ddb2": { + "balance": "25000000000000000000000" + }, + "71d9494e50c5dd59c599dba3810ba1755e6537f0": { + "balance": "4000000000000000000000" + }, + "6eb5578a6bb7c32153195b0d8020a6914852c059": { + "balance": "660000000000000000000000" + }, + "543f8c674e2462d8d5daa0e80195a8708e11a29e": { + "balance": "63940000000000000000" + }, + "a0459ef3693aacd1647cd5d8929839204cef53be": { + "balance": "1000000000000000000000" + }, + "dda371e600d30688d4710e088e02fdf2b9524d5f": { + "balance": "6920000000000000000000" + }, + "dd4dd6d36033b0636fcc8d0938609f4dd64f4a86": { + "balance": "60000000000000000000" + }, + "3bd624b548cb659736907ed8aa3c0c705e24b575": { + "balance": "2000000000000000000000" + }, + "414599092e879ae25372a84d735af5c4e510cd6d": { + "balance": "400000000000000000000" + }, + "3d66cd4bd64d5c8c1b5eea281e106d1c5aad2373": { + "balance": "1951100000000000000000" + }, + "5948bc3650ed519bf891a572679fd992f8780c57": { + "balance": "197000000000000000000" + }, + "8b74a7cb1bb8c58fce267466a30358adaf527f61": { + "balance": "13620000000000000000000" + }, + "3f10800282d1b7ddc78fa92d8230074e1bf6aeae": { + "balance": "4925000000000000000000" + }, + "32dbb6716c54e83165829a4abb36757849b6e47d": { + "balance": "1000000000000000000000" + }, + "e6b3ac3f5d4da5a8857d0b3f30fc4b2b692b77d7": { + "balance": "1460000000000000000000" + }, + "052a58e035f1fe9cdd169bcf20970345d12b9c51": { + "balance": "1490000000000000000000" + }, + "581bdf1bb276dbdd86aedcdb397a01efc0e00c5b": { + "balance": "1000000000000000000000" + }, + "604e9477ebf4727c745bcabbedcb6ccf29994022": { + "balance": "1000060000000000000000" + }, + "59b96deb8784885d8d3b4a166143cc435d2555a1": { + "balance": "1337000000000000000000" + }, + "37d980a12ee3bf23cc5cdb63b4ae45691f74c837": { + "balance": "2000000000000000000000" + }, + "3bfbd3847c17a61cf3f17b52f8eba1b960b3f39f": { + "balance": "3000000000000000000000" + }, + "49c941e0e5018726b7290fc473b471d41dae80d1": { + "balance": "500000000000000000000" + }, + "f26bcedce3feadcea3bc3e96eb1040dfd8ffe1a0": { + "balance": "775000000000000000000" + }, + "d0944aa185a1337061ae20dc9dd96c83b2ba4602": { + "balance": "200000000000000000000" + }, + "904caa429c619d940f8e6741826a0db692b19728": { + "balance": "1000000000000000000000" + }, + "b95c9b10aa981cf4a67a71cc52c504dee8cf58bd": { + "balance": "4000000000000000000000" + }, + "15874686b6733d10d703c9f9bec6c52eb8628d67": { + "balance": "2000000000000000000000" + }, + "1374facd7b3f8d68649d60d4550ee69ff0484133": { + "balance": "269700000000000000000" + }, + "b0e469c886593815b3495638595daef0665fae62": { + "balance": "1940000000000000000000" + }, + "47ff6feb43212060bb1503d7a397fc08f4e70352": { + "balance": "2000000000000000000000" + }, + "c60b04654e003b4683041f1cbd6bc38fda7cdbd6": { + "balance": "2000000000000000000000" + }, + "3ecdb532e397579662b2a46141e78f8235936a5f": { + "balance": "66850000000000000000" + }, + "b3a8c2cb7d358e5739941d945ba9045a023a8bbb": { + "balance": "1000000000000000000000" + }, + "32ef5cdc671df5562a901aee5db716b9be76dcf6": { + "balance": "2000000000000000000000" + }, + "c94110e71afe578aa218e4fc286403b0330ace8d": { + "balance": "2000000000000000000000" + }, + "9b43dcb95fde318075a567f1e6b57617055ef9e8": { + "balance": "3940000000000000000000" + }, + "efeea010756f81da4ba25b721787f058170befbd": { + "balance": "32470000000000000000" + }, + "c88255eddcf521c6f81d97f5a42181c9073d4ef1": { + "balance": "290793000000000000000" + }, + "dd47189a3e64397167f0620e484565b762bfbbf4": { + "balance": "1850000000000000000000" + }, + "82f39b2758ae42277b86d69f75e628d958ebcab0": { + "balance": "40000000000000000000000" + }, + "e37f5fdc6ec97d2f866a1cfd0d3a4da4387b22b5": { + "balance": "10000000000000000000000" + }, + "62331df2a3cbee3520e911dea9f73e905f892505": { + "balance": "2000000000000000000000" + }, + "8c5d16ed65e3ed7e8b96ca972bc86173e3500b03": { + "balance": "2000000000000000000000" + }, + "8b9841862e77fbbe919470935583a93cf027e450": { + "balance": "2000054000000000000000" + }, + "c8dd27f16bf22450f5771b9fe4ed4ffcb30936f4": { + "balance": "197000000000000000000" + }, + "dec8a1a898f1b895d8301fe64ab3ad5de941f689": { + "balance": "787803000000000000000" + }, + "61c4ee7c864c4d6b5e37ea1331c203739e826b2f": { + "balance": "30063000000000000000" + }, + "3250e3e858c26adeccadf36a5663c22aa84c4170": { + "balance": "5000000000000000000000" + }, + "299e0bca55e069de8504e89aca6eca21d38a9a5d": { + "balance": "55500000000000000000" + }, + "d50f7fa03e389876d3908b60a537a6706304fb56": { + "balance": "100000000000000000000" + }, + "69073269729e6414b26ec8dc0fd935c73b579f1e": { + "balance": "30000000000000000000000" + }, + "14fcd1391e7d732f41766cdacd84fa1deb9ffdd2": { + "balance": "2000000000000000000000" + }, + "823768746737ce6da312d53e54534e106f967cf3": { + "balance": "20000000000000000000" + }, + "882f75708386653c80171d0663bfe30b017ed0ad": { + "balance": "2000000000000000000000" + }, + "a25b086437fd2192d0a0f64f6ed044f38ef3da32": { + "balance": "335000000000000000000" + }, + "5a9c8b69fc614d69564999b00dcb42db67f97e90": { + "balance": "3429227000000000000000" + }, + "a2b701f9f5cdd09e4ba62baebae3a88257105885": { + "balance": "1000000000000000000000" + }, + "5e7b8c54dc57b0402062719dee7ef5e37ea35d62": { + "balance": "2877224000000000000000" + }, + "7ffabfbc390cbe43ce89188f0868b27dcb0f0cad": { + "balance": "6370000000000000000000" + }, + "b5cdbc4115406f52e5aa85d0fea170d2979cc7ba": { + "balance": "1337000000000000000000" + }, + "263814309de4e635cf585e0d365477fc40e66cf7": { + "balance": "146000000000000000000" + }, + "24cff0e9336a9f80f9b1cb968caf6b1d1c4932a4": { + "balance": "200200000000000000000" + }, + "d3a941c961e8ca8b1070f23c6d6d0d2a758a4444": { + "balance": "200000000000000000000" + }, + "a97beb3a48c45f1528284cb6a95f7de453358ec6": { + "balance": "31000000000000000000000" + }, + "4dd131c74a068a37c90aded4f309c2409f6478d3": { + "balance": "400008000000000000000" + }, + "653675b842d7d8b461f722b4117cb81dac8e639d": { + "balance": "31000000000000000000" + }, + "561be9299b3e6b3e63b79b09169d1a948ae6db01": { + "balance": "500000000000000000000" + }, + "dc067ed3e12d711ed475f5156ef7e71a80d934b9": { + "balance": "9550000000000000000000" + }, + "08d97eadfcb7b064e1ccd9c8979fbee5e77a9719": { + "balance": "266063000000000000000" + }, + "6e4c2ab7db026939dbd3bc68384af660a61816b2": { + "balance": "167000000000000000000" + }, + "bf4c73a7ede7b164fe072114843654e4d8781dde": { + "balance": "2000000000000000000000" + }, + "f504943aaf16796e0b341bbcdf21d11cc586cdd1": { + "balance": "9000000000000000000000" + }, + "ea81ca8638540cd9d4d73d060f2cebf2241ffc3e": { + "balance": "1970000000000000000000" + }, + "9944fee9d34a4a880023c78932c00b59d5c82a82": { + "balance": "750022000000000000000" + }, + "12f460ae646cd2780fd35c50a6af4b9accfa85c6": { + "balance": "1000000000000000000000" + }, + "4e232d53b3e6be8f895361d31c34d4762b12c82e": { + "balance": "1760000000000000000000" + }, + "6bb2aca23fa1626d18efd6777fb97db02d8e0ae4": { + "balance": "40000000000000000000000" + }, + "bc4e471560c99c8a2a4b1b1ad0c36aa6502b7c4b": { + "balance": "12000000000000000000000" + }, + "2e2cbd7ad82547b4f5ff8b3ab56f942a6445a3b0": { + "balance": "200000000000000000000" + }, + "21ecb2dfa65779c7592d041cd2105a81f4fd4e46": { + "balance": "1000000000000000000000" + }, + "34318625818ec13f11835ae97353ce377d6f590a": { + "balance": "1520000000000000000000" + }, + "a7ef35ce87eda6c28df248785815053ec97a5045": { + "balance": "4999998000000000000000" + }, + "6a514e6242f6b68c137e97fea1e78eb555a7e5f7": { + "balance": "20000000000000000000" + }, + "9340b5f678e45ee05eb708bb7abb6ec8f08f1b6b": { + "balance": "6000000000000000000000" + }, + "43cc08d0732aa58adef7619bed46558ad7774173": { + "balance": "4443926000000000000000" + }, + "12e9a4ad2ad57484dd700565bddb46423bd9bd31": { + "balance": "19999800000000000000000" + }, + "ebbeeb259184a6e01cccfc2207bbd883785ac90a": { + "balance": "619966000000000000000" + }, + "704ab1150d5e10f5e3499508f0bf70650f028d4b": { + "balance": "4000000000000000000000" + }, + "fc361105dd90f9ede566499d69e9130395f12ac8": { + "balance": "395000000000000000000000" + }, + "c1b9a5704d351cfe983f79abeec3dbbbae3bb629": { + "balance": "20000000000000000000" + }, + "66f50406eb1b11a946cab45927cca37470e5a208": { + "balance": "2000000000000000000000" + }, + "53942e7949d6788bb780a7e8a0792781b1614b84": { + "balance": "15899600000000000000000" + }, + "32ba9a7d0423e03a525fe2ebeb661d2085778bd8": { + "balance": "20000000000000000000000" + }, + "11c0358aa6479de21866fe21071924b65e70f8b9": { + "balance": "36400000000000000000000" + }, + "76cb9c8b69f4387675c48253e234cb7e0d74a426": { + "balance": "7396300000000000000000" + }, + "9f5f44026b576a4adb41e95961561d41039ca391": { + "balance": "250000000000000000000" + }, + "533a73a4a2228eee05c4ffd718bbf3f9c1b129a7": { + "balance": "6000000000000000000000" + }, + "dcc52d8f8d9fc742a8b82767f0555387c563efff": { + "balance": "500000000000000000000" + }, + "f456a75bb99655a7412ce97da081816dfdb2b1f2": { + "balance": "200000000000000000000" + }, + "d0c101fd1f01c63f6b1d19bc920d9f932314b136": { + "balance": "20000000000000000000000" + }, + "dabc225042a6592cfa13ebe54efa41040878a5a2": { + "balance": "259550000000000000000" + }, + "38eec6e217f4d41aa920e424b9525197041cd4c6": { + "balance": "4428166000000000000000" + }, + "8a247d186510809f71cffc4559471c3910858121": { + "balance": "1790000000000000000000" + }, + "4f152b2fb8659d43776ebb1e81673aa84169be96": { + "balance": "2000000000000000000000" + }, + "b4496ddb27799a222457d73979116728e8a1845b": { + "balance": "2610331000000000000000" + }, + "4a4053b31d0ee5dbafb1d06bd7ac7ff3222c47d6": { + "balance": "1400000000000000000000" + }, + "0f7bea4ef3f73ae0233df1e100718cbe29310bb0": { + "balance": "2000000000000000000000" + }, + "c836e24a6fcf29943b3608e662290a215f6529ea": { + "balance": "292000000000000000000" + }, + "1765361c2ec2f83616ce8363aae21025f2566f40": { + "balance": "5000000000000000000000" + }, + "b6e6c3222b6b6f9be2875d2a89f127fb64100fe2": { + "balance": "8008000000000000000000" + }, + "01bbc14f67af0639aab1441e6a08d4ce7162090f": { + "balance": "1309500000000000000000" + }, + "af2058c7282cf67c8c3cf930133c89617ce75d29": { + "balance": "6920000000000000000000" + }, + "464d9c89cce484df000277198ed8075fa63572d1": { + "balance": "20000000000000000000" + }, + "50cd97e9378b5cf18f173963236c9951ef7438a5": { + "balance": "1400000000000000000000" + }, + "cb47bd30cfa8ec5468aaa6a94642ced9c819c8d4": { + "balance": "4000000000000000000000" + }, + "6b10f8f8b3e3b60de90aa12d155f9ff5ffb22c50": { + "balance": "2000000000000000000000" + }, + "09b7a988d13ff89186736f03fdf46175b53d16e0": { + "balance": "6000000000000000000000" + }, + "5bfafe97b1dd1d712be86d41df79895345875a87": { + "balance": "500000000000000000000" + }, + "a06cd1f396396c0a64464651d7c205efaf387ca3": { + "balance": "1999944000000000000000" + }, + "fc0096b21e95acb8d619d176a4a1d8d529badbef": { + "balance": "384601000000000000000" + }, + "a74444f90fbb54e56f3ac9b6cfccaa4819e4614a": { + "balance": "20000000000000000000" + }, + "3c15b3511df6f0342e7348cc89af39a168b7730f": { + "balance": "1000000000000000000000" + }, + "3d6ff82c9377059fb30d9215723f60c775c891fe": { + "balance": "250066000000000000000" + }, + "a524a8cccc49518d170a328270a2f88133fbaf5d": { + "balance": "294500000000000000000" + }, + "8a7a06be199a3a58019d846ac9cbd4d95dd757de": { + "balance": "3000200000000000000000" + }, + "d744ac7e5310be696a63b003c40bd039370561c6": { + "balance": "1670000000000000000000" + }, + "fe362688845fa244cc807e4b1130eb3741a8051e": { + "balance": "1000000000000000000000" + }, + "b2d0360515f17daba90fcbac8205d569b915d6ac": { + "balance": "6000000000000000000000" + }, + "c53594c7cfb2a08f284cc9d7a63bbdfc0b319732": { + "balance": "49200000000000000000000" + }, + "b3c228731d186d2ded5b5fbe004c666c8e469b86": { + "balance": "29000000000000000000" + }, + "63e414603e80d4e5a0f5c18774204642258208e4": { + "balance": "5000000000000000000000" + }, + "826ce5790532e0548c6102a30d3eac836bd6388f": { + "balance": "18000000000000000000000" + }, + "c5e812f76f15f2e1f2f9bc4823483c8804636f67": { + "balance": "73000000000000000000" + }, + "116fef5e601642c918cb89160fc2293ba71da936": { + "balance": "802200000000000000000" + }, + "08b84536b74c8c01543da88b84d78bb95747d822": { + "balance": "200000000000000000000" + }, + "04a80afad53ef1f84165cfd852b0fdf1b1c24ba8": { + "balance": "58000000000000000000" + }, + "2b0362633614bfcb583569438ecc4ea57b1d337e": { + "balance": "20000000000000000000000" + }, + "e95179527deca5916ca9a38f215c1e9ce737b4c9": { + "balance": "10000000000000000000000" + }, + "2c5df866666a194b26cebb407e4a1fd73e208d5e": { + "balance": "1000000000000000000000" + }, + "529e824fa072582b4032683ac7eecc1c04b4cac1": { + "balance": "2000000000000000000000" + }, + "78634371e17304cbf339b1452a4ce438dc764cce": { + "balance": "10000000000000000000000" + }, + "e172dfc8f80cd1f8cd8539dc26082014f5a8e3e8": { + "balance": "3000000000000000000000" + }, + "b07618328a901307a1b7a0d058fcd5786e9e72fe": { + "balance": "30239500000000000000000" + }, + "b0571153db1c4ed7acaefe13ecdfdb72e7e4f06a": { + "balance": "80520000000000000000000" + }, + "ad910a23d6850613654af786337ad2a70868ac6d": { + "balance": "1999800000000000000000" + }, + "4da5edc688b0cb62e1403d1700d9dcb99ffe3fd3": { + "balance": "2000000000000000000000" + }, + "be2471a67f6047918772d0e36839255ed9d691ae": { + "balance": "4000000000000000000000" + }, + "28868324337e11ba106cb481da962f3a8453808d": { + "balance": "2000000000000000000000" + }, + "d8f94579496725b5cb53d7985c989749aff849c0": { + "balance": "17000000000000000000000" + }, + "4981c5ff66cc4e9680251fc4cd2ff907cb327865": { + "balance": "750000000000000000000" + }, + "fd2872d19e57853cfa16effe93d0b1d47b4f93fb": { + "balance": "4000000000000000000000" + }, + "63c8dfde0b8e01dadc2e748c824cc0369df090b3": { + "balance": "3880000000000000000000" + }, + "c4dd048bfb840e2bc85cb53fcb75abc443c7e90f": { + "balance": "3716000000000000000000" + }, + "f579714a45eb8f52c3d57bbdefd2c15b2e2f11df": { + "balance": "1560000000000000000000" + }, + "cc7b0481cc32e6faef2386a07022bcb6d2c3b4fc": { + "balance": "3160000000000000000000" + }, + "a0aa5f0201f04d3bbeb898132f7c11679466d901": { + "balance": "36600000000000000000" + }, + "f3df63a97199933330383b3ed7570b96c4812334": { + "balance": "2000000000000000000000" + }, + "42732d8ef49ffda04b19780fd3c18469fb374106": { + "balance": "425068000000000000000" + }, + "6f92d6e4548c78996509ee684b2ee29ba3c532b4": { + "balance": "1000000000000000000000" + }, + "fff4bad596633479a2a29f9a8b3f78eefd07e6ee": { + "balance": "100000000000000000000" + }, + "ac4460a76e6db2b9fcd152d9c7718d9ac6ed8c6f": { + "balance": "200000000000000000000" + }, + "553b6b1c57050e88cf0c31067b8d4cd1ff80cb09": { + "balance": "400000000000000000000" + }, + "84b6b6adbe2f5b3e2d682c66af1bc4905340c3ed": { + "balance": "619333000000000000000" + }, + "9f4a7195ac7c151ca258cafda0cab083e049c602": { + "balance": "1537100000000000000000" + }, + "2955c357fd8f75d5159a3dfa69c5b87a359dea8c": { + "balance": "2000000000000000000000" + }, + "11d7844a471ef89a8d877555583ceebd1439ea26": { + "balance": "10098000000000000000000" + }, + "34b454416e9fb4274e6addf853428a0198d62ee1": { + "balance": "407000000000000000000" + }, + "308dd21cebe755126704b48c0f0dc234c60ba9b1": { + "balance": "200000000000000000000" + }, + "381db4c8465df446a4ce15bf81d47e2f17c980bf": { + "balance": "32000000000000000000000" + }, + "1abc4e253b080aeb437984ab05bca0979aa43e1c": { + "balance": "1000000000000000000000" + }, + "53e35b12231f19c3fd774c88fec8cbeedf1408b2": { + "balance": "512000000000000000000" + }, + "69e2e2e704307ccc5b5ca3f164fece2ea7b2e512": { + "balance": "7000000000000000000000" + }, + "1914f1eb95d1277e93b6e61b668b7d77f13a11a1": { + "balance": "970000000000000000000" + }, + "50e13023bd9ca96ad4c53fdfd410cb6b1f420bdf": { + "balance": "200000000000000000000" + }, + "46224f32f4ece5c8867090d4409d55e50b18432d": { + "balance": "6000000000000000000000" + }, + "ff83855051ee8ffb70b4817dba3211ed2355869d": { + "balance": "400000000000000000000" + }, + "fb39189af876e762c71d6c3e741893df226cedd6": { + "balance": "4000000000000000000000" + }, + "9875623495a46cdbf259530ff838a1799ec38991": { + "balance": "2000000000000000000000" + }, + "e1b39b88d9900dbc4a6cdc481e1060080a8aec3c": { + "balance": "2000000000000000000000" + }, + "5baf6d749620803e8348af3710e5c4fbf20fc894": { + "balance": "5003680000000000000000" + }, + "9c54e4ed479a856829c6bb42da9f0b692a75f728": { + "balance": "7520000000000000000000" + }, + "486a6c8583a84484e3df43a123837f8c7e2317d0": { + "balance": "323378000000000000000" + }, + "d235d15cb5eceebb61299e0e827fa82748911d89": { + "balance": "4000000000000000000000" + }, + "47d792a756779aedf1343e8883a6619c6c281184": { + "balance": "2000000000000000000000" + }, + "70c213488a020c3cfb39014ef5ba6404724bcaa3": { + "balance": "1940000000000000000000" + }, + "133c490fa5bf7f372888e607d958fab7f955bae1": { + "balance": "1580000000000000000000" + }, + "a9e194661aac704ee9dea043974e9692ded84a5d": { + "balance": "482400000000000000000" + }, + "bc6b58364bf7f1951c309e0cba0595201cd73f9a": { + "balance": "1812400000000000000000" + }, + "2309d34091445b3232590bd70f4f10025b2c9509": { + "balance": "10000000000000000000000" + }, + "d89bc271b27ba3ab6962c94a559006ae38d5f56a": { + "balance": "2000000000000000000000" + }, + "ff0e2fec304207467e1e3307f64cbf30af8fd9cd": { + "balance": "2000000000000000000000" + }, + "c0b0b7a8a6e1acdd05e47f94c09688aa16c7ad8d": { + "balance": "64234000000000000000" + }, + "b66f92124b5e63035859e390628869dbdea9485e": { + "balance": "9850000000000000000000" + }, + "a9e6e25e656b762558619f147a21985b8874edfe": { + "balance": "2000000000000000000000" + }, + "a43e1947a9242b355561c30a829dfeeca2815af8": { + "balance": "3878255000000000000000" + }, + "8b20ad3b94656dbdc0dd21a393d8a7d9e02138cb": { + "balance": "3000000000000000000000" + }, + "aca2a838330b17302da731d30db48a04f0f207c1": { + "balance": "1337000000000000000000" + }, + "fa60868aafd4ff4c5c57914b8ed58b425773dfa9": { + "balance": "8557400000000000000000" + }, + "1848003c25bfd4aa90e7fcb5d7b16bcd0cffc0d8": { + "balance": "1000000000000000000000" + }, + "b4b185d943ee2b58631e33dff5af6854c17993ac": { + "balance": "1000000000000000000000" + }, + "7719888795ad745924c75760ddb1827dffd8cda8": { + "balance": "1999980000000000000000" + }, + "ccd521132d986cb96869842622a7dda26c3ed057": { + "balance": "2000000000000000000000" + }, + "253e32b74ea4490ab92606fda0aa257bf23dcb8b": { + "balance": "10000000000000000000000" + }, + "3712367e5e55a96d5a19168f6eb2bc7e9971f869": { + "balance": "1000000000000000000000" + }, + "8f29a14a845ad458f2d108b568d813166bcdf477": { + "balance": "10000000000000000000000" + }, + "51a8c2163602a32ee24cf4aa97fd9ea414516941": { + "balance": "62904000000000000000" + }, + "61cea71fa464d62a07063f920b0cc917539733d8": { + "balance": "1670000000000000000000" + }, + "6f81f3abb1f933b1df396b8e9cc723a89b7c9806": { + "balance": "280000000000000000000" + }, + "61b1b8c012cd4c78f698e470f90256e6a30f48dd": { + "balance": "200000000000000000000" + }, + "4f3f2c673069ac97c2023607152981f5cd6063a0": { + "balance": "600000000000000000000" + }, + "e2efa5fca79538ce6068bf31d2c516d4d53c08e5": { + "balance": "131200000000000000000" + }, + "2383c222e67e969190d3219ef14da37850e26c55": { + "balance": "2000000000000000000000" + }, + "eac3af5784927fe9a598fc4eec38b8102f37bc58": { + "balance": "1000000000000000000000" + }, + "4fe56ab3bae1b0a44433458333c4b05a248f8241": { + "balance": "2180000000000000000000" + }, + "fe9cfc3bb293ddb285e625f3582f74a6b0a5a6cd": { + "balance": "1970000000000000000000" + }, + "f48e1f13f6af4d84b371d7de4b273d03a263278e": { + "balance": "600000000000000000000" + }, + "1ba9228d388727f389150ea03b73c82de8eb2e09": { + "balance": "7258000000000000000000" + }, + "37a7a6ff4ea3d60ec307ca516a48d3053bb79cbb": { + "balance": "2000000000000000000000" + }, + "e33840d8bca7da98a6f3d096d83de78b70b71ef8": { + "balance": "2000000000000000000000" + }, + "8e7fd23848f4db07906a7d10c04b21803bb08227": { + "balance": "1000000000000000000000" + }, + "07d4334ec385e8aa54eedaeadb30022f0cdfa4ab": { + "balance": "2629946000000000000000" + }, + "d4b085fb086f3d0d68bf12926b1cc3142cae8770": { + "balance": "3700000000000000000000" + }, + "5a87f034e6f68f4e74ffe60c64819436036cf7d7": { + "balance": "20000000000000000000" + }, + "c00ab080b643e1c2bae363e0d195de2efffc1c44": { + "balance": "500000000000000000000" + }, + "22f3c779dd79023ea92a78b65c1a1780f62d5c4a": { + "balance": "1970000000000000000000" + }, + "c7d5c7054081e918ec687b5ab36e973d18132935": { + "balance": "182000000000000000000" + }, + "9662ee021926682b31c5f200ce457abea76c6ce9": { + "balance": "670500000000000000000" + }, + "116a09df66cb150e97578e297fb06e13040c893c": { + "balance": "2000000000000000000000" + }, + "b7240af2af90b33c08ae9764103e35dce3638428": { + "balance": "8464547000000000000000" + }, + "e8b28acda971725769db8f563d28666d41ddab6c": { + "balance": "10000000000000000000000" + }, + "17d4918dfac15d77c47f9ed400a850190d64f151": { + "balance": "2000000000000000000000" + }, + "c42250b0fe42e6b7dcd5c890a6f0c88f5f5fb574": { + "balance": "149800000000000000000" + }, + "5da2a9a4c2c0a4a924cbe0a53ab9d0c627a1cfa0": { + "balance": "733202000000000000000" + }, + "5869fb867d71f1387f863b698d09fdfb87c49b5c": { + "balance": "3666000000000000000000" + }, + "d49a75bb933fca1fca9aa1303a64b6cb44ea30e1": { + "balance": "10000000000000000000000" + }, + "76331e30796ce664b2700e0d4153700edc869777": { + "balance": "2000000000000000000000" + }, + "8a5fb75793d043f1bcd43885e037bd30a528c927": { + "balance": "356500000000000000000" + }, + "fc0ee6f7c2b3714ae9916c45566605b656f32441": { + "balance": "1760000000000000000000" + }, + "bf50ce2e264b9fe2b06830617aedf502b2351b45": { + "balance": "1000000000000000000000" + }, + "0f6000de1578619320aba5e392706b131fb1de6f": { + "balance": "499986000000000000000" + }, + "c953f934c0eb2d0f144bdab00483fd8194865ce7": { + "balance": "2000000000000000000000" + }, + "24fd9a6c874c2fab3ff36e9afbf8ce0d32c7de92": { + "balance": "1337000000000000000000" + }, + "c6cd68ec35362c5ad84c82ad4edc232125912d99": { + "balance": "27750000000000000000000" + }, + "2a67660a1368efcd626ef36b2b1b601980941c05": { + "balance": "133700000000000000000" + }, + "9deb39027af877992b89f2ec4a1f822ecdf12693": { + "balance": "2000000000000000000000" + }, + "c12f881fa112b8199ecbc73ec4185790e614a20f": { + "balance": "2000000000000000000000" + }, + "d58a52e078a805596b0d56ea4ae1335af01c66eb": { + "balance": "267400000000000000000" + }, + "4d7cfaa84cb33106800a8c802fb8aa463896c599": { + "balance": "1790000000000000000000" + }, + "0ee391f03c765b11d69026fd1ab35395dc3802a0": { + "balance": "200000000000000000000" + }, + "a192f06ab052d5fd7f94eea8318e827815fe677a": { + "balance": "131400000000000000000" + }, + "8f0ab894bd3f4e697dbcfb859d497a9ba195994a": { + "balance": "39501652000000000000000" + }, + "387eeafd6b4009deaf8bd5b85a72983a8dcc3487": { + "balance": "4000000000000000000000" + }, + "03b0f17cd4469ddccfb7da697e82a91a5f9e7774": { + "balance": "20000000000000000000" + }, + "11172b278ddd44eea2fdf4cb1d16962391c453d9": { + "balance": "935900000000000000000000" + }, + "33d172ab075c51db1cd40a8ca8dbff0d93b843bb": { + "balance": "5727139000000000000000" + }, + "909b5e763a39dcc795223d73a1dbb7d94ca75ac8": { + "balance": "2000000000000000000000" + }, + "0ca12ab0b9666cf0cec6671a15292f2653476ab2": { + "balance": "210000600000000000000000" + }, + "6b5ae7bf78ec75e90cb503c778ccd3b24b4f1aaf": { + "balance": "800000000000000000000" + }, + "d9e3857efd1e202a441770a777a49dcc45e2e0d3": { + "balance": "223500000000000000000" + }, + "d703c6a4f11d60194579d58c2766a7ef16c30a29": { + "balance": "2000000000000000000000" + }, + "838bd565f99fde48053f7917fe333cf84ad548ab": { + "balance": "200000000000000000000" + }, + "8168edce7f2961cf295b9fcd5a45c06cdeda6ef5": { + "balance": "200000000000000000000" + }, + "de50868eb7e3c71937ec73fa89dd8b9ee10d45aa": { + "balance": "1000000000000000000000" + }, + "087498c0464668f31150f4d3c4bcdda5221ba102": { + "balance": "20000000000000000000" + }, + "613fab44b16bbe554d44afd178ab1d02f37aeaa5": { + "balance": "2000000000000000000000" + }, + "e2ee691f237ee6529b6557f2fcdd3dcf0c59ec63": { + "balance": "5450048000000000000000" + }, + "a9ed377b7d6ec25971c1a597a3b0f3bead57c98f": { + "balance": "400000000000000000000" + }, + "175feeea2aa4e0efda12e1588d2f483290ede81a": { + "balance": "200000000000000000000" + }, + "b51ddcb4dd4e8ae6be336dd9654971d9fec86b41": { + "balance": "421133000000000000000" + }, + "92c0f573eccf62c54810ee6ba8d1f113542b301b": { + "balance": "3384000000000000000000" + }, + "a109e18bb0a39c9ef82fa19597fc5ed8e9eb6d58": { + "balance": "1640000000000000000000" + }, + "f74e6e145382b4db821fe0f2d98388f45609c69f": { + "balance": "100000000000000000000" + }, + "378f37243f3ff0bef5e1dc85eb4308d9340c29f9": { + "balance": "2000200000000000000000" + }, + "84e9949680bece6841b9a7e5250d08acd87d16cd": { + "balance": "200000000000000000000" + }, + "882bd3a2e9d74110b24961c53777f22f1f46dc5d": { + "balance": "13370000000000000000000" + }, + "acce01e0a70610dc70bb91e9926fa9957f372fba": { + "balance": "537000000000000000000" + }, + "c5f687717246da8a200d20e5e9bcac60b67f3861": { + "balance": "28650000000000000000" + }, + "e14617f6022501e97e7b3e2d8836aa61f0ff2dba": { + "balance": "200000000000000000000" + }, + "076ee99d3548623a03b5f99859d2d785a1778d48": { + "balance": "200000000000000000000" + }, + "2c424ee47f583cdce07ae318b6fad462381d4d2b": { + "balance": "4000000000000000000000" + }, + "f98250730c4c61c57f129835f2680894794542f3": { + "balance": "4000000000000000000000" + }, + "ed1b24b6912d51b334ac0de6e771c7c0454695ea": { + "balance": "40000000000000000000" + }, + "ffd5170fd1a8118d558e7511e364b24906c4f6b3": { + "balance": "60085000000000000000" + }, + "bf49c14898316567d8b709c2e50594b366c6d38c": { + "balance": "733202000000000000000" + }, + "65ea26eabbe2f64ccccfe06829c25d4637520225": { + "balance": "700000000000000000000" + }, + "5c5419565c3aad4e714e0739328e3521c98f05cc": { + "balance": "528000000000000000000" + }, + "c53b50fd3b2b72bc6c430baf194a515585d3986d": { + "balance": "20000000000000000000" + }, + "2b74c373d04bfb0fd60a18a01a88fbe84770e58c": { + "balance": "40000000000000000000" + }, + "d97f4526dea9b163f8e8e33a6bcf92fb907de6ec": { + "balance": "284000000000000000000" + }, + "a4a49f0bc8688cc9e6dc04e1e08d521026e65574": { + "balance": "200000000000000000000" + }, + "575c00c2818210c28555a0ff29010289d3f82309": { + "balance": "10000000000000000000000" + }, + "3f1233714f204de9de4ee96d073b368d8197989f": { + "balance": "38606000000000000000" + }, + "f964d98d281730ba35b2e3a314796e7b42fedf67": { + "balance": "1543800000000000000000" + }, + "1deec01abe5c0d952de9106c3dc30639d85005d6": { + "balance": "2000000000000000000000" + }, + "12d60d65b7d9fc48840be5f891c745ce76ee501e": { + "balance": "21359400000000000000000" + }, + "5c6136e218de0a61a137b2b3962d2a6112b809d7": { + "balance": "294273000000000000000" + }, + "cd43258b7392a930839a51b2ef8ad23412f75a9f": { + "balance": "2000000000000000000000" + }, + "db3f258ab2a3c2cf339c4499f75a4bd1d3472e9e": { + "balance": "1500000000000000000000" + }, + "0edd4b580ff10fe06c4a03116239ef96622bae35": { + "balance": "197000000000000000000" + }, + "1d157c5876c5cad553c912caf6ce2d5277e05c73": { + "balance": "2000000000000000000000" + }, + "cda1b886e3a795c9ba77914e0a2fe5676f0f5ccf": { + "balance": "106024000000000000000" + }, + "f50cbafd397edd556c0678988cb2af5c2617e0a2": { + "balance": "716000000000000000000" + }, + "327bb49e754f6fb4f733c6e06f3989b4f65d4bee": { + "balance": "20000000000000000000" + }, + "c44bdec8c36c5c68baa2ddf1d431693229726c43": { + "balance": "100000000000000000000000" + }, + "34e2849bea583ab0cc37975190f322b395055582": { + "balance": "7780340000000000000000" + }, + "9221c9ce01232665741096ac07235903ad1fe2fc": { + "balance": "126489000000000000000" + }, + "ff3ded7a40d3aff0d7a8c45fa6136aa0433db457": { + "balance": "1999800000000000000000" + }, + "10b5b34d1248fcf017f8c8ffc408ce899ceef92f": { + "balance": "267400000000000000000" + }, + "f1a1f320407964fd3c8f2e2cc8a4580da94f01ea": { + "balance": "2000040000000000000000" + }, + "6c800d4b49ba07250460f993b8cbe00b266a2553": { + "balance": "492500000000000000000" + }, + "f827d56ed2d32720d4abf103d6d0ef4d3bcd559b": { + "balance": "26265000000000000000" + }, + "ffb9c7217e66743031eb377af65c77db7359dcda": { + "balance": "40000000000000000000" + }, + "530319db0a8f93e5bb7d4dbf4816314fbed8361b": { + "balance": "2000000000000000000000" + }, + "9c28a2c4086091cb5da226a657ce3248e8ea7b6f": { + "balance": "280000000000000000000" + }, + "db23a6fef1af7b581e772cf91882deb2516fc0a7": { + "balance": "200000000000000000000" + }, + "6636d7ac637a48f61d38b14cfd4865d36d142805": { + "balance": "500000000000000000000" + }, + "b3c260609b9df4095e6c5dff398eeb5e2df49985": { + "balance": "254030000000000000000" + }, + "58e5c9e344c806650dacfc904d33edba5107b0de": { + "balance": "19100000000000000000" + }, + "4f67396d2553f998785f704e07a639197dd1948d": { + "balance": "300080000000000000000" + }, + "510d8159cc945768c7450790ba073ec0d9f89e30": { + "balance": "2560000000000000000000" + }, + "593c48935beaff0fde19b04d309cd530a28e52ce": { + "balance": "4000000000000000000000" + }, + "c27f4e08099d8cf39ee11601838ef9fc06d7fc41": { + "balance": "1790000000000000000000" + }, + "07723e3c30e8b731ee456a291ee0e798b0204a77": { + "balance": "2000000000000000000000" + }, + "0a652e2a8b77bd97a790d0e91361c98890dbb04e": { + "balance": "1000000000000000000000" + }, + "671015b97670b10d5e583f3d62a61c1c79c5143f": { + "balance": "400000000000000000000" + }, + "7cc24a6a958c20c7d1249660f7586226950b0d9a": { + "balance": "1970000000000000000000" + }, + "6ef9e8c9b6217d56769af97dbb1c8e1b8be799d2": { + "balance": "182000000000000000000" + }, + "5c4368918ace6409c79eca80cdaae4391d2b624e": { + "balance": "4000000000000000000000" + }, + "043707071e2ae21eed977891dc79cd5d8ee1c2da": { + "balance": "2000000000000000000000" + }, + "39bfd978689bec048fc776aa15247f5e1d7c39a2": { + "balance": "20000000000000000000000" + }, + "05915d4e225a668162aee7d6c25fcfc6ed18db03": { + "balance": "66348000000000000000" + }, + "3f551ba93cd54693c183fb9ad60d65e1609673c9": { + "balance": "2000000000000000000000" + }, + "a8c0b02faf02cb5519dda884de7bbc8c88a2da81": { + "balance": "16700000000000000000" + }, + "bd0c5cd799ebc48642ef97d74e8e429064fee492": { + "balance": "326000000000000000000" + }, + "0a931b449ea8f12cdbd5e2c8cc76bad2c27c0639": { + "balance": "23031000000000000000" + }, + "2ea5fee63f337a376e4b918ea82148f94d48a626": { + "balance": "1864242000000000000000" + }, + "cc6c2df00e86eca40f21ffda1a67a1690f477c65": { + "balance": "3160000000000000000000" + }, + "e5e37e19408f2cfbec83349dd48153a4a795a08f": { + "balance": "4200000000000000000000" + }, + "f555a27bb1e2fd4e2cc784caee92939fc06e2fc9": { + "balance": "2000000000000000000000" + }, + "dcf9719be87c6f46756db4891db9b611d2469c50": { + "balance": "1000000000000000000000" + }, + "8e2f9034c9254719c38e50c9aa64305ed696df1e": { + "balance": "4728000000000000000000" + }, + "a01f12d70f44aa7b113b285c22dcdb45873454a7": { + "balance": "18200000000000000000" + }, + "bce40475d345b0712dee703d87cd7657fc7f3b62": { + "balance": "7750000000000000000000" + }, + "bb19bf91cbad74cceb5f811db27e411bc2ea0656": { + "balance": "17600000000000000000" + }, + "acc062702c59615d3444ef6214b8862b009a02ed": { + "balance": "1499936000000000000000" + }, + "449ac4fbe383e36738855e364a57f471b2bfa131": { + "balance": "197000000000000000000000" + }, + "ad59a78eb9a74a7fbdaefafa82eada8475f07f95": { + "balance": "500000000000000000000" + }, + "6b6577f3909a4d6de0f411522d4570386400345c": { + "balance": "1880000000000000000000" + }, + "79bf2f7b6e328aaf26e0bb093fa22da29ef2f471": { + "balance": "1790000000000000000000" + }, + "940f715140509ffabf974546fab39022a41952d2": { + "balance": "1400000000000000000000" + }, + "1d572edd2d87ca271a6714c15a3b37761dcca005": { + "balance": "127674000000000000000" + }, + "d78ecd25adc86bc2051d96f65364866b42a426b7": { + "balance": "3877300000000000000000" + }, + "f9729d48282c9e87166d5eef2d01eda9dbf78821": { + "balance": "99981000000000000000" + }, + "17762560e82a93b3f522e0e524adb8612c3a7470": { + "balance": "1000000000000000000000" + }, + "d500e4d1c9824ba9f5b635cfa3a8c2c38bbd4ced": { + "balance": "400000000000000000000" + }, + "a11effab6cf0f5972cffe4d56596e98968144a8f": { + "balance": "1670000000000000000000" + }, + "f64ecf2117931c6d535a311e4ffeaef9d49405b8": { + "balance": "2674000000000000000000" + }, + "229cc4711b62755ea296445ac3b77fc633821cf2": { + "balance": "39481000000000000000" + }, + "fc989cb487bf1a7d17e4c1b7c4b7aafdda6b0a8d": { + "balance": "20000000000000000000" + }, + "ea8527febfa1ade29e26419329d393b940bbb7dc": { + "balance": "1999944000000000000000" + }, + "bce13e22322acfb355cd21fd0df60cf93add26c6": { + "balance": "200000000000000000000" + }, + "19ff244fcfe3d4fa2f4fd99f87e55bb315b81eb6": { + "balance": "200000000000000000000" + }, + "d2581a55ce23ab10d8ad8c44378f59079bd6f658": { + "balance": "8800000000000000000000" + }, + "4073fa49b87117cb908cf1ab512da754a932d477": { + "balance": "1970000000000000000000" + }, + "b6a82933c9eadabd981e5d6d60a6818ff806e36b": { + "balance": "400000000000000000000" + }, + "c79806032bc7d828f19ac6a640c68e3d820fa442": { + "balance": "20000000000000000000" + }, + "577b2d073c590c50306f5b1195a4b2ba9ecda625": { + "balance": "373600000000000000000" + }, + "7f13d760498d7193ca6859bc95c901386423d76c": { + "balance": "5000000000000000000000" + }, + "416784af609630b070d49a8bcd12235c6428a408": { + "balance": "20000000000000000000000" + }, + "fbe71622bcbd31c1a36976e7e5f670c07ffe16de": { + "balance": "400000000000000000000" + }, + "a5698035391e67a49013c0002079593114feb353": { + "balance": "240000000000000000000" + }, + "ab2871e507c7be3965498e8fb462025a1a1c4264": { + "balance": "775000000000000000000" + }, + "9c78fbb4df769ce2c156920cfedfda033a0e254a": { + "balance": "1970000000000000000000" + }, + "95e6f93dac228bc7585a25735ac2d076cc3a4017": { + "balance": "6000000000000000000000" + }, + "3c1f91f301f4b565bca24751aa1f761322709ddd": { + "balance": "1790000000000000000000" + }, + "f77f9587ff7a2d7295f1f571c886bd33926a527c": { + "balance": "1999800000000000000000" + }, + "755f587e5efff773a220726a13d0f2130d9f896b": { + "balance": "1000000000000000000000" + }, + "8c6aa882ee322ca848578c06cb0fa911d3608305": { + "balance": "600000000000000000000" + }, + "492cb5f861b187f9df21cd4485bed90b50ffe22d": { + "balance": "499928000000000000000" + }, + "95a577dc2eb3ae6cb9dfc77af697d7efdfe89a01": { + "balance": "136000000000000000000" + }, + "4173419d5c9f6329551dc4d3d0ceac1b701b869e": { + "balance": "88000000000000000000" + }, + "456ae0aca48ebcfae166060250525f63965e760f": { + "balance": "300000000000000000000" + }, + "81f8de2c283d5fd4afbda85dedf9760eabbbb572": { + "balance": "3000000000000000000000" + }, + "cd0af3474e22f069ec3407870dd770443d5b12b0": { + "balance": "2626262000000000000000" + }, + "283c2314283c92d4b064f0aef9bb5246a7007f39": { + "balance": "200000000000000000000" + }, + "29b3f561ee7a6e25941e98a5325b78adc79785f3": { + "balance": "100000000000000000000" + }, + "cd4306d7f6947ac1744d4e13b8ef32cb657e1c00": { + "balance": "499986000000000000000" + }, + "d9ec2efe99ff5cf00d03a8317b92a24aef441f7e": { + "balance": "2000000000000000000000" + }, + "83dbf8a12853b40ac61996f8bf1dc8fdbaddd329": { + "balance": "970000000000000000000" + }, + "9d93fab6e22845f8f45a07496f11de71530debc7": { + "balance": "1998000000000000000000" + }, + "fd204f4f4aba2525ba728afdf78792cbdeb735ae": { + "balance": "2000000000000000000000" + }, + "99fad50038d0d9d4c3fbb4bce05606ecadcd5121": { + "balance": "2000000000000000000000" + }, + "d206aaddb336d45e7972e93cb075471d15897b5d": { + "balance": "600000000000000000000" + }, + "428a1ee0ed331d7952ccbe1c7974b2852bd1938a": { + "balance": "2208370000000000000000" + }, + "690228e4bb12a8d4b5e0a797b0c5cf2a7509131e": { + "balance": "1880000000000000000000" + }, + "fa3a1aa4488b351aa7560cf5ee630a2fd45c3222": { + "balance": "878850000000000000000" + }, + "0372e852582e0934344a0fed2178304df25d4628": { + "balance": "20000000000000000000000" + }, + "35ea2163a38cdf9a123f82a5ec00258dae0bc767": { + "balance": "4000000000000000000000" + }, + "d1fed0aee6f5dfd7e25769254c3cfad15adeccaa": { + "balance": "730000000000000000000" + }, + "c05b740620f173f16e52471dc38b9c514a0b1526": { + "balance": "140000000000000000000" + }, + "87e3062b2321e9dfb0875ce3849c9b2e3522d50a": { + "balance": "10000000000000000000000" + }, + "303fbaebbe46b35b6e5b74946a5f99bc1585cae7": { + "balance": "878148000000000000000" + }, + "e7a8e471eafb798f4554cc6e526730fd56e62c7d": { + "balance": "1000000000000000000000" + }, + "ad7dd053859edff1cb6f9d2acbed6dd5e332426f": { + "balance": "1970000000000000000000" + }, + "dc4345d6812e870ae90c568c67d2c567cfb4f03c": { + "balance": "6700000000000000000000" + }, + "a6a08252c8595177cc2e60fc27593e2379c81fb1": { + "balance": "20055000000000000000" + }, + "a9af21acbe482f8131896a228036ba51b19453c3": { + "balance": "49999000000000000000" + }, + "86e3fe86e93da486b14266eadf056cbfa4d91443": { + "balance": "2000000000000000000000" + }, + "744b03bba8582ae5498e2dc22d19949467ab53fc": { + "balance": "500000000000000000000" + }, + "d3118ea3c83505a9d893bb67e2de142d537a3ee7": { + "balance": "20000000000000000000" + }, + "b32f1c2689a5ce79f1bc970b31584f1bcf2283e7": { + "balance": "20000000000000000000" + }, + "4828e4cbe34e1510afb72c2beeac8a4513eaebd9": { + "balance": "3940000000000000000000" + }, + "b07bcc085ab3f729f24400416837b69936ba8873": { + "balance": "2000140000000000000000" + }, + "bdc74873af922b9df474853b0fa7ff0bf8c82695": { + "balance": "3999000000000000000000" + }, + "15ebd1c7cad2aff19275c657c4d808d010efa0f5": { + "balance": "200550000000000000000" + }, + "cbc04b4d8b82caf670996f160c362940d66fcf1a": { + "balance": "6000000000000000000000" + }, + "8197948121732e63d9c148194ecad46e30b749c8": { + "balance": "4000000000000000000000" + }, + "69797bfb12c9bed682b91fbc593591d5e4023728": { + "balance": "10000000000000000000000" + }, + "be9b8c34b78ee947ff81472eda7af9d204bc8466": { + "balance": "150000000000000000000" + }, + "df3f57b8ee6434d047223def74b20f63f9e4f955": { + "balance": "250500000000000000000" + }, + "a3ae1879007d801cb5f352716a4dd8ba2721de3d": { + "balance": "200000000000000000000000" + }, + "cb4bb1c623ba28dc42bdaaa6e74e1d2aa1256c2a": { + "balance": "1999944000000000000000" + }, + "e03c00d00388ecbf4f263d0ac778bb41a57a40d9": { + "balance": "1000072000000000000000" + }, + "fc2c1f88961d019c3e9ea33009152e0693fbf88a": { + "balance": "8000000000000000000000" + }, + "8599cbd5a6a9dcd4b966be387d69775da5e33c6f": { + "balance": "58180000000000000000000" + }, + "b7a31a7c38f3db09322eae11d2272141ea229902": { + "balance": "2000000000000000000000" + }, + "231a15acc199c89fa9cb22441cc70330bdcce617": { + "balance": "500000000000000000000" + }, + "3fbed6e7e0ca9c84fbe9ebcf9d4ef9bb49428165": { + "balance": "2000000000000000000000" + }, + "92cfd60188efdfb2f8c2e7b1698abb9526c1511f": { + "balance": "2000000000000000000000" + }, + "5c936f3b9d22c403db5e730ff177d74eef42dbbf": { + "balance": "75000000000000000000" + }, + "931fe712f64207a2fd5022728843548bfb8cbb05": { + "balance": "2000000000000000000000" + }, + "08d54e83ad486a934cfaeae283a33efd227c0e99": { + "balance": "1039000000000000000000" + }, + "a339a3d8ca280e27d2415b26d1fc793228b66043": { + "balance": "1013600000000000000000" + }, + "581f34b523e5b41c09c87c298e299cbc0e29d066": { + "balance": "1131607000000000000000" + }, + "caaa68ee6cdf0d34454a769b0da148a1faaa1865": { + "balance": "7216000000000000000000" + }, + "0838a7768d9c2aca8ba279adfee4b1f491e326f1": { + "balance": "200000000000000000000" + }, + "dde77a4740ba08e7f73fbe3a1674912931742eeb": { + "balance": "19867021000000000000000" + }, + "cbe810fe0fecc964474a1db97728bc87e973fcbd": { + "balance": "10000000000000000000000" + }, + "86c28b5678af37d727ec05e4447790f15f71f2ea": { + "balance": "200000000000000000000" + }, + "dd6c062193eac23d2fdbf997d5063a346bb3b470": { + "balance": "20000000000000000000" + }, + "5975b9528f23af1f0e2ec08ac8ebaa786a2cb8e0": { + "balance": "345827000000000000000" + }, + "e29d8ae452dcf3b6ac645e630409385551faae0a": { + "balance": "80276000000000000000" + }, + "2fbc85798a583598b522166d6e9dda121d627dbc": { + "balance": "200000000000000000000" + }, + "7a36aba5c31ea0ca7e277baa32ec46ce93cf7506": { + "balance": "20000000000000000000000" + }, + "dbcbcd7a57ea9db2349b878af34b1ad642a7f1d1": { + "balance": "200000000000000000000" + }, + "92aae59768eddff83cfe60bb512e730a05a161d7": { + "balance": "1708015000000000000000" + }, + "a5e93b49ea7c509de7c44d6cfeddef5910deaaf2": { + "balance": "2000000000000000000000" + }, + "e33d980220fab259af6a1f4b38cf0ef3c6e2ea1a": { + "balance": "2000000000000000000000" + }, + "8ed0af11ff2870da0681004afe18b013f7bd3882": { + "balance": "4000000000000000000000" + }, + "f23e5c633221a8f7363e65870c9f287424d2a960": { + "balance": "1380000000000000000000" + }, + "96334bfe04fffa590213eab36514f338b864b736": { + "balance": "400000000000000000000" + }, + "fa1f1971a775c3504fef5079f640c2c4bce7ac05": { + "balance": "2000000000000000000000" + }, + "df44c47fc303ac76e74f97194cca67b5bb3c023f": { + "balance": "591000000000000000000" + }, + "4b74f5e58e2edf76daf70151964a0b8f1de0663c": { + "balance": "324020000000000000000" + }, + "e38b91b35190b6d9deed021c30af094b953fdcaa": { + "balance": "33340000000000000000" + }, + "6b38de841fad7f53fe02da115bd86aaf662466bd": { + "balance": "1730000000000000000000" + }, + "11675a25554607a3b6c92a9ee8f36f75edd3e336": { + "balance": "159800000000000000000" + }, + "0ba8705bf55cf219c0956b5e3fc01c4474a6cdc1": { + "balance": "94963000000000000000" + }, + "0f05f120c89e9fbc93d4ab0c5e2b4a0df092b424": { + "balance": "30000000000000000000000" + }, + "fdd1195f797d4f35717d15e6f9810a9a3ff55460": { + "balance": "18200000000000000000" + }, + "63a61dc30a8e3b30a763c4213c801cbf98738178": { + "balance": "1000000000000000000000" + }, + "e5bdf34f4ccc483e4ca530cc7cf2bb18febe92b3": { + "balance": "126260000000000000000" + }, + "d6e09e98fe1300332104c1ca34fbfac554364ed9": { + "balance": "2000000000000000000000" + }, + "5bd6862d517d4de4559d4eec0a06cad05e2f946e": { + "balance": "200000000000000000000" + }, + "7294ec9da310bc6b4bbdf543b0ef45abfc3e1b4d": { + "balance": "22000000000000000000000" + }, + "ae34861d342253194ffc6652dfde51ab44cad3fe": { + "balance": "466215000000000000000" + }, + "f50ae7fab4cfb5a646ee04ceadf9bf9dd5a8e540": { + "balance": "3999952000000000000000" + }, + "dd2bdfa917c1f310e6fa35aa8af16939c233cd7d": { + "balance": "400000000000000000000" + }, + "e0060462c47ff9679baef07159cae08c29f274a9": { + "balance": "2000000000000000000000" + }, + "b7d12e84a2e4c4a6345af1dd1da9f2504a2a996e": { + "balance": "200000000000000000000" + }, + "f5500178cb998f126417831a08c2d7abfff6ab5f": { + "balance": "1308923000000000000000" + }, + "fd377a385272900cb436a3bb7962cdffe93f5dad": { + "balance": "2000000000000000000000" + }, + "a4a83a0738799b971bf2de708c2ebf911ca79eb2": { + "balance": "600000000000000000000" + }, + "52a5e4de4393eeccf0581ac11b52c683c76ea15d": { + "balance": "19999800000000000000000" + }, + "b07fdeaff91d4460fe6cd0e8a1b0bd8d22a62e87": { + "balance": "5260000000000000000000" + }, + "35f5860149e4bbc04b8ac5b272be55ad1aca58e0": { + "balance": "200000000000000000000" + }, + "fb135eb15a8bac72b69915342a60bbc06b7e077c": { + "balance": "20000000000000000000000" + }, + "02d4a30968a39e2b3498c3a6a4ed45c1c6646822": { + "balance": "2000000000000000000000" + }, + "e44b7264dd836bee8e87970340ed2b9aed8ed0a5": { + "balance": "5772100000000000000000" + }, + "e90a354cec04d69e5d96ddc0c5138d3d33150aa0": { + "balance": "499971000000000000000" + }, + "693d83be09459ef8390b2e30d7f7c28de4b4284e": { + "balance": "2000000000000000000000" + }, + "87bf7cd5d8a929e1c785f9e5449106ac232463c9": { + "balance": "77800000000000000000" + }, + "e5f8ef6d970636b0dcaa4f200ffdc9e75af1741c": { + "balance": "2000000000000000000000" + }, + "fef09d70243f39ed8cd800bf9651479e8f4aca3c": { + "balance": "200000000000000000000" + }, + "e98c91cadd924c92579e11b41217b282956cdaa1": { + "balance": "135800000000000000000" + }, + "c2836188d9a29253e0cbda6571b058c289a0bb32": { + "balance": "2000000000000000000000" + }, + "afa6946effd5ff53154f82010253df47ae280ccc": { + "balance": "1970000000000000000000" + }, + "43c7ebc5b3e7af16f47dc5617ab10e0f39b4afbb": { + "balance": "1910000000000000000000" + }, + "097ecda22567c2d91cb03f8c5215c22e9dcda949": { + "balance": "20055000000000000000" + }, + "3e66b84769566ab67945d5fa81373556bcc3a1fa": { + "balance": "152000000000000000000" + }, + "56373daab46316fd7e1576c61e6affcb6559ddd7": { + "balance": "215340000000000000000" + }, + "faaeba8fc0bbda553ca72e30ef3d732e26e82041": { + "balance": "1338337000000000000000" + }, + "f54c19d9ef3873bfd1f7a622d02d86249a328f06": { + "balance": "44284729000000000000000" + }, + "825309a7d45d1812f51e6e8df5a7b96f6c908887": { + "balance": "2365000000000000000000" + }, + "89009e3c6488bd5e570d1da34eabe28ed024de1b": { + "balance": "20000000000000000000000" + }, + "63977cad7d0dcdc52b9ac9f2ffa136e8642882b8": { + "balance": "75000000000000000000" + }, + "c239abdfae3e9af5457f52ed2b91fd0ab4d9c700": { + "balance": "2000000000000000000000" + }, + "1a4ec6a0ae7f5a9427d23db9724c0d0cffb2ab2f": { + "balance": "179000000000000000000" + }, + "a12a6c2d985daf0e4f5f207ae851aaf729b332cd": { + "balance": "100000000000000000000000" + }, + "cbe52fc533d7dd608c92a260b37c3f45deb4eb33": { + "balance": "1000000000000000000000" + }, + "abb2e6a72a40ba6ed908cdbcec3c5612583132fe": { + "balance": "1460000000000000000000" + }, + "6503860b191008c15583bfc88158099301762828": { + "balance": "1000000000000000000000" + }, + "a0228240f99e1de9cb32d82c0f2fa9a3d44b0bf3": { + "balance": "1600000000000000000000" + }, + "e154daeadb545838cbc6aa0c55751902f528682a": { + "balance": "4925000000000000000000" + }, + "8e92aba38e72a098170b92959246537a2e5556c0": { + "balance": "267400000000000000000" + }, + "d23d7affacdc3e9f3dae7afcb4006f58f8a44600": { + "balance": "3600000000000000000000" + }, + "00d78d89b35f472716eceafebf600527d3a1f969": { + "balance": "27750000000000000000000" + }, + "120f9de6e0af7ec02a07c609ca8447f157e6344c": { + "balance": "267400000000000000000" + }, + "e0352fdf819ba265f14c06a6315c4ac1fe131b2e": { + "balance": "1000000000000000000000" + }, + "8f47328ee03201c9d35ed2b5412b25decc859362": { + "balance": "2000000000000000000000" + }, + "453e359a3397944c5a275ab1a2f70a5e5a3f6989": { + "balance": "240000000000000000000" + }, + "9bf58efbea0784eb068adecfa0bb215084c73a35": { + "balance": "5800000000000000000000" + }, + "21bfe1b45cacde6274fd8608d9a178bf3eeb6edc": { + "balance": "2009400000000000000000" + }, + "d1d5b17ffe2d7bbb79cc7d7930bcb2e518fb1bbf": { + "balance": "3000000000000000000000" + }, + "20a29c5079e26b3f18318bb2e50e8e8b346e5be8": { + "balance": "499986000000000000000" + }, + "7d392852f3abd92ff4bb5bb26cb60874f2be6795": { + "balance": "1000070000000000000000" + }, + "55852943492970f8d629a15366cdda06a94f4513": { + "balance": "2000000000000000000000" + }, + "ab5dfc1ea21adc42cf8c3f6e361e243fd0da61e5": { + "balance": "300000000000000000000" + }, + "9d2bfc36106f038250c01801685785b16c86c60d": { + "balance": "380000000000000000000000" + }, + "6e60aee1a78f8eda8b424c73e353354ae67c3042": { + "balance": "3490300000000000000000" + }, + "7e29290038493559194e946d4e460b96fc38a156": { + "balance": "309072000000000000000" + }, + "6006e36d929bf45d8f16231b126a011ae283d925": { + "balance": "176000000000000000000" + }, + "d6d03572a45245dbd4368c4f82c95714bd2167e2": { + "balance": "1162200000000000000000" + }, + "d1432538e35b7664956ae495a32abdf041a7a21c": { + "balance": "19700000000000000000000" + }, + "2276264bec8526c0c0f270677abaf4f0e441e167": { + "balance": "1000000000000000000000" + }, + "c8814e34523e38e1f927a7dce8466a447a093603": { + "balance": "10000000000000000000000" + }, + "688a569e965524eb1d0ac3d3733eab909fb3d61e": { + "balance": "1320000000000000000000" + }, + "90dc09f717fc2a5b69fd60ba08ebf40bf4e8246c": { + "balance": "4000086000000000000000" + }, + "239a733e6b855ac592d663156186a8a174d2449e": { + "balance": "1637020000000000000000" + }, + "bcdfacb9d9023c3417182e9100e8ea1d373393a3": { + "balance": "59100000000000000000" + }, + "ba6440aeb3737b8ef0f1af9b0c15f4c214ffc7cf": { + "balance": "1000000000000000000000" + }, + "322e5c43b0f524389655a9b3ff24f2d4db3da10f": { + "balance": "4650000000000000000000" + }, + "be5a60689998639ad75bc105a371743eef0f7940": { + "balance": "501700000000000000000" + }, + "b727a9fc82e1cffc5c175fa1485a9befa2cdbdd1": { + "balance": "999000000000000000000" + }, + "a3883a24f7f166205f1a6a9949076c26a76e7178": { + "balance": "1820000000000000000000" + }, + "5e95fe5ffcf998f9f9ac0e9a81dab83ead77003d": { + "balance": "539766000000000000000" + }, + "e60955dc0bc156f6c41849f6bd776ba44b0ef0a1": { + "balance": "299982000000000000000" + }, + "af203e229d7e6d419df4378ea98715515f631485": { + "balance": "1970000000000000000000" + }, + "86499a1228ff2d7ee307759364506f8e8c8307a5": { + "balance": "1970000000000000000000" + }, + "1a04cec420ad432215246d77fe178d339ed0b595": { + "balance": "316000000000000000000" + }, + "cc2b5f448f3528d3fe41cc7d1fa9c0dc76f1b776": { + "balance": "60000000000000000000" + }, + "cb50587412822304ebcba07dab3a0f09fffee486": { + "balance": "1370000000000000000000" + }, + "4ae2a04d3909ef454e544ccfd614bfefa71089ae": { + "balance": "442800000000000000000" + }, + "c8a2c4e59e1c7fc54805580438aed3e44afdf00e": { + "balance": "44000000000000000000" + }, + "5792814f59a33a1843faa01baa089eb02ffb5cf1": { + "balance": "499986000000000000000" + }, + "a1f2854050f872658ed82e52b0ad7bbc1cb921f6": { + "balance": "2010918000000000000000" + }, + "92dca5e102b3b81b60f1a504634947c374a88ccb": { + "balance": "2000000000000000000000" + }, + "732fead60f7bfdd6a9dec48125e3735db1b6654f": { + "balance": "20000000000000000000" + }, + "6bf7b3c065f2c1e7c6eb092ba0d15066f393d1b8": { + "balance": "400000000000000000000" + }, + "cde36d81d128c59da145652193eec2bfd96586ef": { + "balance": "4000000000000000000000" + }, + "40eddb448d690ed72e05c225d34fc8350fa1e4c5": { + "balance": "7000000000000000000000" + }, + "454b61b344c0ef965179238155f277c3829d0b38": { + "balance": "2000000000000000000000" + }, + "ac3da526cfce88297302f34c49ca520dc271f9b2": { + "balance": "800000000000000000000" + }, + "c989eec307e8839b9d7237cfda08822962abe487": { + "balance": "400000000000000000000" + }, + "e99de258a4173ce9ac38ede26c0b3bea3c0973d5": { + "balance": "1656800000000000000000" + }, + "ff0cb06c42e3d88948e45bd7b0d4e291aefeea51": { + "balance": "1910000000000000000000" + }, + "0990e81cd785599ea236bd1966cf526302c35b9c": { + "balance": "1000000000000000000000" + }, + "6da0ed8f1d69339f059f2a0e02471cb44fb8c3bb": { + "balance": "935900000000000000000" + }, + "5d958a9bd189c2985f86c58a8c69a7a78806e8da": { + "balance": "10200000000000000000000" + }, + "98be696d51e390ff1c501b8a0f6331b628ddc5ad": { + "balance": "2000000000000000000000" + }, + "09d0b8cd077c69d9f32d9cca43b3c208a21ed48b": { + "balance": "150011000000000000000" + }, + "96e7c0c9d5bf10821bf140c558a145b7cac21397": { + "balance": "1056000000000000000000" + }, + "5b736eb18353629bde9676dadd165034ce5ecc68": { + "balance": "1970000000000000000000" + }, + "e5a365343cc4eb1e770368e1f1144a77b832d7e0": { + "balance": "20000000000000000000" + }, + "4cf5537b85842f89cfee359eae500fc449d2118f": { + "balance": "1000000000000000000000" + }, + "c71f1d75873f33dcb2dd4b3987a12d0791a5ce27": { + "balance": "1015200000000000000000" + }, + "9bf703b41c3624e15f4054962390bcba3052f0fd": { + "balance": "6055000000000000000000" + }, + "145e1de0147911ccd880875fbbea61f6a142d11d": { + "balance": "4000000000000000000000" + }, + "68419c6dd2d3ce6fcbb3c73e2fa079f06051bde6": { + "balance": "1970000000000000000000" + }, + "d8eb78503ec31a54a90136781ae109004c743257": { + "balance": "1000000000000000000000" + }, + "f25e4c70bc465632c89e5625a832a7722f6bffab": { + "balance": "4488000000000000000000" + }, + "7b4d2a38269069c18557770d591d24c5121f5e83": { + "balance": "700000000000000000000" + }, + "27d158ac3d3e1109ab6e570e90e85d3892cd7680": { + "balance": "100000000000000000000" + }, + "d3679a47df2d99a49b01c98d1c3e0c987ce1e158": { + "balance": "280000000000000000000" + }, + "095b949de3333a377d5019d893754a5e4656ff97": { + "balance": "340000000000000000000" + }, + "6b17598a8ef54f797ae515ccb6517d1859bf8011": { + "balance": "100000000000000000000" + }, + "3eaf0879b5b6db159b589f84578b6a74f6c10357": { + "balance": "7253657000000000000000" + }, + "40d45d9d7625d15156c932b771ca7b0527130958": { + "balance": "100000000000000000000000" + }, + "0392549a727f81655429cb928b529f25df4d1385": { + "balance": "26248000000000000000" + }, + "c5b009baeaf788a276bd35813ad65b400b849f3b": { + "balance": "1000000000000000000000" + }, + "6ed884459f809dfa1016e770edaf3e9fef46fa30": { + "balance": "3400170000000000000000" + }, + "439d2f2f5110a4d58b1757935015408740fec7f8": { + "balance": "3830421000000000000000" + }, + "dc46c13325cd8edf0230d068896486f007bf4ef1": { + "balance": "1337000000000000000000" + }, + "8c54c7f8b9896e75d7d5f5c760258699957142ad": { + "balance": "40000000000000000000" + }, + "61c8f1fa43bf846999ecf47b2b324dfb6b63fe3a": { + "balance": "800000000000000000000" + }, + "935069444a6a984de2084e46692ab99f671fc727": { + "balance": "9000000000000000000000" + }, + "fc49c1439a41d6b3cf26bb67e0365224e5e38f5f": { + "balance": "1000076000000000000000" + }, + "e1dfb5cc890ee8b2877e885d267c256187d019e6": { + "balance": "100000000000000000000" + }, + "ee7c3ded7c28f459c92fe13b4d95bafbab02367d": { + "balance": "700000000000000000000" + }, + "a5874d754635a762b381a5c4c792483af8f23d1d": { + "balance": "50000000000000000000" + }, + "cfbb32b7d024350e3321fa20c9a914035372ffc6": { + "balance": "401100000000000000000" + }, + "2bc429d618a66a4cf82dbb2d824e9356effa126a": { + "balance": "1999944000000000000000" + }, + "db244f97d9c44b158a40ed9606d9f7bd38913331": { + "balance": "102000000000000000000" + }, + "55e220876262c218af4f56784798c7e55da09e91": { + "balance": "133566000000000000000" + }, + "ca41ccac30172052d522cd2f2f957d248153409f": { + "balance": "1970000000000000000000" + }, + "b11fa7fb270abcdf5a2eab95aa30c4b53636efbf": { + "balance": "800000000000000000000" + }, + "0ffea06d7113fb6aec2869f4a9dfb09007facef4": { + "balance": "225416000000000000000" + }, + "646628a53c2c4193da88359ce718dadd92b7a48d": { + "balance": "200032000000000000000" + }, + "ca8409083e01b397cf12928a05b68455ce6201df": { + "balance": "1600000000000000000000" + }, + "dbbcbb79bf479a42ad71dbcab77b5adfaa872c58": { + "balance": "1730000000000000000000" + }, + "db7d4037081f6c65f9476b0687d97f1e044d0a1d": { + "balance": "660000000000000000000" + }, + "4be90d412129d5a4d0424361d6649d4e47a62316": { + "balance": "1015200000000000000000" + }, + "e3ab3ca9b870e3f548517306bba4de2591afafc2": { + "balance": "1200062000000000000000" + }, + "5c61ab79b408dd3229f662593705d72f1e147bb8": { + "balance": "22729000000000000000000" + }, + "4f177f9d56953ded71a5611f393322c30279895c": { + "balance": "246000000000000000000" + }, + "e6cb260b716d4c0ab726eeeb07c8707204e276ae": { + "balance": "1000000000000000000000" + }, + "44355253b27748e3f34fe9cae1fb718c8f249529": { + "balance": "200000000000000000000" + }, + "a309df54cabce70c95ec3033149cd6678a6fd4cf": { + "balance": "223600000000000000000" + }, + "ec4867d2175ab5b9469361595546554684cda460": { + "balance": "3000000000000000000000" + }, + "8d06e464245cad614939e0af0845e6d730e20374": { + "balance": "200359000000000000000" + }, + "9810e34a94db6ed156d0389a0e2b80f4fd6b0a8a": { + "balance": "2000000000000000000000" + }, + "dcfff3e8d23c2a34b56bd1b3bd45c79374432239": { + "balance": "5000000000000000000000" + }, + "7d7dd5ee614dbb6fbfbcd26305247a058c41faa1": { + "balance": "2000000000000000000000" + }, + "8a9eca9c5aba8e139f8003edf1163afb70aa3aa9": { + "balance": "660000000000000000000" + }, + "d942de4784f7a48716c0fd4b9d54a6e54c5f2f3e": { + "balance": "20000000000000000000000" + }, + "07dae622630d1136381933d2ad6b22b839d82102": { + "balance": "200000000000000000000" + }, + "abf12fa19e82f76c718f01bdca0003674523ef30": { + "balance": "2000000000000000000000" + }, + "411c831cc6f44f1965ec5757ab4e5b3ca4cffd1f": { + "balance": "425000000000000000000" + }, + "99129d5b3c0cde47ea0def4dfc070d1f4a599527": { + "balance": "2000000000000000000000" + }, + "c5cdcee0e85d117dabbf536a3f4069bf443f54e7": { + "balance": "1969606000000000000000" + }, + "f218bd848ee7f9d38bfdd1c4eb2ed2496ae4305f": { + "balance": "500000000000000000000" + }, + "fe549bbfe64740189892932538daaf46d2b61d4f": { + "balance": "40000000000000000000" + }, + "dc3f0e7672f71fe7525ba30b9755183a20b9166a": { + "balance": "9603617000000000000000" + }, + "0e83b850481ab44d49e0a229a2e464902c69539b": { + "balance": "100000000000000000000" + }, + "07ddd0422c86ef65bf0c7fc3452862b1228b08b8": { + "balance": "2065302000000000000000" + }, + "a68c313445c22d919ee46cc2d0cdff043a755825": { + "balance": "75189000000000000000" + }, + "a9e9dbce7a2cb03694799897bed7c54d155fdaa8": { + "balance": "197559000000000000000" + }, + "18fccf62d2c3395453b7587b9e26f5cff9eb7482": { + "balance": "1000000000000000000000" + }, + "ff41d9e1b4effe18d8b0d1f63fc4255fb4e06c3d": { + "balance": "1337000000000000000000" + }, + "8f69eafd0233cadb4059ab779c46edf2a0506e48": { + "balance": "1788210000000000000000" + }, + "9aa48c66e4fb4ad099934e32022e827427f277ba": { + "balance": "10000000000000000000000" + }, + "f46980e3a4a9d29a6a6e90604537a3114bcb2897": { + "balance": "500000000000000000000" + }, + "801732a481c380e57ed62d6c29de998af3fa3b13": { + "balance": "100000000000000000000" + }, + "0cd6a141918d126b106d9f2ebf69e102de4d3277": { + "balance": "20000000000000000000" + }, + "17589a6c006a54cad70103123aae0a82135fdeb4": { + "balance": "4000000000000000000000" + }, + "8725e8c753b3acbfdca55f3c62dfe1a59454968a": { + "balance": "1000090000000000000000" + }, + "d20dcb0b78682b94bc3000281448d557a20bfc83": { + "balance": "895000000000000000000" + }, + "e84f8076a0f2969ecd333eef8de41042986291f2": { + "balance": "432000000000000000000" + }, + "b3145b74506d1a8d047cdcdc55392a7b5350799a": { + "balance": "129314663000000000000000" + }, + "0d9a825ff2bcd397cbad5b711d9dcc95f1cc112d": { + "balance": "12800000000000000000000" + }, + "0ca670eb2c8b96cba379217f5929c2b892f39ef6": { + "balance": "2000000000000000000000" + }, + "25cfc4e25c35c13b69f7e77dbfb08baf58756b8d": { + "balance": "40000000000000000000000" + }, + "182db85293f606e88988c3704cb3f0c0bbbfca5a": { + "balance": "133700000000000000000" + }, + "bd73c3cbc26a175062ea0320dd84b253bce64358": { + "balance": "394000000000000000000" + }, + "2680713d40808e2a50ed013150a2a694b96a7f1d": { + "balance": "1790000000000000000000" + }, + "51e32f14f4ca5e287cdac057a7795ea9e0439953": { + "balance": "500000000000000000000" + }, + "b1e9c5f1d21e61757a6b2ee75913fc5a1a4101c3": { + "balance": "2000000000000000000000" + }, + "d4c4d1a7c3c74984f6857b2f5f07e8face68056d": { + "balance": "2000000000000000000000" + }, + "4651dc420e08c3293b27d2497890eb50223ae2f4": { + "balance": "20000000000000000000000" + }, + "c74a3995f807de1db01a2eb9c62e97d0548f696f": { + "balance": "1000000000000000000000" + }, + "0505a08e22a109015a22f685305354662a5531d5": { + "balance": "2600000000000000000000" + }, + "39c773367c8825d3596c686f42bf0d14319e3f84": { + "balance": "133700000000000000000" + }, + "0f929cf895db017af79f3ead2216b1bd69c37dc7": { + "balance": "2000000000000000000000" + }, + "bdd3254e1b3a6dc6cc2c697d45711aca21d516b2": { + "balance": "2000000000000000000000" + }, + "ae5d221afcd3d29355f508eadfca408ce33ca903": { + "balance": "100000000000000000000000" + }, + "916cf17d71412805f4afc3444a0b8dd1d9339d16": { + "balance": "14300000000000000000" + }, + "4319263f75402c0b5325f263be4a5080651087f0": { + "balance": "983086000000000000000" + }, + "0f1c249cd962b00fd114a9349f6a6cc778d76c4d": { + "balance": "2000000000000000000000" + }, + "54febcce20fe7a9098a755bd90988602a48c089e": { + "balance": "640000000000000000000" + }, + "2c1800f35fa02d3eb6ff5b25285f5e4add13b38d": { + "balance": "906400000000000000000" + }, + "72b904440e90e720d6ac1c2ad79c321dcc1c1a86": { + "balance": "1550000000000000000000" + }, + "b0aa00950c0e81fa3210173e729aaf163a27cd71": { + "balance": "40000000000000000000000" + }, + "663604b0503046e624cd26a8b6fb4742dce02a6f": { + "balance": "65400000000000000000" + }, + "3c98594bf68b57351e8814ae9e6dfd2d254aa06f": { + "balance": "300000000000000000000" + }, + "9c45202a25f6ad0011f115a5a72204f2f2198866": { + "balance": "5014000000000000000000" + }, + "b02d062873334545cea29218e4057760590f7423": { + "balance": "3186000000000000000000" + }, + "7bddb2ee98de19ee4c91f661ee8e67a91d054b97": { + "balance": "1000000000000000000000" + }, + "9cf2928beef09a40f9bfc953be06a251116182fb": { + "balance": "6000000000000000000000" + }, + "51b4758e9e1450e7af4268c3c7b1e7bd6f5c7550": { + "balance": "1000000000000000000000" + }, + "eb570dba975227b1c42d6e8dea2c56c9ad960670": { + "balance": "2000000000000000000000" + }, + "970d8b8a0016d143054f149fb3b8e550dc0797c7": { + "balance": "1000000000000000000000" + }, + "c7b39b060451000ca1049ba154bcfa00ff8af262": { + "balance": "100000000000000000000000" + }, + "945e18769d7ee727c7013f92de24d117967ff317": { + "balance": "2000000000000000000000" + }, + "d18eb9e1d285dabe93e5d4bae76beefe43b521e8": { + "balance": "668500000000000000000" + }, + "c618521321abaf5b26513a4a9528086f220adc6f": { + "balance": "27000000000000000000" + }, + "dd65f6e17163b5d203641f51cc7b24b00f02c8fb": { + "balance": "200000000000000000000" + }, + "131faed12561bb7aee04e5185af802b1c3438d9b": { + "balance": "219000000000000000000" + }, + "1ced6715f862b1ff86058201fcce5082b36e62b2": { + "balance": "6684522000000000000000" + }, + "a0ff5b4cf016027e8323497d4428d3e5a83b8795": { + "balance": "6596500000000000000000" + }, + "02e816afc1b5c0f39852131959d946eb3b07b5ad": { + "balance": "1000000000000000000000" + }, + "153cf2842cb9de876c276fa64767d1a8ecf573bb": { + "balance": "2000000000000000000000" + }, + "3bc6e3ee7a56ce8f14a37532590f63716b9966e8": { + "balance": "2000000000000000000000" + }, + "f6d25d3f3d846d239f525fa8cac97bc43578dbac": { + "balance": "896000000000000000000" + }, + "2066774d822793ff25f1760909479cf62491bf88": { + "balance": "55160000000000000000000" + }, + "46779a5656ff00d73eac3ad0c38b6c853094fb40": { + "balance": "230752000000000000000" + }, + "22eed327f8eb1d1338a3cb7b0f8a4baa5907cd95": { + "balance": "23445000000000000000" + }, + "ff88ebacc41b3687f39e4b59e159599b80cba33f": { + "balance": "400000000000000000000" + }, + "2874f3e2985d5f7b406627e17baa772b01abcc9e": { + "balance": "6014000000000000000000" + }, + "eb10458daca79e4a6b24b29a8a8ada711b7f2eb6": { + "balance": "3998000000000000000000" + }, + "541060fc58c750c40512f83369c0a63340c122b6": { + "balance": "1970000000000000000000" + }, + "fd2757cc3551a095878d97875615fe0c6a32aa8a": { + "balance": "598200000000000000000" + }, + "be659d85e7c34f8833ea7f488de1fbb5d4149bef": { + "balance": "9072500000000000000000" + }, + "e149b5726caf6d5eb5bf2acc41d4e2dc328de182": { + "balance": "1940000000000000000000" + }, + "2fe0cc424b53a31f0916be08ec81c50bf8eab0c1": { + "balance": "600000000000000000000" + }, + "e3712701619ca7623c55db3a0ad30e867db0168b": { + "balance": "20000000000000000000" + }, + "f8ca336c8e91bd20e314c20b2dd4608b9c8b9459": { + "balance": "846000000000000000000" + }, + "68acdaa9fb17d3c309911a77b05f5391fa034ee9": { + "balance": "8950000000000000000000" + }, + "e77d7deab296c8b4fa07ca3be184163d5a6d606c": { + "balance": "92538000000000000000" + }, + "e6b9545f7ed086e552924639f9a9edbbd5540b3e": { + "balance": "3760000000000000000000" + }, + "2866b81decb02ee70ae250cee5cdc77b59d7b679": { + "balance": "2000000000000000000000" + }, + "60e3cc43bcdb026aad759c7066f555bbf2ac66f5": { + "balance": "2000000000000000000000" + }, + "fcbd85feea6a754fcf3449449e37ff9784f7773c": { + "balance": "3086000000000000000000" + }, + "38a744efa6d5c2137defef8ef9187b649eee1c78": { + "balance": "4000000000000000000000" + }, + "9d7655e9f3e5ba5d6e87e412aebe9ee0d49247ee": { + "balance": "2620100000000000000000" + }, + "2020b81ae53926ace9f7d7415a050c031d585f20": { + "balance": "341200000000000000000" + }, + "4244f1331158b9ce26bbe0b9236b9203ca351434": { + "balance": "10000000000000000000000" + }, + "99c236141daec837ece04fdaee1d90cf8bbdc104": { + "balance": "2184000000000000000000" + }, + "943d37864a4a537d35c8d99723cd6406ce2562e6": { + "balance": "2000000000000000000000" + }, + "d79483f6a8444f2549d611afe02c432d15e11051": { + "balance": "20000000000000000000" + }, + "9fd64373f2fbcd9c0faca60547cad62e26d9851f": { + "balance": "1000000000000000000000" + }, + "b89c036ed7c492879921be41e10ca1698198a74c": { + "balance": "1820000000000000000000" + }, + "7462c89caa9d8d7891b2545def216f7464d5bb21": { + "balance": "109162000000000000000" + }, + "bb0366a7cfbd3445a70db7fe5ae34885754fd468": { + "balance": "6160000000000000000000" + }, + "6c52cf0895bb35e656161e4dc46ae0e96dd3e62c": { + "balance": "4000086000000000000000" + }, + "b9cf71b226583e3a921103a5316f855a65779d1b": { + "balance": "24000000000000000000000" + }, + "016b60bb6d67928c29fd0313c666da8f1698d9c5": { + "balance": "2000000000000000000000" + }, + "9454b3a8bff9709fd0e190877e6cb6c89974dbd6": { + "balance": "2674000000000000000000" + }, + "84aac7fa197ff85c30e03b7a5382b957f41f3afb": { + "balance": "157600000000000000000" + }, + "db6e560c9bc620d4bea3a94d47f7880bf47f2d5f": { + "balance": "89500000000000000000" + }, + "eefd05b0e3c417d55b3343060486cdd5e92aa7a6": { + "balance": "1430000000000000000000" + }, + "3a59a08246a8206f8d58f70bb1f0d35c5bcc71bd": { + "balance": "185000000000000000000" + }, + "9bfff50db36a785555f07652a153b0c42b1b8b76": { + "balance": "2000000000000000000000" + }, + "d44f5edf2bcf2433f211dadd0cc450db1b008e14": { + "balance": "267400000000000000000" + }, + "2378fd4382511e968ed192106737d324f454b535": { + "balance": "1000000000000000000000" + }, + "c94089553ae4c22ca09fbc98f57075cf2ec59504": { + "balance": "4000000000000000000000" + }, + "08ef3fa4c43ccdc57b22a4b9b2331a82e53818f2": { + "balance": "4000000000000000000000" + }, + "e48e65125421880d42bdf1018ab9778d96928f3f": { + "balance": "4200000000000000000000" + }, + "67518e5d02b205180f0463a32004471f753c523e": { + "balance": "1984289000000000000000" + }, + "0da7401262384e2e8b4b26dd154799b55145efa0": { + "balance": "300000000000000000000" + }, + "0b6920a64b363b8d5d90802494cf564b547c430d": { + "balance": "1200000000000000000000" + }, + "a5ab4bd3588f46cb272e56e93deed386ba8b753d": { + "balance": "1332989000000000000000" + }, + "1788da9b57fd05edc4ff99e7fef301519c8a0a1e": { + "balance": "2000000000000000000000" + }, + "17b2d6cf65c6f4a347ddc6572655354d8a412b29": { + "balance": "2000000000000000000000" + }, + "d0319139fbab2e8e2accc1d924d4b11df6696c5a": { + "balance": "200000000000000000000" + }, + "4c377bb03ab52c4cb79befa1dd114982924c4ae9": { + "balance": "1827814000000000000000" + }, + "fb949c647fdcfd2514c7d58e31f28a532d8c5833": { + "balance": "20000000000000000000000" + }, + "70e5e9da735ff077249dcb9aaf3db2a48d9498c0": { + "balance": "1000000000000000000000" + }, + "fe6f5f42b6193b1ad16206e4afb5239d4d7db45e": { + "balance": "1730000000000000000000" + }, + "bda4be317e7e4bed84c0495eee32d607ec38ca52": { + "balance": "2309457000000000000000" + }, + "5910106debd291a1cd80b0fbbb8d8d9e93a7cc1e": { + "balance": "2000000000000000000000" + }, + "ba42f9aace4c184504abf5425762aca26f71fbdc": { + "balance": "37400000000000000000" + }, + "beb4fd315559436045dcb99d49dcec03f40c42dc": { + "balance": "2000000000000000000000" + }, + "452b64db8ef7d6df87c788639c2290be8482d575": { + "balance": "8000000000000000000000" + }, + "66e09427c1e63deed7e12b8c55a6a19320ef4b6a": { + "balance": "170000000000000000000" + }, + "faad905d847c7b23418aeecbe3addb8dd3f8924a": { + "balance": "1970000000000000000000" + }, + "a29319e81069e5d60df00f3de5adee3505ecd5fb": { + "balance": "2000000000000000000000" + }, + "cf348f2fe47b7e413c077a7baf3a75fbf8428692": { + "balance": "2000000000000000000000" + }, + "e1e8c50b80a352b240ce7342bbfdf5690cc8cb14": { + "balance": "394000000000000000000" + }, + "131c792c197d18bd045d7024937c1f84b60f4438": { + "balance": "4000000000000000000000" + }, + "e49af4f34adaa2330b0e49dc74ec18ab2f92f827": { + "balance": "2000000000000000000000" + }, + "f2e99f5cbb836b7ad36247571a302cbe4b481c69": { + "balance": "1970000000000000000000" + }, + "c93fbde8d46d2bcc0fa9b33bd8ba7f8042125565": { + "balance": "1400000000000000000000" + }, + "038779ca2dbe663e63db3fe75683ea0ec62e2383": { + "balance": "1670000000000000000000" + }, + "a33cb450f95bb46e25afb50fe05feee6fb8cc8ea": { + "balance": "776000000000000000000" + }, + "40ab66fe213ea56c3afb12c75be33f8e32fd085d": { + "balance": "4000000000000000000000" + }, + "6403d062549690c8e8b63eae41d6c109476e2588": { + "balance": "2000000000000000000000" + }, + "bfb0ea02feb61dec9e22a5070959330299c43072": { + "balance": "20000000000000000000000" + }, + "99c475bf02e8b9214ada5fad02fdfd15ba365c0c": { + "balance": "591000000000000000000" + }, + "904966cc2213b5b8cb5bd6089ef9cddbef7edfcc": { + "balance": "2000000000000000000000" + }, + "767a03655af360841e810d83f5e61fb40f4cd113": { + "balance": "985000000000000000000" + }, + "ab209fdca979d0a647010af9a8b52fc7d20d8cd1": { + "balance": "9129000000000000000000" + }, + "6294eae6e420a3d5600a39c4141f838ff8e7cc48": { + "balance": "2955000000000000000000" + }, + "9777cc61cf756be3b3c20cd4491c69d275e7a120": { + "balance": "10000000000000000000000" + }, + "bcbf6ba166e2340db052ea23d28029b0de6aa380": { + "balance": "3880000000000000000000" + }, + "9f10f2a0463b65ae30b070b3df18cf46f51e89bd": { + "balance": "1910000000000000000000" + }, + "8d9952d0bb4ebfa0efd01a3aa9e8e87f0525742e": { + "balance": "3460000000000000000000" + }, + "4f23b6b817ffa5c664acdad79bb7b726d30af0f9": { + "balance": "1760000000000000000000" + }, + "b4c20040ccd9a1a3283da4d4a2f365820843d7e2": { + "balance": "1000000000000000000000" + }, + "7f49e7a4269882bd8722d4a6f566347629624079": { + "balance": "2000000000000000000000" + }, + "33629bd52f0e107bc071176c64df108f64777d49": { + "balance": "33425000000000000000" + }, + "6a7b2e0d88867ff15d207c222bebf94fa6ce8397": { + "balance": "60000000000000000000000" + }, + "b7ce684b09abda53389a875369f71958aeac3bdd": { + "balance": "2000000000000000000000" + }, + "ffbc3da0381ec339c1c049eb1ed9ee34fdcea6ca": { + "balance": "4000000000000000000000" + }, + "849ab80790b28ff1ffd6ba394efc7463105c36f7": { + "balance": "34600000000000000000" + }, + "b0b36af9aeeedf97b6b02280f114f13984ea3260": { + "balance": "985000000000000000000" + }, + "4d57e716876c0c95ef5eaebd35c8f41b069b6bfe": { + "balance": "2000000000000000000000" + }, + "2d2b032359b363964fc11a518263bfd05431e867": { + "balance": "149600000000000000000" + }, + "2ccc1f1cb5f4a8002e186b20885d9dbc030c0894": { + "balance": "2000000000000000000000" + }, + "016c85e1613b900fa357b8283b120e65aefcdd08": { + "balance": "799954000000000000000" + }, + "710b0274d712c77e08a5707d6f3e70c0ce3d92cf": { + "balance": "6400000000000000000000" + }, + "3cd3a6e93579c56d494171fc533e7a90e6f59464": { + "balance": "2000000000000000000000" + }, + "fe0e30e214290d743dd30eb082f1f0a5225ade61": { + "balance": "200000000000000000000" + }, + "d0718520eae0a4d62d70de1be0ca431c5eea2482": { + "balance": "2000000000000000000000" + }, + "af7f79cb415a1fb8dbbd094607ee8d41fb7c5a3b": { + "balance": "10000000000000000000000" + }, + "b7d252ee9402b0eef144295f0e69f0db586c0871": { + "balance": "660000000000000000000" + }, + "c3b928a76fad6578f04f0555e63952cd21d1520a": { + "balance": "2000000000000000000000" + }, + "a7a517d7ad35820b09d497fa7e5540cde9495853": { + "balance": "2000000000000000000000" + }, + "e6e886317b6a66a5b4f81bf164c538c264351765": { + "balance": "2000000000000000000000" + }, + "0770b43dbae4b1f35a927b4fa8124d3866caf97b": { + "balance": "1016390000000000000000" + }, + "52b4257cf41b6e28878d50d57b99914ffa89873a": { + "balance": "3930150000000000000000" + }, + "e08bc29c2b48b169ff2bdc16714c586e6cb85ccf": { + "balance": "20000000000000000000" + }, + "2372c4c1c9939f7aaf6cfac04090f00474840a09": { + "balance": "10000000000000000000000" + }, + "ab6b65eab8dfc917ec0251b9db0ecfa0fa032849": { + "balance": "500000000000000000000" + }, + "582e7cc46f1d7b4e6e9d95868bfd370573178f4c": { + "balance": "2000000000000000000000" + }, + "f167f5868dcf4233a7830609682caf2df4b1b807": { + "balance": "2396150000000000000000" + }, + "ec82f50d06475f684df1b392e00da341aa145444": { + "balance": "2000000000000000000000" + }, + "0968ee5a378f8cadb3bafdbed1d19aaacf936711": { + "balance": "1000000000000000000000" + }, + "a86613e6c4a4c9c55f5c10bcda32175dcbb4af60": { + "balance": "10696140000000000000000" + }, + "a5cd123992194b34c4781314303b03c54948f4b9": { + "balance": "2010462000000000000000" + }, + "52f058d46147e9006d29bf2c09304ad1cddd6e15": { + "balance": "1500000000000000000000" + }, + "160226efe7b53a8af462d117a0108089bdecc2d1": { + "balance": "200550000000000000000" + }, + "256292a191bdda34c4da6b6bd69147bf75e2a9ab": { + "balance": "14051000000000000000" + }, + "1b8aa0160cd79f005f88510a714913d70ad3be33": { + "balance": "201760000000000000000" + }, + "d4b2ff3bae1993ffea4d3b180231da439f7502a2": { + "balance": "2000000000000000000000" + }, + "e408aa99835307eea4a6c5eb801fe694117f707d": { + "balance": "500000000000000000000" + }, + "e60a55f2df996dc3aedb696c08dde039b2641de8": { + "balance": "2000000000000000000000" + }, + "73df3c3e7955f4f2d859831be38000b1076b3884": { + "balance": "1970000000000000000000" + }, + "6228ade95e8bb17d1ae23bfb0518414d497e0eb8": { + "balance": "400000000000000000000" + }, + "0f46c81db780c1674ac73d314f06539ee56ebc83": { + "balance": "9850000000000000000000" + }, + "762d6f30dab99135e4eca51d5243d6c8621102d5": { + "balance": "282000000000000000000" + }, + "4ba0d9e89601772b496847a2bb4340186787d265": { + "balance": "1000000000000000000000" + }, + "ca747576446a4c8f30b08340fee198de63ec92cf": { + "balance": "7020000000000000000000" + }, + "99c31fe748583787cdd3e525b281b218961739e3": { + "balance": "1015200000000000000000" + }, + "1210f80bdb826c175462ab0716e69e46c24ad076": { + "balance": "100000000000000000000" + }, + "3f75ae61cc1d8042653b5baec4443e051c5e7abd": { + "balance": "95500000000000000000" + }, + "5c4892907a0720df6fd3413e63ff767d6b398023": { + "balance": "13189467000000000000000" + }, + "17f14632a7e2820be6e8f6df823558283dadab2d": { + "balance": "2000000000000000000000" + }, + "1dc7f7dad85df53f1271152403f4e1e4fdb3afa0": { + "balance": "200000000000000000000" + }, + "5a30feac37ac9f72d7b4af0f2bc73952c74fd5c3": { + "balance": "2000000000000000000000" + }, + "136d4b662bbd1080cfe4445b0fa213864435b7f1": { + "balance": "4000000000000000000000" + }, + "c1ec81dd123d4b7c2dd9b4d438a7072c11dc874c": { + "balance": "2000000000000000000000" + }, + "09f9575be57d004793c7a4eb84b71587f97cbb6a": { + "balance": "200000000000000000000" + }, + "2c4b470307a059854055d91ec3794d80b53d0f4a": { + "balance": "20000000000000000000000" + }, + "6af6c7ee99df271ba15bf384c0b764adcb4da182": { + "balance": "999972000000000000000" + }, + "0dae3ee5b915b36487f9161f19846d101433318a": { + "balance": "1910000000000000000000" + }, + "0dcf9d8c9804459f647c14138ed50fad563b4154": { + "balance": "173000000000000000000" + }, + "bfa8c858df102cb12421008b0a31c4c7190ad560": { + "balance": "200000000000000000000" + }, + "c2fd0bf7c725ef3e047e5ae1c29fe18f12a7299c": { + "balance": "1337000000000000000000" + }, + "d70a612bd6dda9eab0dddcff4aaf4122d38feae4": { + "balance": "540000000000000000000" + }, + "e07137ae0d116d033533c4eab496f8a9fb09569c": { + "balance": "1400000000000000000000" + }, + "7f49f20726471ac1c7a83ef106e9775ceb662566": { + "balance": "5910000000000000000000" + }, + "1e706655e284dcf0bb37fe075d613a18dc12ff4a": { + "balance": "4376760000000000000000" + }, + "03af7ad9d5223cf7c8c13f20df67ebe5ffc5bb41": { + "balance": "200000000000000000000" + }, + "228242f8336eecd8242e1f000f41937e71dffbbf": { + "balance": "5000000000000000000000" + }, + "e8ed51bbb3ace69e06024b33f86844c47348db9e": { + "balance": "165170600000000000000000" + }, + "3b566a8afad19682dc2ce8679a3ce444a5b0fd4f": { + "balance": "2000000000000000000000" + }, + "dc738fb217cead2f69594c08170de1af10c419e3": { + "balance": "100000000000000000000000" + }, + "13032446e7d610aa00ec8c56c9b574d36ca1c016": { + "balance": "2000000000000000000000" + }, + "6ca6a132ce1cd288bee30ec7cfeffb85c1f50a54": { + "balance": "2000000000000000000000" + }, + "b85f26dd0e72d9c29ebaf697a8af77472c2b58b5": { + "balance": "11900000000000000000000" + }, + "055bd02caf19d6202bbcdc836d187bd1c01cf261": { + "balance": "100000000000000000000" + }, + "3c322e611fdb820d47c6f8fc64b6fad74ca95f5e": { + "balance": "242514000000000000000" + }, + "8daddf52efbd74da95b969a5476f4fbbb563bfd2": { + "balance": "835000000000000000000" + }, + "c63ac417992e9f9b60386ed953e6d7dff2b090e8": { + "balance": "4000086000000000000000" + }, + "27f03cf1abc5e1b51dbc444b289e542c9ddfb0e6": { + "balance": "5000000000000000000000" + }, + "d8f4bae6f84d910d6d7d5ac914b1e68372f94135": { + "balance": "100000000000000000000" + }, + "9f83a293c324d4106c18faa8888f64d299054ca0": { + "balance": "200000000000000000000" + }, + "39ee4fe00fbced647068d4f57c01cb22a80bccd1": { + "balance": "6000000000000000000000" + }, + "404100db4c5d0eec557823b58343758bcc2c8083": { + "balance": "20000000000000000000" + }, + "02751dc68cb5bd737027abf7ddb77390cd77c16b": { + "balance": "20000000000000000000" + }, + "d10302faa1929a326904d376bf0b8dc93ad04c4c": { + "balance": "1790000000000000000000" + }, + "cc419fd9912b85135659e77a93bc3df182d45115": { + "balance": "10000000000000000000000" + }, + "10097198b4e7ee91ff82cc2f3bd95fed73c540c0": { + "balance": "2000000000000000000000" + }, + "7e24d9e22ce1da3ce19f219ccee523376873f367": { + "balance": "5900150000000000000000" + }, + "2e4ee1ae996aa0a1d92428d06652a6bea6d2d15d": { + "balance": "2000000000000000000000" + }, + "91a4149a2c7b1b3a67ea28aff34725e0bf8d7524": { + "balance": "1940000000000000000000" + }, + "ead65262ed5d122df2b2751410f98c32d1238f51": { + "balance": "101680000000000000000" + }, + "e20954d0f4108c82d4dcb2148d26bbd924f6dd24": { + "balance": "10000000000000000000000" + }, + "ebb7d2e11bc6b58f0a8d45c2f6de3010570ac891": { + "balance": "26740000000000000000" + }, + "ef115252b1b845cd857f002d630f1b6fa37a4e50": { + "balance": "1970000000000000000000" + }, + "01a818135a414210c37c62b625aca1a54611ac36": { + "balance": "260000000000000000000" + }, + "ea1ea0c599afb9cd36caacbbb52b5bbb97597377": { + "balance": "1069600000000000000000" + }, + "7a7a4f807357a4bbe68e1aa806393210c411ccb3": { + "balance": "30000000000000000000000" + }, + "6d40ca27826d97731b3e86effcd7b92a4161fe89": { + "balance": "2000000000000000000000" + }, + "8431277d7bdd10457dc017408c8dbbbd414a8df3": { + "balance": "39400000000000000000" + }, + "69b81d5981141ec7a7141060dfcf8f3599ffc63e": { + "balance": "5000000000000000000000" + }, + "47688410ff25d654d72eb2bc06e4ad24f833b094": { + "balance": "160440000000000000000" + }, + "6c101205b323d77544d6dc52af37aca3cec6f7f1": { + "balance": "10000000000000000000000" + }, + "fb685c15e439965ef626bf0d834cd1a89f2b5695": { + "balance": "3940000000000000000000" + }, + "673706b1b0e4dc7a949a7a796258a5b83bb5aa83": { + "balance": "16100000000000000000000" + }, + "ecdaf93229b45ee672f65db506fb5eca00f7fce6": { + "balance": "1605009000000000000000" + }, + "ec6904bae1f69790591709b0609783733f2573e3": { + "balance": "500000000000000000000" + }, + "812ea7a3b2c86eed32ff4f2c73514cc63bacfbce": { + "balance": "1000000000000000000000" + }, + "196c02210a450ab0b36370655f717aa87bd1c004": { + "balance": "259456000000000000000" + }, + "d96ac2507409c7a383ab2eee1822a5d738b36b56": { + "balance": "200000000000000000000" + }, + "ae2f9c19ac76136594432393b0471d08902164d3": { + "balance": "698600000000000000000" + }, + "9d32962ea99700d93228e9dbdad2cc37bb99f07e": { + "balance": "3327560000000000000000" + }, + "17e584e810e567702c61d55d434b34cdb5ee30f6": { + "balance": "5000000000000000000000" + }, + "a3a93ef9dbea2636263d06d8492f6a41de907c22": { + "balance": "60000000000000000000" + }, + "2b5016e2457387956562587115aa8759d8695fdf": { + "balance": "200000000000000000000000" + }, + "140129eaa766b5a29f5b3af2574e4409f8f6d3f1": { + "balance": "6400000000000000000000" + }, + "7025965d2b88da197d4459be3dc9386344cc1f31": { + "balance": "2005500000000000000000" + }, + "388bdcdae794fc44082e667501344118ea96cd96": { + "balance": "1670000000000000000000" + }, + "eee9d0526eda01e43116a395322dda8970578f39": { + "balance": "9999980000000000000000" + }, + "6ec89b39f9f5276a553e8da30e6ec17aa47eefc7": { + "balance": "447500000000000000000" + }, + "7e236666b2d06e63ea4e2ab84357e2dfc977e50e": { + "balance": "999972000000000000000" + }, + "68df947c495bebaeb8e889b3f953d533874bf106": { + "balance": "546000000000000000000" + }, + "d40ed66ab3ceff24ca05ecd471efb492c15f5ffa": { + "balance": "500000000000000000000" + }, + "f0c70d0d6dab7663aa9ed9ceea567ee2c6b02765": { + "balance": "2089349000000000000000" + }, + "b589676d15a04448344230d4ff27c95edf122c49": { + "balance": "1000000000000000000000" + }, + "a0347f0a98776390165c166d32963bf74dcd0a2f": { + "balance": "1000000000000000000000" + }, + "d47d8685faee147c520fd986709175bf2f886bef": { + "balance": "2000000000000000000000" + }, + "a1dcd0e5b05a977c9623e5ae2f59b9ada2f33e31": { + "balance": "100000000000000000000" + }, + "4979194ec9e97db9bee8343b7c77d9d7f3f1dc9f": { + "balance": "20000000000000000000" + }, + "7cd20eccb518b60cab095b720f571570caaa447e": { + "balance": "500000000000000000000" + }, + "2ff830cf55fb00d5a0e03514fecd44314bd6d9f1": { + "balance": "10000000000000000000000" + }, + "0bb25ca7d188e71e4d693d7b170717d6f8f0a70a": { + "balance": "336870000000000000000" + }, + "e9a2b4914e8553bf0d7c00ca532369b879f931bf": { + "balance": "2000000000000000000000" + }, + "720e6b22bf430966fa32b6acb9a506eebf662c61": { + "balance": "152000000000000000000" + }, + "7ade5d66b944bb860c0efdc86276d58f4653f711": { + "balance": "2000000000000000000000" + }, + "2eaff9f8f8113064d3957ac6d6e11eee42c8195d": { + "balance": "1970000000000000000000" + }, + "0c8fd7775e54a6d9c9a3bf890e761f6577693ff0": { + "balance": "9850000000000000000000" + }, + "290a56d41f6e9efbdcea0342e0b7929a8cdfcb05": { + "balance": "344000000000000000000" + }, + "d73ed2d985b5f21b55b274643bc6da031d8edd8d": { + "balance": "49250000000000000000000" + }, + "80156d10efa8b230c99410630d37e269d4093cea": { + "balance": "2000000000000000000000" + }, + "0989c200440b878991b69d6095dfe69e33a22e70": { + "balance": "1910000000000000000000" + }, + "ec8014efc7cbe5b0ce50f3562cf4e67f8593cd32": { + "balance": "17300000000000000000" + }, + "de612d0724e84ea4a7feaa3d2142bd5ee82d3201": { + "balance": "20000000000000000000" + }, + "0f832a93df9d7f74cd0fb8546b7198bf5377d925": { + "balance": "143000000000000000000" + }, + "aa2c670096d3f939305325427eb955a8a60db3c5": { + "balance": "2003010000000000000000" + }, + "25287b815f5c82380a73b0b13fbaf982be24c4d3": { + "balance": "40000000000000000000" + }, + "e75c3b38a58a3f33d55690a5a59766be185e0284": { + "balance": "500000000000000000000" + }, + "1940dc9364a852165f47414e27f5002445a4f143": { + "balance": "10850000000000000000000" + }, + "e5b826196c0e1bc1119b021cf6d259a610c99670": { + "balance": "200000000000000000000" + }, + "82a15cef1d6c8260eaf159ea3f0180d8677dce1c": { + "balance": "2000000000000000000000" + }, + "da06044e293c652c467fe74146bf185b21338a1c": { + "balance": "1000000000000000000000" + }, + "f815c10a032d13c34b8976fa6e3bd2c9131a8ba9": { + "balance": "1337000000000000000000" + }, + "cd95fa423d6fc120274aacde19f4eeb766f10420": { + "balance": "200000000000000000000" + }, + "e3a4f83c39f85af9c8b1b312bfe5fc3423afa634": { + "balance": "28650000000000000000" + }, + "768ce0daa029b7ded022e5fc574d11cde3ecb517": { + "balance": "322000000000000000000" + }, + "e3ec18a74ed43855409a26ade7830de8e42685ef": { + "balance": "19700000000000000000" + }, + "b2bdbedf95908476d7148a370cc693743628057f": { + "balance": "4000000000000000000000" + }, + "bbb8ffe43f98de8eae184623ae5264e424d0b8d7": { + "balance": "107600000000000000000" + }, + "090cebef292c3eb081a05fd8aaf7d39bf07b89d4": { + "balance": "4000000000000000000000" + }, + "dd2a233adede66fe1126d6c16823b62a021feddb": { + "balance": "2000000000000000000000" + }, + "d8cd64e0284eec53aa4639afc4750810b97fab56": { + "balance": "20000000000000000000" + }, + "e5953fea497104ef9ad2d4e5841c271f073519c2": { + "balance": "704000000000000000000" + }, + "967d4142af770515dd7062af93498dbfdff29f20": { + "balance": "20200000000000000000" + }, + "fd191a35157d781373fb411bf9f25290047c5eef": { + "balance": "1000000000000000000000" + }, + "8967d7b9bdb7b4aed22e65a15dc803cb7a213f10": { + "balance": "400000000000000000000" + }, + "51e43fe0d25c782860af81ea89dd793c13f0cbb1": { + "balance": "60000000000000000000" + }, + "a38476691d34942eea6b2f76889223047db4617a": { + "balance": "2000000000000000000000" + }, + "1321ccf29739b974e5a516f18f3a843671e39642": { + "balance": "4000000000000000000000" + }, + "4d71a6eb3d7f327e1834278e280b039eddd31c2f": { + "balance": "6000000000000000000000" + }, + "dc2d15a69f6bb33b246aef40450751c2f6756ad2": { + "balance": "1996000000000000000000" + }, + "ec89f2b678a1a15b9134ec5eb70c6a62071fbaf9": { + "balance": "200000000000000000000" + }, + "27bf943c1633fe32f8bcccdb6302b407a5724e44": { + "balance": "940229000000000000000" + }, + "d0a6c6f9e9c4b383d716b31de78d56414de8fa91": { + "balance": "300000000000000000000" + }, + "7b6175ec9befc738249535ddde34688cd36edf25": { + "balance": "10000000000000000000000" + }, + "41ce79950935cff55bf78e4ccec2fe631785db95": { + "balance": "2000000000000000000000" + }, + "5598b3a79a48f32b1f5fc915b87b645d805d1afe": { + "balance": "500000000000000000000" + }, + "5c4881165cb42bb82e97396c8ef44adbf173fb99": { + "balance": "110600000000000000000" + }, + "25b0533b81d02a617b9229c7ec5d6f2f672e5b5a": { + "balance": "1000000000000000000000" + }, + "015f097d9acddcddafaf2a107eb93a40fc94b04c": { + "balance": "20000000000000000000000" + }, + "b84b53d0bb125656cddc52eb852ab71d7259f3d5": { + "balance": "16000000000000000000000" + }, + "1a79c7f4039c67a39d7513884cdc0e2c34222490": { + "balance": "20000000000000000000" + }, + "926209b7fda54e8ddb9d9e4d3d19ebdc8e88c29f": { + "balance": "2000000000000000000000" + }, + "c2fe7d75731f636dcd09dbda0671393ba0c82a7d": { + "balance": "2200000000000000000000" + }, + "30248d58e414b20fed3a6c482b59d9d8f5a4b7e2": { + "balance": "60000000000000000000" + }, + "d0e194f34b1db609288509ccd2e73b6131a2538b": { + "balance": "999972000000000000000" + }, + "e8f29969e75c65e01ce3d86154207d0a9e7c76f2": { + "balance": "2991807000000000000000" + }, + "cb93199b9c90bc4915bd859e3d42866dc8c18749": { + "balance": "231800000000000000000" + }, + "e6fe0afb9dcedd37b2e22c451ba6feab67348033": { + "balance": "10000000000000000000000" + }, + "82f854c9c2f087dffa985ac8201e626ca5467686": { + "balance": "100000000000000000000000" + }, + "63bb664f9117037628594da7e3c5089fd618b5b5": { + "balance": "20000000000000000000" + }, + "f8d17424c767bea31205739a2b57a7277214eebe": { + "balance": "42000000000000000000" + }, + "4ca8db4a5efefc80f4cd9bbcccb03265931332b6": { + "balance": "200000000000000000000" + }, + "c56e6b62ba6e40e52aab167d21df025d0055754b": { + "balance": "2000000000000000000000" + }, + "0d8c40a79e18994ff99ec251ee10d088c3912e80": { + "balance": "114600000000000000000" + }, + "40a331195b977325c2aa28fa2f42cb25ec3c253c": { + "balance": "2000000000000000000000" + }, + "a2c5854ff1599f98892c5725d262be1da98aadac": { + "balance": "314315000000000000000" + }, + "23ab09e73f87aa0f3be0139df0c8eb6be5634f95": { + "balance": "8000000000000000000000" + }, + "b8040536958d5998ce4bec0cfc9c2204989848e9": { + "balance": "24472420000000000000000" + }, + "42d6b263d9e9f4116c411424fc9955783c763030": { + "balance": "2000000000000000000000" + }, + "c496cbb0459a6a01600fc589a55a32b454217f9d": { + "balance": "274000000000000000000" + }, + "48302c311ef8e5dc664158dd583c81194d6e0d58": { + "balance": "3364760000000000000000" + }, + "d5b284040130abf7c1d163712371cc7e28ad66da": { + "balance": "1970000000000000000000" + }, + "d22f0ca4cd479e661775053bcc49e390f670dd8a": { + "balance": "1000000000000000000000" + }, + "e597f083a469c4591c3d2b1d2c772787befe27b2": { + "balance": "280000000000000000000" + }, + "668b6ba8ab08eace39c502ef672bd5ccb6a67a20": { + "balance": "31135320000000000000000" + }, + "a3bff1dfa9971668360c0d82828432e27bf54e67": { + "balance": "200000000000000000000" + }, + "ee655bb4ee0e8d5478526fb9f15e4064e09ff3dd": { + "balance": "200000000000000000000" + }, + "121f855b70149ac83473b9706fb44d47828b983b": { + "balance": "1400000000000000000000" + }, + "20a15256d50ce058bf0eac43aa533aa16ec9b380": { + "balance": "20000000000000000000" + }, + "69bcfc1d43b4ba19de7b274bdffb35139412d3d7": { + "balance": "985000000000000000000" + }, + "db288f80ffe232c2ba47cc94c763cf6fc9b82b0d": { + "balance": "85000000000000000000" + }, + "e1cb83ec5eb6f1eeb85e99b2fc63812fde957184": { + "balance": "20000000000000000000000" + }, + "a419a984142363267575566089340eea0ea20819": { + "balance": "1999944000000000000000" + }, + "8489f6ad1d9a94a297789156899db64154f1dbb5": { + "balance": "358849000000000000000" + }, + "d609bf4f146eea6b0dc8e06ddcf4448a1fccc9fa": { + "balance": "2000000000000000000000" + }, + "df1fa2e20e31985ebe2c0f0c93b54c0fb67a264b": { + "balance": "200000000000000000000" + }, + "efe8ff87fc260e0767638dd5d02fc4672e0ec06d": { + "balance": "2000000000000000000000" + }, + "eef1bbb1e5a83fde8248f88ee3018afa2d1332eb": { + "balance": "200000000000000000000" + }, + "4b3aab335ebbfaa870cc4d605e7d2e74c668369f": { + "balance": "60000000000000000000000" + }, + "8f4fb1aea7cd0f570ea5e61b40a4f4510b6264e4": { + "balance": "4000000000000000000000" + }, + "0b0b3862112aeec3a03492b1b05f440eca54256e": { + "balance": "4000000000000000000000" + }, + "dff4007931786593b229efe5959f3a4e219e51af": { + "balance": "4925000000000000000000" + }, + "fec14e5485de2b3eef5e74c46146db8e454e0335": { + "balance": "179000000000000000000" + }, + "ac21c1e5a3d7e0b50681679dd6c792dbca87decb": { + "balance": "100000000000000000000000" + }, + "796ebbf49b3e36d67694ad79f8ff36767ac6fab0": { + "balance": "60800000000000000000" + }, + "ae7739124ed153052503fc101410d1ffd8cd13b7": { + "balance": "999942000000000000000" + }, + "86026cad3fe4ea1ce7fca260d3d45eb09ea6a364": { + "balance": "200000000000000000000" + }, + "b2fc84a3e50a50af02f94da0383ed59f71ff01d7": { + "balance": "30000000000000000000000" + }, + "bbab000b0408ed015a37c04747bc461ab14e151b": { + "balance": "6000000000000000000000" + }, + "c4ff6fbb1f09bd9e102ba033d636ac1c4c0f5304": { + "balance": "1000000000000000000000" + }, + "cc606f511397a38fc7872bd3b0bd03c71bbd768b": { + "balance": "1000000000000000000000" + }, + "f346d7de92741c08fc58a64db55b062dde012d14": { + "balance": "295106000000000000000" + }, + "33f15223310d44de8b6636685f3a4c3d9c5655a5": { + "balance": "250500000000000000000" + }, + "3c860e2e663f46db53427b29fe3ea5e5bf62bbcc": { + "balance": "98500000000000000000" + }, + "acb94338554bc488cc88ae2d9d94080d6bdf8410": { + "balance": "1000000000000000000000" + }, + "9c5cc111092c122116f1a85f4ee31408741a7d2f": { + "balance": "492500000000000000000" + }, + "5f76f0a306269c78306b3d650dc3e9c37084db61": { + "balance": "2400000000000000000000" + }, + "2c0cc3f951482cc8a2925815684eb9f94e060200": { + "balance": "6000000000000000000000" + }, + "b74372dbfa181dc9242f39bf1d3731dffe2bdacf": { + "balance": "2000000000000000000000" + }, + "3bab4b01a7c84ba13feea9b0bb191b77a3aadca3": { + "balance": "200000000000000000000" + }, + "39aa05e56d7d32385421cf9336e90d3d15a9f859": { + "balance": "26000000000000000000" + }, + "4a52bad20357228faa1e996bed790c93674ba7d0": { + "balance": "1337000000000000000000" + }, + "ff128f4b355be1dc4a6f94fa510d7f15d53c2aff": { + "balance": "2720000000000000000000" + }, + "92793ac5b37268774a7130de2bbd330405661773": { + "balance": "40110000000000000000" + }, + "db19a3982230368f0177219cb10cb259cdb2257c": { + "balance": "2000000000000000000000" + }, + "8d1794da509cb297053661a14aa892333231e3c1": { + "balance": "199600000000000000000" + }, + "9b7c8810cc7cc89e804e6d3e38121850472877fe": { + "balance": "2000000000000000000000" + }, + "ed3cbc3782cebd67989b305c4133b2cde32211eb": { + "balance": "400000000000000000000" + }, + "8532490897bbb4ce8b7f6b837e4cba848fbe9976": { + "balance": "100000000000000000000" + }, + "c384ac6ee27c39e2f278c220bdfa5baed626d9d3": { + "balance": "600000000000000000000" + }, + "b1459285863ea2db3759e546ceb3fb3761f5909c": { + "balance": "1122309000000000000000" + }, + "634efc24371107b4cbf03f79a93dfd93e431d5fd": { + "balance": "1221341000000000000000" + }, + "ef9f59aeda418c1494682d941aab4924b5f4929a": { + "balance": "100000000000000000000000" + }, + "e7311c9533f0092c7248c9739b5b2c864a34b1ce": { + "balance": "2803436000000000000000" + }, + "e6e621eaab01f20ef0836b7cad47464cb5fd3c96": { + "balance": "316014000000000000000" + }, + "cd102cd6db3df14ad6af0f87c72479861bfc3d24": { + "balance": "2000000000000000000000" + }, + "005a9c03f69d17d66cbb8ad721008a9ebbb836fb": { + "balance": "2000000000000000000000" + }, + "a072cebe62a9e9f61cc3fbf88a9efbfe3e9a8d70": { + "balance": "400000000000000000000" + }, + "f2ab1161750244d0ecd048ee0d3e51abb143a2fd": { + "balance": "1235800000000000000000" + }, + "f686785b89720b61145fea80978d6acc8e0bc196": { + "balance": "4000000000000000000000" + }, + "0a2b4fc5d81ace67dc4bba03f7b455413d46fe3d": { + "balance": "197000000000000000000" + }, + "c32ec7e42ad16ce3e2555ad4c54306eda0b26758": { + "balance": "2000000000000000000000" + }, + "f3fa723552a5d0512e2b62f48dca7b2b8105305b": { + "balance": "137000000000000000000" + }, + "6dc3f92baa1d21dab7382b893261a0356fa7c187": { + "balance": "1730000000000000000000" + }, + "4627c606842671abde8295ee5dd94c7f549534f4": { + "balance": "286600000000000000000" + }, + "e39e46e15d22ce56e0c32f1877b7d1a264cf94f3": { + "balance": "20000000000000000000000" + }, + "d7d157e4c0a96437a6d285741dd23ec4361fa36b": { + "balance": "2000000000000000000000" + }, + "68f8f45155e98c5029a4ebc5b527a92e9fa83120": { + "balance": "4436101000000000000000" + }, + "9aba2b5e27ff78baaab5cdc988b7be855cebbdce": { + "balance": "9999000000000000000000" + }, + "66b39837cb3cac8a802afe3f12a258bbca62dacd": { + "balance": "400000000000000000000" + }, + "d39b7cbc94003fc948f0cde27b100db8ccd6e063": { + "balance": "400000000000000000000" + }, + "3db9ed7f024c7e26372feacf2b050803445e3810": { + "balance": "1285600000000000000000" + }, + "3fbc1e4518d73400c6d046359439fb68ea1a49f4": { + "balance": "16400000000000000000000" + }, + "e3da4f3240844c9b6323b4996921207122454399": { + "balance": "11539639000000000000000" + }, + "09afa73bc047ef46b977fd9763f87286a6be68c6": { + "balance": "501500000000000000000" + }, + "1dbe8e1c2b8a009f85f1ad3ce80d2e05350ee39c": { + "balance": "135400000000000000000" + }, + "2c5a2d0abda03bbe215781b4ff296c8c61bdbaf6": { + "balance": "30617000000000000000" + }, + "9a9d1dc0baa77d6e20c3d849c78862dd1c054c87": { + "balance": "880000000000000000000" + }, + "3ccef88679573947e94997798a1e327e08603a65": { + "balance": "807700000000000000000" + }, + "850b9db18ff84bf0c7da49ea3781d92090ad7e64": { + "balance": "2600000000000000000000" + }, + "361c75931696bc3d427d93e76c77fd13b241f6f4": { + "balance": "549212000000000000000" + }, + "c8f2b320e6dfd70906c597bad2f9501312c78259": { + "balance": "1504800000000000000000" + }, + "8dc1d5111d09af25fdfcac455c7cec283e6d6775": { + "balance": "2000000000000000000000" + }, + "cd7ece086b4b619b3b369352ee38b71ddb06439a": { + "balance": "200000000000000000000" + }, + "f607c2150d3e1b99f24fa1c7d540add35c4ebe1e": { + "balance": "3098020000000000000000" + }, + "32485c818728c197fea487fbb6e829159eba8370": { + "balance": "1053893000000000000000" + }, + "8e670815fb67aeaea57b86534edc00cdf564fee5": { + "balance": "3300000000000000000000" + }, + "10df681506e34930ac7a5c67a54c3e89ce92b981": { + "balance": "2153800000000000000000" + }, + "1cf2eb7a8ccac2adeaef0ee87347d535d3b94058": { + "balance": "2000000000000000000000" + }, + "f0dc43f205619127507b2b1c1cfdf32d28310920": { + "balance": "301973000000000000000" + }, + "f2c2904e9fa664a11ee25656d8fd2cc0d9a522a0": { + "balance": "13370000000000000000" + }, + "70670fbb05d33014444b8d1e8e7700258b8caa6d": { + "balance": "2000000000000000000000" + }, + "5160ed612e1b48e73f3fc15bc4321b8f23b8a24b": { + "balance": "562800000000000000000" + }, + "54a62bf9233e146ffec3876e45f20ee8414adeba": { + "balance": "10000000000000000000000" + }, + "26d4ec17d5ceb2c894bdc59d0a6a695dad2b43cc": { + "balance": "2935300000000000000000" + }, + "205fc843e19a4913d1881eb69b69c0fa3be5c50b": { + "balance": "9700000000000000000000" + }, + "e001aba77c02e172086c1950fffbcaa30b83488f": { + "balance": "1970000000000000000000" + }, + "21efbca09b3580b98e73f5b2f7f4dc0bf02c529c": { + "balance": "2000000000000000000000" + }, + "c4d916574e68c49f7ef9d3d82d1638b2b7ee0985": { + "balance": "1580000000000000000000" + }, + "cab0d32cf3767fa6b3537c84328baa9f50458136": { + "balance": "8960000000000000000000" + }, + "7ce4686446f1949ebed67215eb0d5a1dd72c11b8": { + "balance": "2217776000000000000000" + }, + "7837fcb876da00d1eb3b88feb3df3fa4042fac82": { + "balance": "1760000000000000000000" + }, + "71e38ff545f30fe14ca863d4f5297fd48c73a5ce": { + "balance": "3580000000000000000000" + }, + "e528a0e5a267d667e9393a6584e19b34dc9be973": { + "balance": "5600000000000000000000" + }, + "c5374928cdf193705443b14cc20da423473cd9cf": { + "balance": "138139000000000000000" + }, + "e406f5dd72cab66d8a6ecbd6bfb494a7b6b09afe": { + "balance": "100000000000000000000" + }, + "d7ef340e66b0d7afcce20a19cb7bfc81da33d94e": { + "balance": "3000000000000000000000" + }, + "e012db453827a58e16c1365608d36ed658720507": { + "balance": "2000000000000000000000" + }, + "d59638d3c5faa7711bf085745f9d5bdc23d498d8": { + "balance": "2000000000000000000000" + }, + "008fc7cbadffbd0d7fe44f8dfd60a79d721a1c9c": { + "balance": "1000000000000000000000" + }, + "8a3470282d5e2a2aefd7a75094c822c4f5aeef8a": { + "balance": "242743000000000000000" + }, + "38b3965c21fa893931079beacfffaf153678b6eb": { + "balance": "170374000000000000000" + }, + "57dd9471cbfa262709f5f486bcb774c5f527b8f8": { + "balance": "197000000000000000000" + }, + "5a60c924162873fc7ea4da7f972e350167376031": { + "balance": "83583000000000000000" + }, + "b9013c51bd078a098fae05bf2ace0849c6be17a5": { + "balance": "80000000000000000000" + }, + "dc23b260fcc26e7d10f4bd044af794579460d9da": { + "balance": "500038000000000000000" + }, + "45db03bccfd6a5f4d0266b82a22a368792c77d83": { + "balance": "8000000000000000000000" + }, + "3e0cbe6a6dcb61f110c45ba2aa361d7fcad3da73": { + "balance": "8022000000000000000000" + }, + "42d3a5a901f2f6bd9356f112a70180e5a1550b60": { + "balance": "925000000000000000000" + }, + "47219229e8cd56659a65c2a943e2dd9a8f4bfd89": { + "balance": "1520000000000000000000" + }, + "a20d071b1b003063497d7990e1249dabf36c35f7": { + "balance": "1000000000000000000000" + }, + "6835c8e8b74a2ca2ae3f4a8d0f6b954a3e2a8392": { + "balance": "60140000000000000000" + }, + "0c2d5c920538e953caaf24f0737f554cc6927742": { + "balance": "1000000000000000000000" + }, + "eedf6c4280e6eb05b934ace428e11d4231b5905b": { + "balance": "200000000000000000000" + }, + "ffa696ecbd787e66abae4fe87b635f07ca57d848": { + "balance": "1337000000000000000000" + }, + "3e81772175237eb4cbe0fe2dcafdadffeb6a1999": { + "balance": "8800000000000000000000" + }, + "b44783c8e57b480793cbd69a45d90c7b4f0c48ac": { + "balance": "20000000000000000000" + }, + "f84f090adf3f8db7e194b350fbb77500699f66fd": { + "balance": "1970000000000000000000" + }, + "2e9824b5c132111bca24ddfba7e575a5cd7296c1": { + "balance": "17201900000000000000000" + }, + "5cce72d068c7c3f55b1d2819545e77317cae8240": { + "balance": "1940000000000000000000" + }, + "d815e1d9f4e2b5e57e34826b7cfd8881b8546890": { + "balance": "17300000000000000000" + }, + "f901c00fc1db88b69c4bc3252b5ca70ea6ee5cf6": { + "balance": "400000000000000000000" + }, + "a960b1cadd3b5c1a8e6cb3abcaf52ee7c3d9fa88": { + "balance": "1522704000000000000000" + }, + "f7e45a12aa711c709acefe95f33b78612d2ad22a": { + "balance": "66230000000000000000000" + }, + "c332df50b13c013490a5d7c75dbfa366da87b6d6": { + "balance": "4000000000000000000000" + }, + "d467cf064c0871989b90d8b2eb14ccc63b360823": { + "balance": "200000000000000000000" + }, + "b9144b677c2dc614ceefdf50985f1183208ea64c": { + "balance": "2000000000000000000000" + }, + "ea7c4d6dc729cd6b157c03ad237ca19a209346c3": { + "balance": "2000000000000000000000" + }, + "9c9de44724a4054da0eaa605abcc802668778bea": { + "balance": "200020000000000000000" + }, + "d7140c8e5a4307fab0cc27badd9295018bf87970": { + "balance": "109600000000000000000" + }, + "c33acdb3ba1aab27507b86b15d67faf91ecf6293": { + "balance": "2000000000000000000000" + }, + "db2a0c9ab64df58ddfb1dbacf8ba0d89c85b31b4": { + "balance": "4000000000000000000000" + }, + "bfcb9730246304700da90b4153e71141622e1c41": { + "balance": "1000000000000000000000" + }, + "07dc8c8b927adbedfa8f5d639b4352351f2f36d2": { + "balance": "314382000000000000000" + }, + "2d5391e938b34858cf965b840531d5efda410b09": { + "balance": "1400000000000000000000" + }, + "0b5e2011ebc25a007f21362960498afb8af280fb": { + "balance": "2000000000000000000000" + }, + "ed9fb1f5af2fbf7ffc5029cee42b70ff5c275bf5": { + "balance": "280000000000000000000" + }, + "a3232d068d50064903c9ebc563b515acc8b7b097": { + "balance": "2002000000000000000000" + }, + "66274fea82cd30b6c29b23350e4f4f3d310a5899": { + "balance": "2070000000000000000000" + }, + "dbfb1bb464b8a58e500d2ed8de972c45f5f1c0fb": { + "balance": "1600000000000000000000" + }, + "a1f8d8bcf90e777f19b3a649759ad95027abdfc3": { + "balance": "200000000000000000000" + }, + "5bd23547477f6d09d7b2a005c5ee650c510c56d7": { + "balance": "10000000000000000000000" + }, + "ec3b8b58a12703e581ce5ffd7e21c57d1e5c663f": { + "balance": "1700000000000000000000" + }, + "54310b3aa88703a725dfa57de6e646935164802c": { + "balance": "1910000000000000000000" + }, + "8f41b1fbf54298f5d0bc2d122f4eb95da4e5cd3d": { + "balance": "354200000000000000000" + }, + "c80b36d1beafba5fcc644d60ac6e46ed2927e7dc": { + "balance": "13370000000000000000" + }, + "1ea492bce1ad107e337f4bd4a7ac9a7babcccdab": { + "balance": "100000000000000000000" + }, + "aaf023fef290a49bb78bb7abc95d669c50d528b0": { + "balance": "200000000000000000000" + }, + "80b79f338390d1ba1b3737a29a0257e5d91e0731": { + "balance": "20000000000000000000" + }, + "f382e4c20410b951089e19ba96a2fee3d91cce7e": { + "balance": "5054000000000000000000" + }, + "0748713145ef83c3f0ef4d31d823786f7e9cc689": { + "balance": "4500000000000000000000" + }, + "21e219c89ca8ac14ae4cba6130eeb77d9e6d3962": { + "balance": "789580000000000000000" + }, + "ca9a042a6a806ffc92179500d24429e8ab528117": { + "balance": "1100000000000000000000" + }, + "bcc9593b2da6df6a34d71b1aa38dacf876f95b88": { + "balance": "20000000000000000000" + }, + "d1438267231704fc7280d563adf4763844a80722": { + "balance": "200000000000000000000" + }, + "4989e1ab5e7cd00746b3938ef0f0d064a2025ba5": { + "balance": "2000000000000000000000" + }, + "bd4b60faec740a21e3071391f96aa534f7c1f44e": { + "balance": "182000000000000000000" + }, + "8c7cb4e48b25031aa1c4f92925d631a8c3edc761": { + "balance": "1000000000000000000000" + }, + "322788b5e29bf4f5f55ae1ddb32085fda91b8ebe": { + "balance": "200000000000000000000" + }, + "f15e182c4fbbad79bd93342242d4dccf2be58925": { + "balance": "1940000000000000000000" + }, + "1548b770a5118ede87dba2f690337f616de683ab": { + "balance": "527558000000000000000" + }, + "69c2d835f13ee90580408e6a3283c8cca6a434a2": { + "balance": "656000000000000000000" + }, + "a1e4380a3b1f749673e270229993ee55f35663b4": { + "balance": "2000000000000000000000" + }, + "c7675e5647b9d8daf4d3dff1e552f6b07154ac38": { + "balance": "180000000000000000000" + }, + "a02c1e34064f0475f7fa831ccb25014c3aa31ca2": { + "balance": "60000000000000000000" + }, + "517c75430de401c341032686112790f46d4d369e": { + "balance": "388000000000000000000" + }, + "29681d9912ddd07eaabb88d05d90f766e862417d": { + "balance": "1000000000000000000000" + }, + "544dda421dc1eb73bb24e3e56a248013b87c0f44": { + "balance": "1970000000000000000000" + }, + "2ab97e8d59eee648ab6caf8696f89937143864d6": { + "balance": "3820000000000000000000" + }, + "79c130c762b8765b19d2abc9a083ab8f3aad7940": { + "balance": "3940000000000000000000" + }, + "f9650d6989f199ab1cc479636ded30f241021f65": { + "balance": "850000000000000000000" + }, + "d1c96e70f05ae0e6cd6021b2083750a7717cde56": { + "balance": "500000000000000000000" + }, + "88106c27d20b74b4b98ca62b232bd5c97411171f": { + "balance": "197000000000000000000" + }, + "37ab66083a4fa23848b886f9e66d79cdc150cc70": { + "balance": "88510000000000000000000" + }, + "8e6156336be2cdbe32140df08a2ba55fd0a58463": { + "balance": "74480000000000000000" + }, + "2982d76a15f847dd41f1922af368fe678d0e681e": { + "balance": "100000000000000000000" + }, + "209e8e29d33beae8fb6baa783d133e1d9ec1bc0b": { + "balance": "835000000000000000000" + }, + "b325674c01e3f7290d5226339fbeac67d221279f": { + "balance": "2800000000000000000000" + }, + "f20c9a99b74759d782f25c1ceca802a27e0b436c": { + "balance": "1670000000000000000000" + }, + "61bf84d5ab026f58c873f86ff0dfca82b55733ae": { + "balance": "2000000000000000000000" + }, + "0734a0a81c9562f4d9e9e10a8503da15db46d76e": { + "balance": "18200000000000000000" + }, + "0521bc3a9f8711fecb10f50797d71083e341eb9d": { + "balance": "20000000000000000000" + }, + "3301d9ca2f3bfe026279cd6819f79a293d98156e": { + "balance": "50000000000000000000000" + }, + "549d51af29f724c967f59423b85b2681e7b15136": { + "balance": "3760000000000000000000" + }, + "2053ac97548a0c4e8b80bc72590cd6a098fe7516": { + "balance": "187000000000000000000" + }, + "aa321fdbd449180db8ddd34f0fe906ec18ee0914": { + "balance": "685000000000000000000" + }, + "697f55536bf85ada51841f0287623a9f0ed09a17": { + "balance": "10000000000000000000000" + }, + "df57353aaff2aadb0a04f9014e8da7884e86589c": { + "balance": "152800000000000000000" + }, + "6807ddc88db489b033e6b2f9a81553571ab3c805": { + "balance": "29944000000000000000" + }, + "90057af9aa66307ec9f033b29724d3b2f41eb6f9": { + "balance": "121930000000000000000000" + }, + "3ff836b6f57b901b440c30e4dbd065cf37d3d48c": { + "balance": "200000000000000000000" + }, + "91051764af6b808e4212c77e30a5572eaa317070": { + "balance": "1000000000000000000000" + }, + "7faa30c31519b584e97250ed2a3cf3385ed5fd50": { + "balance": "2000000000000000000000" + }, + "fb842ca2c5ef133917a236a0d4ac40690110b038": { + "balance": "306000000000000000000" + }, + "aa167026d39ab7a85635944ed9edb2bfeba11850": { + "balance": "8298000000000000000000" + }, + "57beea716cbd81700a73d67f9ff039529c2d9025": { + "balance": "200000000000000000000" + }, + "654b7e808799a83d7287c67706f2abf49a496404": { + "balance": "1970000000000000000000" + }, + "dde8f0c31b7415511dced1cd7d46323e4bd12232": { + "balance": "1610000000000000000000" + }, + "8667fa1155fed732cfb8dca5a0d765ce0d0705ed": { + "balance": "81770000000000000000" + }, + "905526568ac123afc0e84aa715124febe83dc87c": { + "balance": "17900000000000000000" + }, + "8e98766524b0cf2747c50dd43b9567594d9731de": { + "balance": "1997200000000000000000" + }, + "c6df2075ebd240d44869c2be6bdf82e63d4ef1f5": { + "balance": "20000000000000000000" + }, + "2ff5cab12c0d957fd333f382eeb75107a64cb8e8": { + "balance": "10000000000000000000000" + }, + "3055efd26029e0d11b930df4f53b162c8c3fd2ce": { + "balance": "499938000000000000000" + }, + "b2c53efa33fe4a3a1a80205c73ec3b1dbcad0602": { + "balance": "1918595000000000000000" + }, + "766b3759e8794e926dac473d913a8fb61ad0c2c9": { + "balance": "86500000000000000000" + }, + "882aa798bf41df179f85520130f15ccdf59b5e58": { + "balance": "2000000000000000000000" + }, + "80b23d380b825c46e0393899a85556462da0e18c": { + "balance": "2000000000000000000000" + }, + "51f4663ab44ff79345f427a0f6f8a6c8a53ff234": { + "balance": "20000000000000000000000" + }, + "8d5ef172bf77315ea64e85d0061986c794c6f519": { + "balance": "3940000000000000000000" + }, + "75ac547017134c04ae1e11d60e63ec04d18db4ef": { + "balance": "6000000000000000000000" + }, + "ce1b0cb46aaecfd79b880cad0f2dda8a8dedd0b1": { + "balance": "20000000000000000000" + }, + "21408b4d7a2c0e6eca4143f2cacdbbccba121bd8": { + "balance": "20000000000000000000000" + }, + "9c526a140683edf1431cfaa128a935e2b614d88b": { + "balance": "111000000000000000000" + }, + "599728a78618d1a17b9e34e0fed8e857d5c40622": { + "balance": "14000000000000000000000" + }, + "6ac4d4be2db0d99da3faaaf7525af282051d6a90": { + "balance": "80185000000000000000" + }, + "785c8ea774d73044a734fa790a1b1e743e77ed7c": { + "balance": "238750000000000000000" + }, + "ff2726294148b86c78a9372497e459898ed3fee3": { + "balance": "1970000000000000000000" + }, + "68a86c402388fddc59028fec7021e98cbf830eac": { + "balance": "19100000000000000000" + }, + "6121af398a5b2da69f65c6381aec88ce9cc6441f": { + "balance": "640000000000000000000" + }, + "5a6686b0f17e07edfc59b759c77d5bef164d3879": { + "balance": "1490000000000000000000" + }, + "a2d38de1c73906f6a7ca6efeb97cf6f69cc421be": { + "balance": "1000000000000000000000" + }, + "ae3f98a443efe00f3e711d525d9894dc9a61157b": { + "balance": "295500000000000000000" + }, + "5f1c8a04c90d735b8a152909aeae636fb0ce1665": { + "balance": "6999974000000000000000" + }, + "d687cec0059087fdc713d4d2d65e77daefedc15f": { + "balance": "60000000000000000000" + }, + "845203750f7148a9aa262921e86d43bf641974fd": { + "balance": "100000000000000000000" + }, + "64464a6805b462412a901d2db8174b06c22deea6": { + "balance": "475600000000000000000" + }, + "053471cd9a41925b3904a5a8ffca3659e034be23": { + "balance": "199600000000000000000" + }, + "911ff233e1a211c0172c92b46cf997030582c83a": { + "balance": "1970000000000000000000" + }, + "d930b27a78876485d0f48b70dd5336549679ca8f": { + "balance": "40000000000000000000" + }, + "6ba9b21b35106be159d1c1c2657ac56cd29ffd44": { + "balance": "4480000000000000000000" + }, + "ebac2b4408ef5431a13b8508e86250982114e145": { + "balance": "4000000000000000000000" + }, + "931df34d1225bcd4224e63680d5c4c09bce735a6": { + "balance": "68000000000000000000" + }, + "23eb6fd85671a9063ab7678ebe265a20f61a02b3": { + "balance": "2000000000000000000000" + }, + "b32af3d3e8d075344926546f2e32887bf93b16bd": { + "balance": "200000000000000000000" + }, + "8261fa230c901d43ff579f4780d399f31e6076bc": { + "balance": "2000000000000000000000" + }, + "84a74ceecff65cb93b2f949d773ef1ad7fb4a245": { + "balance": "92998000000000000000" + }, + "da982e9643ffece723075a40fe776e5ace04b29b": { + "balance": "160884000000000000000" + }, + "ba70e8b4759c0c3c82cc00ac4e9a94dd5bafb2b8": { + "balance": "890342000000000000000" + }, + "82f2e991fd324c5f5d17768e9f61335db6319d6c": { + "balance": "500000000000000000000" + }, + "3e84b35c5b2265507061d30b6f12da033fe6f8b9": { + "balance": "1790000000000000000000" + }, + "2895e80999d406ad592e2b262737d35f7db4b699": { + "balance": "1940000000000000000000" + }, + "65f534346d2ffb787fa9cf185d745ba42986bd6e": { + "balance": "500000000000000000000" + }, + "c7368b9709a5c1b51c0adf187a65df14e12b7dba": { + "balance": "9489681000000000000000" + }, + "ba176dbe3249e345cd4fa967c0ed13b24c47e586": { + "balance": "399990000000000000000" + }, + "cff6a6fe3e9a922a12f21faa038156918c4fcb9c": { + "balance": "78800000000000000000" + }, + "bcbd31252ec288f91e298cd812c92160e738331a": { + "balance": "1975802000000000000000" + }, + "5543dd6d169eec8a213bbf7a8af9ffd15d4ff759": { + "balance": "18200000000000000000" + }, + "b65bd780c7434115162027565223f44e5498ff8c": { + "balance": "19999800000000000000000" + }, + "4cadf573ce4ceec78b8e1b21b0ed78eb113b2c0e": { + "balance": "2000000000000000000000" + }, + "04aafc8ae5ce6f4903c89d7fac9cb19512224777": { + "balance": "500000000000000000000" + }, + "fdc4d4765a942f5bf96931a9e8cc7ab8b757ff4c": { + "balance": "87000000000000000000000" + }, + "38c7851f5ffd4cee98df30f3b25597af8a6ca263": { + "balance": "2631920000000000000000" + }, + "0e320219838e859b2f9f18b72e3d4073ca50b37d": { + "balance": "2000000000000000000000" + }, + "bbbf39b1b67995a42241504f9703d2a14a515696": { + "balance": "1580000000000000000000" + }, + "5b800bfd1b3ed4a57d875aed26d42f1a7708d72a": { + "balance": "6392000000000000000000" + }, + "5b85e60e2af0544f2f01c64e2032900ebd38a3c7": { + "balance": "2000000000000000000000" + }, + "c9ac01c3fb0929033f0ccc7e1acfeaaba7945d47": { + "balance": "12459235000000000000000" + }, + "f355d3ec0cfb907d8dbb1bf3464e458128190bac": { + "balance": "4925600000000000000000" + }, + "69c08d744754de709ce96e15ae0d1d395b3a2263": { + "balance": "1000000000000000000000" + }, + "cef77451dfa2c643e00b156d6c6ff84e2373eb66": { + "balance": "188000000000000000000" + }, + "f3034367f87d24d3077fa9a2e38a8b0ccb1104ef": { + "balance": "1000000000000000000000" + }, + "73473e72115110d0c3f11708f86e77be2bb0983c": { + "balance": "20000000000000000000" + }, + "761e6caec189c230a162ec006530193e67cf9d19": { + "balance": "2000000000000000000000" + }, + "e9caf827be9d607915b365c83f0d3b7ea8c79b50": { + "balance": "3000000000000000000000" + }, + "eda4b2fa59d684b27a810df8978a73df308a63c2": { + "balance": "4000000000000000000000" + }, + "065ff575fd9c16d3cb6fd68ffc8f483fc32ec835": { + "balance": "200000000000000000000" + }, + "a72ee666c4b35e82a506808b443cebd5c632c7dd": { + "balance": "800000000000000000000" + }, + "5b30608c678e1ac464a8994c3b33e5cdf3497112": { + "balance": "400000000000000000000" + }, + "b0c7ce4c0dc3c2bbb99cc1857b8a455f611711ce": { + "balance": "4000000000000000000000" + }, + "d7274d50804d9c77da93fa480156efe57ba501de": { + "balance": "1940000000000000000000" + }, + "a609c26dd350c235e44b2b9c1dddccd0a9d9f837": { + "balance": "1000000000000000000000" + }, + "bddfa34d0ebf1b04af53b99b82494a9e3d8aa100": { + "balance": "12000000000000000000000" + }, + "fd40242bb34a70855ef0fd90f3802dec2136b327": { + "balance": "1930600000000000000000" + }, + "58aed6674affd9f64233272a578dd9386b99c263": { + "balance": "3400000000000000000000" + }, + "24434a3e32e54ecf272fe3470b5f6f512f675520": { + "balance": "5910000000000000000000" + }, + "a379a5070c503d2fac89b8b3afa080fd45ed4bec": { + "balance": "19700000000000000000000" + }, + "37e169a93808d8035698f815c7235613c1e659f2": { + "balance": "1000000000000000000000" + }, + "849b116f596301c5d8bb62e0e97a8248126e39f3": { + "balance": "300000000000000000000" + }, + "fe7011b698bf3371132d7445b19eb5b094356aee": { + "balance": "2000000000000000000000" + }, + "f16de1891d8196461395f9b136265b3b9546f6ef": { + "balance": "31313000000000000000" + }, + "6c6564e5c9c24eaaa744c9c7c968c9e2c9f1fbae": { + "balance": "1357800000000000000000" + }, + "8bb0212f3295e029cab1d961b04133a1809e7b91": { + "balance": "2000000000000000000000" + }, + "408a69a40715e1b313e1354e600800a1e6dc02a5": { + "balance": "35144000000000000000" + }, + "ddf0cce1fe996d917635f00712f4052091dff9ea": { + "balance": "2000000000000000000000" + }, + "50fef296955588caae74c62ec32a23a454e09ab8": { + "balance": "1201200000000000000000" + }, + "d913f0771949753c4726acaa2bd3619c5c20ff77": { + "balance": "3000000000000000000000" + }, + "9d6ecfa03af2c6e144b7c4692a86951e902e9e1f": { + "balance": "3000310000000000000000" + }, + "ecbe5e1c9ad2b1dccf0a305fc9522f4669dd3ae7": { + "balance": "5000000000000000000000" + }, + "33e9b71823952e1f66958c278fc28b1196a6c5a4": { + "balance": "100000000000000000000" + }, + "9de20bc37e7f48a80ffd7ad84ffbf1a1abe1738c": { + "balance": "200000000000000000000" + }, + "16f313cf8ad000914a0a176dc6a4342b79ec2538": { + "balance": "2000000000000000000000" + }, + "991ac7ca7097115f26205eee0ef7d41eb4e311ae": { + "balance": "20000000000000000000" + }, + "ddfafdbc7c90f1320e54b98f374617fbd01d109f": { + "balance": "13370000000000000000" + }, + "26b11d066588ce74a572a85a6328739212aa8b40": { + "balance": "2000000000000000000000" + }, + "ef2c34bb487d3762c3cca782ccdd7a8fbb0a9931": { + "balance": "180000000000000000000" + }, + "a9be88ad1e518b0bbb024ab1d8f0e73f790e0c76": { + "balance": "2800000000000000000000" + }, + "4a7494cce44855cc80582842be958a0d1c0072ee": { + "balance": "2400000000000000000000" + }, + "23569542c97d566018c907acfcf391d14067e87e": { + "balance": "2000000000000000000000" + }, + "d252960b0bf6b2848fdead80136db5f507f8be02": { + "balance": "2000000000000000000000" + }, + "2c0f5b9df43625798e7e03c1a5fd6a6d091af82b": { + "balance": "31200000000000000000" + }, + "a7c9d388ebd873e66b1713448397d0f37f8bd3a8": { + "balance": "5000000000000000000000" + }, + "3259bd2fddfbbc6fbad3b6e874f0bbc02cda18b5": { + "balance": "11886645000000000000000" + }, + "f287ff52f461117adb3e1daa71932d1493c65f2e": { + "balance": "3640000000000000000000" + }, + "c852428d2b586497acd30c56aa13fb5582f84402": { + "balance": "945600000000000000000" + }, + "296f00de1dc3bb01d47a8ccd1e5d1dd9a1eb7791": { + "balance": "1000000000000000000000" + }, + "817493cd9bc623702a24a56f9f82e3fd48f3cd31": { + "balance": "2920000000000000000000" + }, + "7adfedb06d91f3cc7390450b85550270883c7bb7": { + "balance": "322312000000000000000" + }, + "8d544c32c07fd0842c761d53a897d6c950bb7599": { + "balance": "200000000000000000000" + }, + "86297d730fe0f7a9ee24e08fb1087b31adb306a7": { + "balance": "2000000000000000000000" + }, + "f64fe0939a8d1eea2a0ecd9a9730fd7958e33109": { + "balance": "20600000000000000000" + }, + "b06eab09a610c6a53d56a946b2c43487ac1d5b2d": { + "balance": "1000000000000000000000" + }, + "bae9b82f7299631408659dd74e891cb8f3860fe5": { + "balance": "1970000000000000000000" + }, + "0eda80f4ed074aea697aeddf283b63dbca3dc4da": { + "balance": "2000000000000000000000" + }, + "ea686c5057093c171c66db99e01b0ececb308683": { + "balance": "384907000000000000000" + }, + "425725c0f08f0811f5f006eec91c5c5c126b12ae": { + "balance": "150000000000000000000" + }, + "b18e67a5050a1dc9fb190919a33da838ef445014": { + "balance": "20000000000000000000" + }, + "8dd484ff8a307364eb66c525a571aac701c5c318": { + "balance": "4000000000000000000000" + }, + "6671b182c9f741a0cd3c356c73c23126d4f9e6f4": { + "balance": "200000000000000000000" + }, + "ba0249e01d945bef93ee5ec61925e03c5ca509fd": { + "balance": "4000000000000000000000" + }, + "b2968f7d35f208871631c6687b3f3daeabc6616c": { + "balance": "156060000000000000000" + }, + "a6f62b8a3d7f11220701ab9ffffcb327959a2785": { + "balance": "506000000000000000000" + }, + "c885a18aabf4541b7b7b7ecd30f6fae6869d9569": { + "balance": "2000000000000000000000" + }, + "33fb577a4d214fe010d32cca7c3eeda63f87ceef": { + "balance": "1000000000000000000000" + }, + "be86d0b0438419ceb1a038319237ba5206d72e46": { + "balance": "999942000000000000000" + }, + "466292f0e80d43a78774277590a9eb45961214f4": { + "balance": "970000000000000000000" + }, + "b33c0323fbf9c26c1d8ac44ef74391d0804696da": { + "balance": "20000000000000000000" + }, + "f7bc4c44910d5aedd66ed2355538a6b193c361ec": { + "balance": "96980000000000000000" + }, + "d0f04f52109aebec9a7b1e9332761e9fe2b97bb5": { + "balance": "4000000000000000000000" + }, + "cb4a914d2bb029f32e5fef5c234c4fec2d2dd577": { + "balance": "1800000000000000000000" + }, + "2e619f57abc1e987aa936ae3a2264962e7eb2d9a": { + "balance": "756000000000000000000" + }, + "166bf6dab22d841b486c38e7ba6ab33a1487ed8c": { + "balance": "20000000000000000000000" + }, + "c3a046e3d2b2bf681488826e32d9c061518cfe8c": { + "balance": "2600000000000000000000" + }, + "d082275f745a2cac0276fbdb02d4b2a3ab1711fe": { + "balance": "30000000000000000000" + }, + "a701df79f594901afe1444485e6b20c3bda2b9b3": { + "balance": "1000000000000000000000" + }, + "dec3eec2640a752c466e2b7e7ee685afe9ac41f4": { + "balance": "1324245000000000000000" + }, + "8134dd1c9df0d6c8a5812426bb55c761ca831f08": { + "balance": "122360000000000000000" + }, + "bfc57aa666fae28e9f107a49cb5089a4e22151dd": { + "balance": "1000000000000000000000" + }, + "c3c2297329a6fd99117e54fc6af379b4d556547e": { + "balance": "6000000000000000000000" + }, + "40585200683a403901372912a89834aadcb55fdb": { + "balance": "2000000000000000000000" + }, + "cd49bf185e70d04507999f92a4de4455312827d0": { + "balance": "1000000000000000000000" + }, + "9c6bc9a46b03ae5404f043dfcf21883e4110cc33": { + "balance": "200000000000000000000" + }, + "1f49b86d0d3945590698a6aaf1673c37755ca80d": { + "balance": "700000000000000000000" + }, + "efeb1997aad277cc33430e6111ed0943594048b8": { + "balance": "2000000000000000000000" + }, + "7c0883054c2d02bc7a852b1f86c42777d0d5c856": { + "balance": "500000000000000000000" + }, + "ff49a775814ec00051a795a875de24592ea400d4": { + "balance": "200000000000000000000000" + }, + "f039683d7b3d225bc7d8dfadef63163441be41e2": { + "balance": "34380000000000000000" + }, + "a3ba0d3a3617b1e31b4e422ce269e873828d5d69": { + "balance": "850000000000000000000" + }, + "d116f3dcd5db744bd008887687aa0ec9fd7292aa": { + "balance": "1000000000000000000000" + }, + "5719f49b720da68856f4b9e708f25645bdbc4b41": { + "balance": "640000000000000000000" + }, + "870796abc0db84af82da52a0ed68734de7e636f5": { + "balance": "300000000000000000000" + }, + "68b6854788a7c6496cdbf5f84b9ec5ef392b78bb": { + "balance": "19700000000000000000000" + }, + "8c2fbeee8eacc5c5d77c16abd462ee9c8145f34b": { + "balance": "1940000000000000000000" + }, + "421684baa9c0b4b5f55338e6f6e7c8e146d41cb7": { + "balance": "1500000000000000000000" + }, + "dd26b429fd43d84ec179825324bad5bfb916b360": { + "balance": "5142000000000000000000" + }, + "3821862493242c0aeb84b90de05d250c1e50c074": { + "balance": "322200000000000000000" + }, + "68a7425fe09eb28cf86eb1793e41b211e57bd68d": { + "balance": "668500000000000000000" + }, + "da875e4e2f3cabe4f37e0eaed7d1f6dcc6ffef43": { + "balance": "2000000000000000000000" + }, + "c2663f8145dbfec6c646fc5c49961345de1c9f11": { + "balance": "690000000000000000000" + }, + "e89c22f1a4e1d4746ecfaa59ed386fee12d51e37": { + "balance": "44932000000000000000" + }, + "eff86b5123bcdc17ed4ce8e05b7e12e51393a1f7": { + "balance": "500000000000000000000" + }, + "6c3d18704126aa99ee3342ce60f5d4c85f1867cd": { + "balance": "50000000000000000000" + }, + "b8d531a964bcea13829620c0ced72422dadb4cca": { + "balance": "169990000000000000000" + }, + "7c29d47d57a733f56b9b217063b513dc3b315923": { + "balance": "4000000000000000000000" + }, + "bc1e80c181616342ebb3fb3992072f1b28b802c6": { + "balance": "4000000000000000000000" + }, + "31313ffd635bf2f3324841a88c07ed146144ceeb": { + "balance": "1970000000000000000000" + }, + "cc4feb72df98ff35a138e01761d1203f9b7edf0a": { + "balance": "7000000000000000000000" + }, + "741693c30376508513082020cc2b63e9fa92131b": { + "balance": "1200000000000000000000" + }, + "aa3135cb54f102cbefe09e96103a1a796718ff54": { + "balance": "57800000000000000000" + }, + "ef61155ba009dcdebef10b28d9da3d1bc6c9ced4": { + "balance": "59100000000000000000" + }, + "b3c94811e7175b148b281c1a845bfc9bb6fbc115": { + "balance": "200000000000000000000" + }, + "96d9cca8f55eea0040ec6eb348a1774b95d93ef4": { + "balance": "4000000000000000000000" + }, + "ce62125adec3370ac52110953a4e760be9451e3b": { + "balance": "152000000000000000000" + }, + "aca1e6bc64cc3180f620e94dc5b1bcfd8158e45d": { + "balance": "2000000000000000000000" + }, + "bc237148d30c13836ffa2cad520ee4d2e5c4eeff": { + "balance": "1970000000000000000000" + }, + "0e024e7f029c6aaf3a8b910f5e080873b85795aa": { + "balance": "1000000000000000000000" + }, + "7283cd4675da58c496556151dafd80c7f995d318": { + "balance": "760000000000000000000" + }, + "39b299327490d72f9a9edff11b83afd0e9d3c450": { + "balance": "200000000000000000000" + }, + "5f333a3b2310765a0d1832b9be4c0a03704c1c09": { + "balance": "1000000000000000000000" + }, + "5aaf1c31254a6e005fba7f5ab0ec79d7fc2b630e": { + "balance": "5910000000000000000000" + }, + "833db42c14163c7be4cab86ac593e06266d699d5": { + "balance": "174212000000000000000000" + }, + "f32d25eb0ea2b8b3028a4c7a155dc1aae865784d": { + "balance": "5710684000000000000000" + }, + "1fa2319fed8c2d462adf2e17feec6a6f30516e95": { + "balance": "125300000000000000000" + }, + "c49cfaa967f3afbf55031061fc4cef88f85da584": { + "balance": "2000000000000000000000" + }, + "43db7ff95a086d28ebbfb82fb8fb5f230a5ebccd": { + "balance": "16100000000000000000" + }, + "cf3f9128b07203a3e10d7d5755c0c4abc6e2cac2": { + "balance": "5000000000000000000000" + }, + "8f4d1e7e4561284a34fef9673c0d34e12af4aa03": { + "balance": "2000000000000000000000" + }, + "934af21b7ebfa467e2ced65aa34edd3a0ec71332": { + "balance": "35420000000000000000000" + }, + "5d231a70c1dfeb360abd97f616e2d10d39f3cab5": { + "balance": "400000000000000000000" + }, + "2d5d7335acb0362b47dfa3a8a4d3f5949544d380": { + "balance": "200000000000000000000" + }, + "d1e1f2b9c16c309874dee7fac32675aff129c398": { + "balance": "72800000000000000000" + }, + "a43b6da6cb7aac571dff27f09d39f846f53769b1": { + "balance": "380000000000000000000" + }, + "779274bf1803a336e4d3b00ddd93f2d4f5f4a62e": { + "balance": "1000000000000000000000" + }, + "a644ed922cc237a3e5c4979a995477f36e50bc62": { + "balance": "583900000000000000000" + }, + "ee6c03429969ca1262cb3f0a4a54afa7d348d7f5": { + "balance": "256100000000000000000" + }, + "4f06246b8d4bd29661f43e93762201d286935ab1": { + "balance": "4818730000000000000000" + }, + "e04972a83ca4112bc871c72d4ae1616c2f0728db": { + "balance": "267606000000000000000" + }, + "df098f5e4e3dffa51af237bda8652c4f73ed9ca6": { + "balance": "502000000000000000000" + }, + "dfded2574b27d1613a7d98b715159b0d00baab28": { + "balance": "20000000000000000000000" + }, + "17d931d4c56294dcbe77c8655be4695f006d4a3c": { + "balance": "2000000000000000000000" + }, + "3ccb71aa6880cb0b84012d90e60740ec06acd78f": { + "balance": "2000000000000000000000" + }, + "e57d2995b0ebdf3f3ca6c015eb04260dbb98b7c6": { + "balance": "2000000000000000000000" + }, + "fb3860f4121c432ebdc8ec6a0331b1b709792e90": { + "balance": "600400000000000000000" + }, + "fa00c376e89c05e887817a9dd0748d96f341aa89": { + "balance": "300700000000000000000" + }, + "c7a018f0968a51d1f6603c5c49dc545bcb0ff293": { + "balance": "4000000000000000000000" + }, + "7d73863038ccca22f96affda10496e51e1e6cd48": { + "balance": "20000000000000000000" + }, + "38ea6f5b5a7b88417551b4123dc127dfe9342da6": { + "balance": "400000000000000000000" + }, + "014b7f67b14f5d983d87014f570c8b993b9872b5": { + "balance": "200000000000000000000" + }, + "8ac89bd9b8301e6b0677fa25fcf0f58f0cc7b611": { + "balance": "20000000000000000000" + }, + "7eb4b0185c92b6439a08e7322168cb353c8a774a": { + "balance": "10165988000000000000000" + }, + "d29dc08efbb3d72e263f78ab7610d0226de76b00": { + "balance": "12000000000000000000000" + }, + "72a8260826294726a75bf39cd9aa9e07a3ea14cd": { + "balance": "2000000000000000000000" + }, + "4cb5c6cd713ca447b848ae2f56b761ca14d7ad57": { + "balance": "267400000000000000000" + }, + "49185dd7c23632f46c759473ebae966008cd3598": { + "balance": "254030000000000000000" + }, + "13d67a7e25f2b12cdb85585009f8acc49b967301": { + "balance": "1999944000000000000000" + }, + "9d913b5d339c95d87745562563fea98b23c60cc4": { + "balance": "170718000000000000000" + }, + "abdc9f1bcf4d19ee96591030e772c334302f7d83": { + "balance": "40110000000000000000000" + }, + "e9a5ae3c9e05977dd1069e9fd9d3aefbae04b8df": { + "balance": "1970000000000000000000" + }, + "1fd296be03ad737c92f9c6869e8d80a71c5714aa": { + "balance": "13370000000000000000" + }, + "2f13657526b177cad547c3908c840eff647b45d9": { + "balance": "1170685000000000000000" + }, + "e69fcc26ed225f7b2e379834c524d70c1735e5bc": { + "balance": "2000000000000000000000" + }, + "bade43599e02f84f4c3014571c976b13a36c65ab": { + "balance": "4000000000000000000000" + }, + "184a4f0beb71ffd558a6b6e8f228b78796c4cf3e": { + "balance": "12000000000000000000000" + }, + "d1de5aad3a5fd803f1b1aeb6103cb8e14fe723b7": { + "balance": "20000000000000000000" + }, + "0bd67dbde07a856ebd893b5edc4f3a5be4202616": { + "balance": "2000000000000000000000" + }, + "6b30f1823910b86d3acb5a6afc9defb6f3a30bf8": { + "balance": "4200000000000000000000" + }, + "9a63d185a79129fdab19b58bb631ea36a420544e": { + "balance": "42000000000000000000" + }, + "df660a91dab9f730f6190d50c8390561500756ca": { + "balance": "2000000000000000000000" + }, + "a1a1f0fa6d20b50a794f02ef52085c9d036aa6ca": { + "balance": "1000000000000000000000" + }, + "4ec768295eeabafc42958415e22be216cde77618": { + "balance": "59600000000000000000" + }, + "c348fc5a461323b57be303cb89361b991913df28": { + "balance": "100000000000000000000000" + }, + "3a7db224acae17de7798797d82cdf8253017dfa8": { + "balance": "5000000000000000000000" + }, + "8bea40379347a5c891d59a6363315640f5a7e07a": { + "balance": "1999992000000000000000" + }, + "2257fca16a6e5c2a647c3c29f36ce229ab93b17e": { + "balance": "4000000000000000000000" + }, + "e492818aa684e5a676561b725d42f3cc56ae5198": { + "balance": "800000000000000000000" + }, + "c841884fa4785fb773b28e9715fae99a5134305d": { + "balance": "2000000000000000000000" + }, + "0d9443a79468a5bbf7c13c6e225d1de91aee07df": { + "balance": "70000000000000000000" + }, + "6d4008b4a888a826f248ee6a0b0dfde9f93210b9": { + "balance": "5460000000000000000000" + }, + "884980eb4565c1048317a8f47fdbb461965be481": { + "balance": "3999922000000000000000" + }, + "985d70d207892bed398590024e2421b1cc119359": { + "balance": "20000000000000000000000" + }, + "d9ec8fe69b7716c0865af888a11b2b12f720ed33": { + "balance": "4000000000000000000000" + }, + "49b74e169265f01a89ec4c9072c5a4cd72e4e835": { + "balance": "16100000000000000000000" + }, + "4c3e95cc3957d252ce0bf0c87d5b4f2234672e70": { + "balance": "2500000000000000000000" + }, + "d9ff115d01266c9f73b063c1c238ef3565e63b36": { + "balance": "680000000000000000000" + }, + "48c5c6970b9161bb1c7b7adfed9cdede8a1ba864": { + "balance": "4000000000000000000000" + }, + "ea6afe2cc928ac8391eb1e165fc40040e37421e7": { + "balance": "2997569000000000000000" + }, + "08ccda50e4b26a0ffc0ef92e9205310706bec2c7": { + "balance": "6077440000000000000000" + }, + "e6e9a39d750fe994394eb68286e5ea62a6997882": { + "balance": "600000000000000000000" + }, + "4b58101f44f7e389e12d471d1635b71614fdd605": { + "balance": "160000000000000000000" + }, + "8d93dac785f88f1a84bf927d53652b45a154ccdd": { + "balance": "158000000000000000000" + }, + "415d096ab06293183f3c033d25f6cf7178ac3bc7": { + "balance": "40000000000000000000" + }, + "c3e387b03ce95ccfd7fa51dd840183bc43532809": { + "balance": "2000000000000000000000" + }, + "da34b2eae30bafe8daeccde819a794cd89e09549": { + "balance": "2000000000000000000000" + }, + "fa279bfd8767f956bf7fa0bd5660168da75686bd": { + "balance": "2674000000000000000000" + }, + "b98ca31785ef06be49a1e47e864f60d076ca472e": { + "balance": "4000000000000000000000" + }, + "b768b5234eba3a9968b34d6ddb481c8419b3655d": { + "balance": "14974000000000000000" + }, + "31047d703f63b93424fbbd6e2f1f9e74de13e709": { + "balance": "2850123000000000000000" + }, + "9a24ce8d485cc4c86e49deb39022f92c7430e67e": { + "balance": "1300000000000000000000" + }, + "e62f9d7c64e8e2635aeb883dd73ba684ee7c1079": { + "balance": "8000000000000000000000" + }, + "f15d9d5a21b1929e790371a17f16d95f0c69655c": { + "balance": "2000000000000000000000" + }, + "285ae51b9500c58d541365d97569f14bb2a3709b": { + "balance": "2000000000000000000000" + }, + "09c177f1ae442411ddacf187d46db956148360e7": { + "balance": "8950000000000000000000" + }, + "12173074980153aeaa4b0dcbc7132eadcec21b64": { + "balance": "240000000000000000000" + }, + "351f16e5e0735af56751b0e225b2421171394090": { + "balance": "13370000000000000000000" + }, + "ac52b77e15664814f39e4f271be641308d91d6cc": { + "balance": "220000000000000000000" + }, + "99c883258546cc7e4e971f522e389918da5ea63a": { + "balance": "4000000000000000000000" + }, + "aa16269aac9c0d803068d82fc79151dadd334b66": { + "balance": "4000000000000000000000" + }, + "7c9a110cb11f2598b2b20e2ca400325e41e9db33": { + "balance": "26000000000000000000000" + }, + "583e83ba55e67e13e0e76f8392d873cd21fbf798": { + "balance": "20000000000000000000" + }, + "555ebe84daa42ba256ea789105cec4b693f12f18": { + "balance": "100000000000000000000" + }, + "978c430ce4359b06bc2cdf5c2985fc950e50d5c8": { + "balance": "480000000000000000000" + }, + "dc1eb9b6e64351f56424509645f83e79eee76cf4": { + "balance": "4000000000000000000000" + }, + "5b290c01967c812e4dc4c90b174c1b4015bae71e": { + "balance": "149946000000000000000" + }, + "e7d213947fcb904ad738480b1eed2f5c329f27e8": { + "balance": "18718000000000000000" + }, + "c517d0315c878813c717e18cafa1eab2654e01da": { + "balance": "10000000000000000000000" + }, + "7e972a8a7c2a44c93b21436c38d21b9252c345fe": { + "balance": "1790000000000000000000" + }, + "9cb28ac1a20a106f7f373692c5ce4c73f13732a1": { + "balance": "1000000000000000000000" + }, + "14ab164b3b524c82d6abfbc0de831126ae8d1375": { + "balance": "2000000000000000000000" + }, + "d46f8223452982a1eea019a8816efc2d6fc00768": { + "balance": "137000000000000000000" + }, + "5cdc4708f14f40dcc15a795f7dc8cb0b7faa9e6e": { + "balance": "537000000000000000000" + }, + "66fdc9fee351fa1538eb0d87d819fcf09e7c106a": { + "balance": "6016500000000000000000" + }, + "e7be82c6593c1eeddd2ae0b15001ff201ab57b2f": { + "balance": "19100000000000000000" + }, + "47d20e6ae4cad3f829eac07e5ac97b66fdd56cf5": { + "balance": "1000000000000000000000" + }, + "0f2d8daf04b5414a0261f549ff6477b80f2f1d07": { + "balance": "200000000000000000000000" + }, + "84bfcef0491a0ae0694b37ceac024584f2aa0467": { + "balance": "1999944000000000000000" + }, + "ec5feafe210c12bfc9a5d05925a123f1e73fbef8": { + "balance": "456000000000000000000000" + }, + "7023c70956e04a92d70025aad297b539af355869": { + "balance": "2000000000000000000000" + }, + "d66ddf1159cf22fd8c7a4bc8d5807756d433c43e": { + "balance": "2200000000000000000000" + }, + "d0638ea57189a6a699024ad78c71d939c1c2ff8c": { + "balance": "2632000000000000000000" + }, + "70d25ed2c8ada59c088cf70dd22bf2db93acc18a": { + "balance": "1056600000000000000000" + }, + "a4875928458ec2005dbb578c5cd33580f0cf1452": { + "balance": "1000000000000000000000" + }, + "b5ad5157dda921e6bafacd9086ae73ae1f611d3f": { + "balance": "2000000000000000000000" + }, + "c493489e56c3bdd829007dc2f956412906f76bfa": { + "balance": "48968000000000000000" + }, + "c57612de91110c482e6f505bcd23f3c5047d1d61": { + "balance": "3580000000000000000000" + }, + "9b18478655a4851cc906e660feac61f7f4c8bffc": { + "balance": "4174120000000000000000" + }, + "b21b7979bf7c5ca01fa82dd640b41c39e6c6bc75": { + "balance": "1999944000000000000000" + }, + "a9d4a2bcbe5b9e0869d70f0fe2e1d6aacd45edc5": { + "balance": "198800000000000000000" + }, + "6f29bb375be5ed34ed999bb830ee2957dde76d16": { + "balance": "2000000000000000000000" + }, + "a006268446643ec5e81e7acb3f17f1c351ee2ed9": { + "balance": "4000000000000000000000" + }, + "42ddd014dc52bfbcc555325a40b516f4866a1dd3": { + "balance": "2000000000000000000000" + }, + "d6d6776958ee23143a81adadeb08382009e996c2": { + "balance": "3000000000000000000000" + }, + "d34e03d36a2bd4d19a5fa16218d1d61e3ffa0b15": { + "balance": "320000000000000000000" + }, + "dac0c177f11c5c3e3e78f2efd663d13221488574": { + "balance": "1000000000000000000000" + }, + "814135da8f9811075783bf1ab67062af8d3e9f40": { + "balance": "20000000000000000000" + }, + "7c3eb713c4c9e0381cd8154c7c9a7db8645cde17": { + "balance": "200000000000000000000" + }, + "f49c47b3efd86b6e6a5bc9418d1f9fec814b69ef": { + "balance": "20000000000000000000000" + }, + "35f1da127b83376f1b88c82a3359f67a5e67dd50": { + "balance": "1910000000000000000000" + }, + "44dfba50b829becc5f4f14d1b04aab3320a295e5": { + "balance": "1000000000000000000000" + }, + "0b924df007e9c0878417cfe63b976ea1a382a897": { + "balance": "40000000000000000000" + }, + "82438fd2b32a9bdd674b49d8cc5fa2eff9781847": { + "balance": "20000000000000000000" + }, + "794529d09d017271359730027075b87ad83dae6e": { + "balance": "310000000000000000000" + }, + "f4b49100757772f33c177b9a76ba95226c8f3dd8": { + "balance": "6700000000000000000000" + }, + "8563c49361b625e768771c96151dbfbd1c906976": { + "balance": "2000000000000000000000" + }, + "0b9df80fbe232009dacf0aa8cac59376e2476203": { + "balance": "2000000000000000000000" + }, + "149b6dbde632c19f5af47cb493114bebd9b03c1f": { + "balance": "12000000000000000000000" + }, + "d7a1431ee453d1e49a0550d1256879b4f5d10201": { + "balance": "1670000000000000000000" + }, + "1d37616b793f94911838ac8e19ee9449df921ec4": { + "balance": "1500000000000000000000" + }, + "d6670c036df754be43dadd8f50feea289d061fd6": { + "balance": "5988459000000000000000" + }, + "02778e390fa17510a3428af2870c4273547d386c": { + "balance": "16163700000000000000000" + }, + "b89f4632df5909e58b2a9964f74feb9a3b01e0c5": { + "balance": "21406707000000000000000" + }, + "76c27535bcb59ce1fa2d8c919cabeb4a6bba01d1": { + "balance": "2000000000000000000000" + }, + "36bf43ff35df90908824336c9b31ce33067e2f50": { + "balance": "346837200000000000000000" + }, + "b53bcb174c2518348b818aece020364596466ba3": { + "balance": "2000000000000000000000" + }, + "b4dd460cd016725a64b22ea4f8e06e06674e033e": { + "balance": "5370000000000000000000" + }, + "cda1741109c0265b3fb2bf8d5ec9c2b8a3346b63": { + "balance": "20000000000000000000" + }, + "feb8b8e2af716ae41fc7c04bcf29540156461e6b": { + "balance": "1555396000000000000000" + }, + "a49f523aa51364cbc7d995163d34eb590ded2f08": { + "balance": "2659160000000000000000" + }, + "a7e74f0bdb278ff0a805a648618ec52b166ff1be": { + "balance": "100000000000000000000" + }, + "5ead29037a12896478b1296ab714e9cb95428c81": { + "balance": "71500000000000000000" + }, + "cdecf5675433cdb0c2e55a68db5d8bbe78419dd2": { + "balance": "20000000000000000000" + }, + "c24ccebc2344cce56417fb684cf81613f0f4b9bd": { + "balance": "1550000000000000000000" + }, + "5a70106f20d63f875265e48e0d35f00e17d02bc9": { + "balance": "20000000000000000000" + }, + "2606c3b3b4ca1b091498602cb1978bf3b95221c0": { + "balance": "400000000000000000000" + }, + "1ad4563ea5786be1159935abb0f1d5879c3e7372": { + "balance": "6000000000000000000000" + }, + "b782bfd1e2de70f467646f9bc09ea5b1fcf450af": { + "balance": "267400000000000000000" + }, + "649a2b9879cd8fb736e6703b0c7747849796f10f": { + "balance": "7358102000000000000000" + }, + "1cc1d3c14f0fb8640e36724dc43229d2ea7a1e48": { + "balance": "1700000000000000000000" + }, + "824b3c3c443e19295d7ef6faa7f374a4798486a8": { + "balance": "20000000000000000000" + }, + "a7758cecb60e8f614cce96137ef72b4fbd07774a": { + "balance": "500000000000000000000" + }, + "981f712775c0dad97518ffedcb47b9ad1d6c2762": { + "balance": "6685000000000000000000" + }, + "26e801b62c827191dd68d31a011990947fd0ebe0": { + "balance": "20000000000000000000" + }, + "95447046313b2f3a5e19b948fd3b8bedc82c717c": { + "balance": "500000000000000000000" + }, + "0b701101a4109f9cb360dc57b77442673d5e5983": { + "balance": "2000000000000000000000" + }, + "5b25cae86dcafa2a60e7723631fc5fa49c1ad87d": { + "balance": "2491200000000000000000" + }, + "f73ac46c203be1538111b151ec8220c786d84144": { + "balance": "294515000000000000000" + }, + "e8c3d3b0e17f97d1e756e684f94e1470f99c95a1": { + "balance": "400000000000000000000" + }, + "8c900a8236b08c2b65405d39d75f20062a7561fd": { + "balance": "1640000000000000000000" + }, + "43898c49a34d509bfed4f76041ee91caf3aa6aa5": { + "balance": "300000000000000000000" + }, + "c85325eab2a59b3ed863c86a5f2906a04229ffa9": { + "balance": "465600000000000000000" + }, + "4a430170152de5172633dd8262d107a0afd96a0f": { + "balance": "3160000000000000000000" + }, + "6e0ee70612c976287d499ddfa6c0dcc12c06deea": { + "balance": "129980000000000000000" + }, + "21c07380484f6cbc8724ad32bc864c3b5ad500b7": { + "balance": "1000000000000000000000" + }, + "ff5162f2354dc492c75fd6e3a107268660eecb47": { + "balance": "1700000000000000000000" + }, + "8845e9f90e96336bac3c616be9d88402683e004c": { + "balance": "2000000000000000000000" + }, + "f23c7b0cb8cd59b82bd890644a57daf40c85e278": { + "balance": "50038000000000000000" + }, + "1784948bf99848c89e445638504dd698271b5924": { + "balance": "6037580000000000000000" + }, + "b39f4c00b2630cab7db7295ef43d47d501e17fd7": { + "balance": "4000000000000000000000" + }, + "3fb7d197b3ba4fe045efc23d50a14585f558d9b2": { + "balance": "20000000000000000000" + }, + "bd043b67c63e60f841ccca15b129cdfe6590c8e3": { + "balance": "200000000000000000000" + }, + "86ca0145957e6b0dfe36875fbe7a0dec55e17a28": { + "balance": "10000000000000000000000" + }, + "dae7201eab8c063302930d693929d07f95e71962": { + "balance": "2687370000000000000000" + }, + "cc034985d3f28c2d39b1a34bced4d3b2b6ca234e": { + "balance": "182000000000000000000" + }, + "40e0dbf3efef9084ea1cd7e503f40b3b4a8443f6": { + "balance": "4000000000000000000000" + }, + "b1896a37e5d8825a2d01765ae5de629977de8352": { + "balance": "200000000000000000000" + }, + "d9f547f2c1de0ed98a53d161df57635dd21a00bd": { + "balance": "98500000000000000000" + }, + "2fea1b2f834f02fc54333f8a809f0438e5870aa9": { + "balance": "20200000000000000000" + }, + "68b31836a30a016ada157b638ac15da73f18cfde": { + "balance": "26000000000000000000" + }, + "bc967fe4418c18b99858966d870678dca2b88879": { + "balance": "8740000000000000000000" + }, + "16bae5d24eff91778cd98b4d3a1cc3162f44aa77": { + "balance": "401100000000000000000" + }, + "f476e1267f86247cc908816f2e7ad5388c952db0": { + "balance": "4000000000000000000000" + }, + "0203ae01d4c41cae1865e04b1f5b53cdfaecae31": { + "balance": "1006054000000000000000" + }, + "bd4bd5b122d8ef7b7c8f0667450320db2116142e": { + "balance": "600000000000000000000" + }, + "a394ad4fd9e6530e6f5c53faecbede81cb172da1": { + "balance": "5600000000000000000000" + }, + "3a9960266df6492063538a99f487c950a3a5ec9e": { + "balance": "24000000000000000000000" + }, + "d8069f84b521493f4715037f3226b25f33b60586": { + "balance": "1910000000000000000000" + }, + "136c834bf111326d207395295b2e583ea7f33572": { + "balance": "100000000000000000000" + }, + "c5c73d61cce7c8fe4c8fce29f39092cd193e0fff": { + "balance": "8000000000000000000000" + }, + "3cfbf066565970639e130df2a7d16b0e14d6091c": { + "balance": "1700000000000000000000" + }, + "61b905de663fc17386523b3a28e2f7d037a655cd": { + "balance": "500000000000000000000" + }, + "fda0ce15330707f10bce3201172d2018b9ddea74": { + "balance": "51900000000000000000" + }, + "f7fc45abf76f5088e2e5b5a8d132f28a4d4ec1c0": { + "balance": "2000000000000000000000" + }, + "c3db9fb6f46c480af34465d79753b4e2b74a67ce": { + "balance": "20000000000000000000000" + }, + "ebe46cc3c34c32f5add6c3195bb486c4713eb918": { + "balance": "1000000000000000000000" + }, + "91d2a9ee1a6db20f5317cca7fbe2313895db8ef8": { + "balance": "8499600000000000000000" + }, + "c4cc45a2b63c27c0b4429e58cd42da59be739bd6": { + "balance": "1000000000000000000000" + }, + "a43b81f99356c0af141a03010d77bd042c71c1ee": { + "balance": "2000000000000000000000" + }, + "4c45d4c9a725d11112bfcbca00bf31186ccaadb7": { + "balance": "400000000000000000000" + }, + "bf9f271f7a7e12e36dd2fe9facebf385fe6142bd": { + "balance": "62760000000000000000" + }, + "e0ce80a461b648a501fd0b824690c8868b0e4de8": { + "balance": "500000000000000000000" + }, + "a1f7dde1d738d8cd679ea1ee965bee224be7d04d": { + "balance": "1127000000000000000000" + }, + "7f1c81ee1697fc144b7c0be5493b5615ae7fddca": { + "balance": "500200000000000000000" + }, + "b508f987b2de34ae4cf193de85bff61389621f88": { + "balance": "6000000000000000000000" + }, + "5f26cf34599bc36ea67b9e7a9f9b4330c9d542a3": { + "balance": "1000000000000000000000" + }, + "d02108d2ae3cab10cbcf1657af223e027c8210f6": { + "balance": "2000140000000000000000" + }, + "952183cfd38e352e579d36decec5b18450f7fba0": { + "balance": "2000000000000000000000" + }, + "eb90c793b3539761e1c814a29671148692193eb4": { + "balance": "12000000000000000000000" + }, + "1076212d4f758c8ec7121c1c7d74254926459284": { + "balance": "35000056000000000000000" + }, + "f05ceeab65410564709951773c8445ad9f4ec797": { + "balance": "299982000000000000000" + }, + "05361d8eb6941d4e90fb7e1418a95a32d5257732": { + "balance": "20000000000000000000" + }, + "a5783bf33432ff82ac498985d7d460ae67ec3673": { + "balance": "1820000000000000000000" + }, + "b1cd4bdfd104489a026ec99d597307a04279f173": { + "balance": "20000000000000000000000" + }, + "876c3f218b4776df3ca9dbfb270de152d94ed252": { + "balance": "100000000000000000000" + }, + "8a36869ad478997cbf6d8924d20a3c8018e9855b": { + "balance": "20000000000000000000" + }, + "fb3fe09bb836861529d7518da27635f538505615": { + "balance": "1399904000000000000000" + }, + "d093e829819fd2e25b973800bb3d5841dd152d05": { + "balance": "4000000000000000000000" + }, + "126d91f7ad86debb0557c612ca276eb7f96d00a1": { + "balance": "100000000000000000000" + }, + "2a81d27cb6d4770ff4f3c4a3ba18e5e57f07517c": { + "balance": "2000000000000000000000" + }, + "c4f7b13ac6d4eb4db3d4e6a252af8a07bd5957da": { + "balance": "200000000000000000000" + }, + "305d26c10bdc103f6b9c21272eb7cb2d9108c47e": { + "balance": "500000000000000000000" + }, + "d0d0a2ad45f59a9dccc695d85f25ca46ed31a5a3": { + "balance": "840000000000000000000" + }, + "522323aad71dbc96d85af90f084b99c3f09decb7": { + "balance": "6000000000000000000000" + }, + "f43da3a4e3f5fab104ca9bc1a0f7f3bb4a56f351": { + "balance": "1999944000000000000000" + }, + "a2dc65ee256b59a5bd7929774f904b358df3ada1": { + "balance": "21319600000000000000000" + }, + "f382df583155d8548f3f93440cd5f68cb79d6026": { + "balance": "266619800000000000000000" + }, + "0c967e3061b87a753e84507eb60986782c8f3013": { + "balance": "100000000000000000000" + }, + "a3a262afd2936819230892fde84f2d5a594ab283": { + "balance": "1880000000000000000000" + }, + "93868ddb2a794d02ebda2fa4807c76e3609858dc": { + "balance": "2027851000000000000000" + }, + "cd35ff010ec501a721a1b2f07a9ca5877dfcf95a": { + "balance": "4011000000000000000000" + }, + "5824a7e22838277134308c5f4b50dab65e43bb31": { + "balance": "6000000000000000000000" + }, + "7f7a3a21b3f5a65d81e0fcb7d52dd00a1aa36dba": { + "balance": "100000000000000000000" + }, + "30513fca9f36fd788cfea7a340e86df98294a244": { + "balance": "447000000000000000000" + }, + "283e6252b4efcf4654391acb75f903c59b78c5fb": { + "balance": "12000000000000000000000" + }, + "eddbaafbc21be8f25562f1ed6d05d6afb58f02c2": { + "balance": "2000000000000000000000" + }, + "0dcfe837ea1cf28c65fccec3bef1f84e59d150c0": { + "balance": "200000000000000000000" + }, + "828ba651cb930ed9787156299a3de44cd08b7212": { + "balance": "1337000000000000000000" + }, + "cfd47493c9f89fe680bda5754dd7c9cfe7cb5bbe": { + "balance": "54508000000000000000" + }, + "0e89eddd3fa0d71d8ab0ff8da5580686e3d4f74f": { + "balance": "2000000000000000000000" + }, + "205f5166f12440d85762c967d3ae86184f8f4d98": { + "balance": "432500000000000000000" + }, + "25dad495a11a86b9eeece1eeec805e57f157faff": { + "balance": "16000000000000000000000" + }, + "6c84cba77c6db4f7f90ef13d5ee21e8cfc7f8314": { + "balance": "2000000000000000000000" + }, + "91a787bc5196f34857fe0c372f4df376aaa76613": { + "balance": "2000000000000000000000" + }, + "b0d3c9872b85056ea0c0e6d1ecf7a77e3ce6ab85": { + "balance": "4999711000000000000000" + }, + "6e4d2e39c8836629e5b487b1918a669aebdd9536": { + "balance": "1000000000000000000000" + }, + "dc703a5f3794c84d6cb3544918cae14a35c3bd4f": { + "balance": "1850000000000000000000" + }, + "47beb20f759100542aa93d41118b3211d664920e": { + "balance": "2000000000000000000000" + }, + "5a7735007d70b06844da9901cdfadb11a2582c2f": { + "balance": "6000000000000000000000" + }, + "aff107960b7ec34ed690b665024d60838c190f70": { + "balance": "500000000000000000000" + }, + "563a03ab9c56b600f6d25b660c21e16335517a75": { + "balance": "1000000000000000000000" + }, + "a106465bbd19e1b6bce50d1b1157dc59095a3630": { + "balance": "2000000000000000000000" + }, + "ca9dec02841adf5cc920576a5187edd2bd434a18": { + "balance": "500000000000000000000" + }, + "572ac1aba0de23ae41a7cae1dc0842d8abfc103b": { + "balance": "1910000000000000000000" + }, + "5f74ed0e24ff80d9b2c4a44baa9975428cd6b935": { + "balance": "2980000000000000000000" + }, + "f2049532fd458a83ca1bff2eebacb6d5ca63f4a4": { + "balance": "3625693000000000000000" + }, + "cee699c0707a7836252b292f047ce8ad289b2f55": { + "balance": "324700000000000000000" + }, + "8b3696f3c60de32432a2e4c395ef0303b7e81e75": { + "balance": "30000000000000000000000" + }, + "13dee03e3799952d0738843d4be8fc0a803fb20e": { + "balance": "2000000000000000000000" + }, + "c853215b9b9f2d2cd0741e585e987b5fb80c212e": { + "balance": "1550000000000000000000" + }, + "851c0d62be4635d4777e8035e37e4ba8517c6132": { + "balance": "500000000000000000000" + }, + "a76b743f981b693072a131b22ba510965c2fefd7": { + "balance": "18200000000000000000" + }, + "69bd25ade1a3346c59c4e930db2a9d715ef0a27a": { + "balance": "4000000000000000000000" + }, + "0fec4ee0d7ca180290b6bd20f9992342f60ff68d": { + "balance": "334383000000000000000" + }, + "ccfd725760a68823ff1e062f4cc97e1360e8d997": { + "balance": "399800000000000000000" + }, + "9f017706b830fb9c30efb0a09f506b9157457534": { + "balance": "2000000000000000000000" + }, + "420fb86e7d2b51401fc5e8c72015decb4ef8fc2e": { + "balance": "1000000000000000000000" + }, + "cb7d2b8089e9312cc9aeaa2773f35308ec6c2a7b": { + "balance": "10000000000000000000000" + }, + "6c822029218ac8e98a260c1e064029348839875b": { + "balance": "5010000000000000000000" + }, + "1c68a66138783a63c98cc675a9ec77af4598d35e": { + "balance": "50100000000000000000" + }, + "f270792576f05d514493ffd1f5e84bec4b2df810": { + "balance": "1000000000000000000000" + }, + "9191f94698210516cf6321a142070e20597674ed": { + "balance": "17194000000000000000" + }, + "c0ca3277942e7445874be31ceb902972714f1823": { + "balance": "250000000000000000000" + }, + "35e096120deaa5c1ecb1645e2ccb8b4edbd9299a": { + "balance": "500000000000000000000" + }, + "e2bbf84641e3541f6c33e6ed683a635a70bde2ec": { + "balance": "502763000000000000000" + }, + "d12d77ae01a92d35117bac705aacd982d02e74c1": { + "balance": "1000000000000000000000" + }, + "dabb0889fc042926b05ef57b2520910abc4b4149": { + "balance": "2000000000000000000000" + }, + "5a1a336962d6e0c63031cc83c6a5c6a6f4478ecb": { + "balance": "1000000000000000000000" + }, + "abd154903513b8da4f019f68284b0656a1d0169b": { + "balance": "1000000000000000000000" + }, + "ad377cd25eb53e83ae091a0a1d2b4516f484afde": { + "balance": "1940000000000000000000" + }, + "08c2f236ac4adcd3fda9fbc6e4532253f9da3bec": { + "balance": "20000000000000000000" + }, + "71135d8f05963c905a4a07922909235a896a52ea": { + "balance": "3000000000000000000000" + }, + "080546508a3d2682c8b9884f13637b8847b44db3": { + "balance": "2000000000000000000000" + }, + "2d61bfc56873923c2b00095dc3eaa0f590d8ae0f": { + "balance": "20760000000000000000000" + }, + "cbfa6af6c283b046e2772c6063b0b21553c40106": { + "balance": "2000000000000000000000" + }, + "ccabc6048a53464424fcf76eeb9e6e1801fa23d4": { + "balance": "49250000000000000000" + }, + "60cc3d445ebdf76a7d7ae571c6971dff68cc8585": { + "balance": "1000000000000000000000" + }, + "fff33a3bd36abdbd412707b8e310d6011454a7ae": { + "balance": "8000000000000000000000" + }, + "d2dbebe89b0357aea98bbe8e496338debb28e805": { + "balance": "4000000000000000000000" + }, + "5f521282e9b278dc8c034c72af53ee29e5443d78": { + "balance": "6520000000000000000000" + }, + "c5a48a8500f9b4e22f0eb16c6f4649687674267d": { + "balance": "812721000000000000000" + }, + "8cb3aa3fcd212854d7578fcc30fdede6742a312a": { + "balance": "300000000000000000000" + }, + "90d2809ae1d1ffd8f63eda01de49dd552df3d1bc": { + "balance": "3998000000000000000000" + }, + "96a55f00dff405dc4de5e58c57f6f6f0cac55d2f": { + "balance": "1962711000000000000000" + }, + "ae842e81858ecfedf6506c686dc204ac15bf8b24": { + "balance": "40000000000000000000" + }, + "0be6a09e4307fe48d412b8d1a1a8284dce486261": { + "balance": "19180000000000000000000" + }, + "c9c7ac0bdd9342b5ead4360923f68c72a6ba633a": { + "balance": "500000000000000000000" + }, + "ea8f30b6e4c5e65290fb9864259bc5990fa8ee8a": { + "balance": "20000000000000000000" + }, + "74d37a51747bf8b771bfbf43943933d100d21483": { + "balance": "1000000000000000000000" + }, + "1a04d5389eb006f9ce880c30d15353f8d11c4b31": { + "balance": "17072800000000000000000" + }, + "726a14c90e3f84144c765cffacba3e0df11b48be": { + "balance": "10000000000000000000000" + }, + "86b7bd563ceab686f96244f9ddc02ad7b0b14bc2": { + "balance": "10000000000000000000000" + }, + "2bbe672a1857508f630f2a5edb563d9e9de92815": { + "balance": "2000000000000000000000" + }, + "a17070c2e9c5a940a4ec0e4954c4d7d643be8f49": { + "balance": "1999965000000000000000" + }, + "f2d1b7357724ec4c03185b879b63f57e26589153": { + "balance": "6000000000000000000000" + }, + "d6a7ac4de7b510f0e8de519d973fa4c01ba83400": { + "balance": "1880000000000000000000" + }, + "593b45a1864ac5c7e8f0caaeba0d873cd5d113b2": { + "balance": "6000000000000000000000" + }, + "0837539b5f6a522a482cdcd3a9bb7043af39bdd2": { + "balance": "6000000000000000000000" + }, + "b927abd2d28aaaa24db31778d27419df8e1b04bb": { + "balance": "27531000000000000000" + }, + "b2e085fddd1468ba07415b274e734e11237fb2a9": { + "balance": "100000000000000000000" + }, + "970938522afb5e8f994873c9fbdc26e3b37e314c": { + "balance": "1000000000000000000000" + }, + "f3de5f26ef6aded6f06d3b911346ee70401da4a0": { + "balance": "354718000000000000000" + }, + "bffb6929241f788693273e7022e60e3eab1fe84f": { + "balance": "2000000000000000000000" + }, + "b56ad2aec6c8c3f19e1515bbb7dd91285256b639": { + "balance": "1000000000000000000000" + }, + "47730f5f8ebf89ac72ef80e46c12195038ecdc49": { + "balance": "3160000000000000000000" + }, + "f39a9d7aa3581df07ee4279ae6c312ef21033658": { + "balance": "4000000000000000000000" + }, + "36227cdfa0fd3b9d7e6a744685f5be9aa366a7f0": { + "balance": "198479000000000000000" + }, + "89e3b59a15864737d493c1d23cc53dbf8dcb1362": { + "balance": "4000000000000000000000" + }, + "bd08e0cddec097db7901ea819a3d1fd9de8951a2": { + "balance": "20000000000000000000" + }, + "533444584082eba654e1ad30e149735c6f7ba922": { + "balance": "1730000000000000000000" + }, + "6a8a4317c45faa0554ccdb482548183e295a24b9": { + "balance": "1000000000000000000000" + }, + "22ce349159eeb144ef06ff2636588aef79f62832": { + "balance": "188000000000000000000" + }, + "3cd1d9731bd548c1dd6fcea61beb75d91754f7d3": { + "balance": "5130285000000000000000" + }, + "8b7056f6abf3b118d026e944d5c073433ca451d7": { + "balance": "999999000000000000000" + }, + "15f1b352110d68901d8f67aac46a6cfafe031477": { + "balance": "200000000000000000000" + }, + "0f789e30397c53bf256fc364e6ef39f853504114": { + "balance": "3640000000000000000000" + }, + "750bbb8c06bbbf240843cc75782ee02f08a97453": { + "balance": "835000000000000000000" + }, + "fff7ac99c8e4feb60c9750054bdc14ce1857f181": { + "balance": "1000000000000000000000" + }, + "5c6f36af90ab1a656c6ec8c7d521512762bba3e1": { + "balance": "1999800000000000000000" + }, + "6811b54cd19663b11b94da1de2448285cd9f68d9": { + "balance": "1100000000000000000000" + }, + "6f50929777824c291a49c46dc854f379a6bea080": { + "balance": "360000000000000000000" + }, + "e83604e4ff6be7f96f6018d3ec3072ec525dff6b": { + "balance": "182000000000000000000" + }, + "d731bb6b5f3c37395e09ceaccd14a918a6060789": { + "balance": "3940000000000000000000" + }, + "372e453a6b629f27678cc8aeb5e57ce85ec0aef9": { + "balance": "200000000000000000000" + }, + "86924fb211aad23cf5ce600e0aae806396444087": { + "balance": "10000000000000000000000" + }, + "18c6723a6753299cb914477d04a3bd218df8c775": { + "balance": "1000000000000000000000" + }, + "e00484788db50fc6a48e379d123e508b0f6e5ab1": { + "balance": "1000000000000000000000" + }, + "150e3dbcbcfc84ccf89b73427763a565c23e60d0": { + "balance": "40000000000000000000" + }, + "8ffa062122ac307418821adb9311075a3703bfa3": { + "balance": "1000000000000000000000" + }, + "21206ce22ea480e85940d31314e0d64f4e4d3a04": { + "balance": "1000000000000000000000" + }, + "ac024f594f9558f04943618eb0e6b2ee501dc272": { + "balance": "2000000000000000000000" + }, + "b2b7cdb4ff4b61d5b7ce0b2270bbb5269743ec04": { + "balance": "2000000000000000000000" + }, + "abc74706964960dfe0dca3dca79e9216056f1cf4": { + "balance": "40000000000000000000000" + }, + "d7eb903162271c1afa35fe69e37322c8a4d29b11": { + "balance": "10000000000000000000000" + }, + "d7c6265dea11876c903b718e4cd8ab24fe265bde": { + "balance": "2000000000000000000000" + }, + "cba288cd3c1eb4d59ddb06a6421c14c345a47b24": { + "balance": "4000000000000000000000" + }, + "8c22426055b76f11f0a2de1a7f819a619685fe60": { + "balance": "1980000000000000000000" + }, + "f463a90cb3f13e1f0643423636beab84c123b06d": { + "balance": "40000000000000000000" + }, + "2b5ced9987c0765f900e49cf9da2d9f9c1138855": { + "balance": "400000000000000000000" + }, + "9bb760d5c289a3e1db18db095345ca413b9a43c2": { + "balance": "197000000000000000000" + }, + "d66ab79294074c8b627d842dab41e17dd70c5de5": { + "balance": "1000000000000000000000" + }, + "0bdd58b96e7c916dd2fb30356f2aebfaaf1d8630": { + "balance": "2000000000000000000000" + }, + "d612597bc31743c78633f633f239b1e9426bd925": { + "balance": "76000000000000000000000" + }, + "140518a3194bad1350b8949e650565debe6db315": { + "balance": "2000000000000000000000" + }, + "daedd4ad107b271e89486cbf80ebd621dd974578": { + "balance": "2000000000000000000000" + }, + "c36c0b63bfd75c2f8efb060883d868cccd6cbdb4": { + "balance": "3000000000000000000000" + }, + "e646665872e40b0d7aa2ff82729caaba5bc3e89e": { + "balance": "400000000000000000000" + }, + "b5fb7ea2ddc1598b667a9d57dd39e85a38f35d56": { + "balance": "500000000000000000000" + }, + "e51421f8ee2210c71ed870fe618276c8954afbe9": { + "balance": "1337000000000000000000" + }, + "08a9a44e1f41de3dbba7a363a3ab412c124cd15e": { + "balance": "200000000000000000000" + }, + "562bced38ab2ab6c080f3b0541b8456e70824b3f": { + "balance": "641760000000000000000" + }, + "1e484d0621f0f5331b35d5408d9aae4eb1acf21e": { + "balance": "20000000000000000000" + }, + "3a476bd2c9e664c63ab266aa4c6e4a4825f516c3": { + "balance": "200000000000000000000" + }, + "8d6df209484d7b94702b03a53e56b9fb0660f6f0": { + "balance": "2000000000000000000000" + }, + "5970fb1b144dd751e4ce2eca7caa20e363dc4da3": { + "balance": "10000000000000000000000" + }, + "d1dd79fb158160e5b4e8e23f312e6a907fbc4d4e": { + "balance": "500000000000000000000" + }, + "7ee5ca805dce23af89c2d444e7e40766c54c7404": { + "balance": "240660000000000000000" + }, + "93e0f37ecdfb0086e3e862a97034447b1e4dec1a": { + "balance": "30000000000000000000" + }, + "e10ac19c546fc2547c61c139f5d1f45a6666d5b0": { + "balance": "4775000000000000000000" + }, + "1c73d00b6e25d8eb9c1ff4ad827b6b9e9cf6d20c": { + "balance": "200000000000000000000" + }, + "d771d9e0ca8a08a113775731434eb3270599c40d": { + "balance": "20000000000000000000" + }, + "e69d1c378b771e0feff051db69d966ac6779f4ed": { + "balance": "553000000000000000000" + }, + "0ef85b49d08a75198692914eddb4b22cf5fa4450": { + "balance": "2004800000000000000000" + }, + "ed70a37cdd1cbda9746d939658ae2a6181288578": { + "balance": "9600000000000000000000" + }, + "eee761847e33fd61d99387ee14628694d1bfd525": { + "balance": "2000000000000000000000" + }, + "271d3d481cb88e7671ad216949b6365e06303de0": { + "balance": "4000000000000000000000" + }, + "5255dc69155a45b970c604d30047e2f530690e7f": { + "balance": "20000000000000000000" + }, + "cabab6274ed15089737e287be878b757934864e2": { + "balance": "20000000000000000000000" + }, + "9defe56a0ff1a1947dba0923f7dd258d8f12fa45": { + "balance": "26880000000000000000000" + }, + "b7a2c103728b7305b5ae6e961c94ee99c9fe8e2b": { + "balance": "50000000000000000000000" + }, + "b498bb0f520005b6216a4425b75aa9adc52d622b": { + "balance": "4000000000000000000000" + }, + "c1132878235c5ddba5d9f3228b5236e47020dc6f": { + "balance": "1000000000000000000000" + }, + "f81622e55757daea6675975dd93538da7d16991e": { + "balance": "2000000000000000000000" + }, + "ce2deab51c0a9ae09cd212c4fa4cc52b53cc0dec": { + "balance": "2000000000000000000000" + }, + "86a1eadeeb30461345d9ef6bd05216fa247c0d0c": { + "balance": "2000000000000000000000" + }, + "7b1fe1ab4dfd0088cdd7f60163ef59ec2aee06f5": { + "balance": "2000000000000000000000" + }, + "6bbc3f358a668dd1a11f0380f3f73108426abd4a": { + "balance": "4000000000000000000000" + }, + "b1e6e810c24ab0488de9e01e574837829f7c77d0": { + "balance": "400000000000000000000" + }, + "03eb3cb860f6028da554d344a2bb5a500ae8b86f": { + "balance": "2000000000000000000000" + }, + "e5481a7fed42b901bbed20789bd4ade50d5f83b9": { + "balance": "2000000000000000000000" + }, + "1f3da68fe87eaf43a829ab6d7ec5a6e009b204fb": { + "balance": "554988000000000000000" + }, + "30037988702671acbe892c03fe5788aa98af287a": { + "balance": "2800000000000000000000" + }, + "edb473353979a206879de144c10a3c51d7d7081a": { + "balance": "6000000000000000000000" + }, + "22bdffc240a88ff7431af3bff50e14da37d5183e": { + "balance": "1000000000000000000000" + }, + "9374869d4a9911ee1eaf558bc4c2b63ec63acfdd": { + "balance": "1000000000000000000000" + }, + "b756ad52f3bf74a7d24c67471e0887436936504c": { + "balance": "20000000000000000000000" + }, + "8bd0b65a50ef5cef84fec420be7b89ed1470ceb9": { + "balance": "11999000000000000000000" + }, + "af26f7c6bf453e2078f08953e4b28004a2c1e209": { + "balance": "100000000000000000000" + }, + "7c532db9e0c06c26fd40acc56ac55c1ee92d3c3a": { + "balance": "300000000000000000000000" + }, + "dde670d01639667576a22dd05d3246d61f06e083": { + "balance": "26740000000000000000" + }, + "5cf44e10540d65716423b1bcb542d21ff83a94cd": { + "balance": "10000000000000000000000" + }, + "f96b4c00766f53736a8574f822e6474c2f21da2d": { + "balance": "400000000000000000000" + }, + "8d89170b92b2be2c08d57c48a7b190a2f146720f": { + "balance": "19700000000000000000000" + }, + "142b87c5043ffb5a91df18c2e109ced6fe4a71db": { + "balance": "200000000000000000000" + }, + "42d34940edd2e7005d46e2188e4cfece8311d74d": { + "balance": "158000000000000000000" + }, + "562105e82b099735de49f62692cc87cd38a8edcd": { + "balance": "6000000000000000000000" + }, + "457bcef37dd3d60b2dd019e3fe61d46b3f1e7252": { + "balance": "20000000000000000000" + }, + "cf8882359c0fb23387f5674074d8b17ade512f98": { + "balance": "6000000000000000000000" + }, + "f0c081da52a9ae36642adf5e08205f05c54168a6": { + "balance": "111000000000000000000" + }, + "551e7784778ef8e048e495df49f2614f84a4f1dc": { + "balance": "600000000000000000000" + }, + "3c869c09696523ced824a070414605bb76231ff2": { + "balance": "1000000000000000000000" + }, + "7e7f18a02eccaa5d61ab8fbf030343c434a25ef7": { + "balance": "66850000000000000000" + }, + "9328d55ccb3fce531f199382339f0e576ee840a3": { + "balance": "4000000000000000000000" + }, + "9d0f347e826b7dceaad279060a35c0061ecf334b": { + "balance": "4000000000000000000000" + }, + "680640838bd07a447b168d6d923b90cf6c43cdca": { + "balance": "1730000000000000000000" + }, + "c951900c341abbb3bafbf7ee2029377071dbc36a": { + "balance": "327600000000000000000" + }, + "ddf5810a0eb2fb2e32323bb2c99509ab320f24ac": { + "balance": "17900000000000000000000" + }, + "2489ac126934d4d6a94df08743da7b7691e9798e": { + "balance": "1000000000000000000000" + }, + "f42f905231c770f0a406f2b768877fb49eee0f21": { + "balance": "197000000000000000000" + }, + "756f45e3fa69347a9a973a725e3c98bc4db0b5a0": { + "balance": "200000000000000000000" + } + } +} diff --git a/ethcore/res/ethereum/frontier_like_test.json b/ethcore/res/ethereum/frontier_like_test.json index ca31927e7..78299bf4e 100644 --- a/ethcore/res/ethereum/frontier_like_test.json +++ b/ethcore/res/ethereum/frontier_like_test.json @@ -9,7 +9,8 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", - "frontierCompatibilityModeLimit": "0x118c30" + "frontierCompatibilityModeLimit": "0x118c30", + "daoRescueSoftFork": false } } }, diff --git a/ethcore/res/ethereum/frontier_like_test_dao_rescue.json b/ethcore/res/ethereum/frontier_like_test_dao_rescue.json new file mode 100644 index 000000000..ba0881508 --- /dev/null +++ b/ethcore/res/ethereum/frontier_like_test_dao_rescue.json @@ -0,0 +1,43 @@ +{ + "name": "Frontier (Test)", + "engine": { + "Ethash": { + "params": { + "gasLimitBoundDivisor": "0x0400", + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "frontierCompatibilityModeLimit": "0x118c30", + "daoRescueSoftFork": true + } + } + }, + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x1" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x1388" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } + } +} diff --git a/ethcore/res/ethereum/frontier_test.json b/ethcore/res/ethereum/frontier_test.json index 3964d33ad..d12390eb9 100644 --- a/ethcore/res/ethereum/frontier_test.json +++ b/ethcore/res/ethereum/frontier_test.json @@ -9,7 +9,8 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", - "frontierCompatibilityModeLimit": "0xffffffffffffffff" + "frontierCompatibilityModeLimit": "0xffffffffffffffff", + "daoRescueSoftFork": false } } }, diff --git a/ethcore/res/ethereum/homestead_test.json b/ethcore/res/ethereum/homestead_test.json index a0e3df275..6d38c29c0 100644 --- a/ethcore/res/ethereum/homestead_test.json +++ b/ethcore/res/ethereum/homestead_test.json @@ -9,7 +9,8 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", - "frontierCompatibilityModeLimit": 0 + "frontierCompatibilityModeLimit": 0, + "daoRescueSoftFork": false } } }, diff --git a/ethcore/res/ethereum/homestead_test_dao_rescue.json b/ethcore/res/ethereum/homestead_test_dao_rescue.json new file mode 100644 index 000000000..7dbe4b321 --- /dev/null +++ b/ethcore/res/ethereum/homestead_test_dao_rescue.json @@ -0,0 +1,43 @@ +{ + "name": "Homestead (Test)", + "engine": { + "Ethash": { + "params": { + "gasLimitBoundDivisor": "0x0400", + "minimumDifficulty": "0x020000", + "difficultyBoundDivisor": "0x0800", + "durationLimit": "0x0d", + "blockReward": "0x4563918244F40000", + "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "frontierCompatibilityModeLimit": 0, + "daoRescueSoftFork": true + } + } + }, + "params": { + "accountStartNonce": "0x00", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x1" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x0000000000000042", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000" + } + }, + "difficulty": "0x400000000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa", + "gasLimit": "0x1388" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } } + } +} diff --git a/ethcore/res/ethereum/morden.json b/ethcore/res/ethereum/morden.json index 0cc88ac64..c7836bd91 100644 --- a/ethcore/res/ethereum/morden.json +++ b/ethcore/res/ethereum/morden.json @@ -9,7 +9,8 @@ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "registrar": "", - "frontierCompatibilityModeLimit": "0x789b0" + "frontierCompatibilityModeLimit": "0x789b0", + "daoRescueSoftFork": false } } }, diff --git a/ethcore/res/ethereum/olympic.json b/ethcore/res/ethereum/olympic.json index 1e0c210b5..86dfc15b7 100644 --- a/ethcore/res/ethereum/olympic.json +++ b/ethcore/res/ethereum/olympic.json @@ -9,7 +9,8 @@ "durationLimit": "0x08", "blockReward": "0x14D1120D7B160000", "registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050", - "frontierCompatibilityModeLimit": "0xffffffffffffffff" + "frontierCompatibilityModeLimit": "0xffffffffffffffff", + "daoRescueSoftFork": false } } }, diff --git a/ethcore/res/null.json b/ethcore/res/null.json new file mode 100644 index 000000000..b9b2b1260 --- /dev/null +++ b/ethcore/res/null.json @@ -0,0 +1,33 @@ +{ + "name": "Morden", + "engine": { + "Null": null + }, + "params": { + "accountStartNonce": "0x0", + "maximumExtraDataSize": "0x20", + "minGasLimit": "0x1388", + "networkID" : "0x2" + }, + "genesis": { + "seal": { + "ethereum": { + "nonce": "0x00006d6f7264656e", + "mixHash": "0x00000000000000000000000000000000000000647572616c65787365646c6578" + } + }, + "difficulty": "0x20000", + "author": "0x0000000000000000000000000000000000000000", + "timestamp": "0x00", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "extraData": "0x", + "gasLimit": "0x2fefd8" + }, + "accounts": { + "0000000000000000000000000000000000000001": { "balance": "1", "nonce": "0", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } }, + "0000000000000000000000000000000000000002": { "balance": "1", "nonce": "0", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } }, + "0000000000000000000000000000000000000003": { "balance": "1", "nonce": "0", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } }, + "0000000000000000000000000000000000000004": { "balance": "1", "nonce": "0", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }, + "9cce34f7ab185c7aba1b7c8140d620b4bda941d6": { "balance": "1606938044258990275541962092341162602522202993782792835301376", "nonce": "0" } + } +} diff --git a/ethcore/src/account.rs b/ethcore/src/account.rs index 29922dda5..d0628436d 100644 --- a/ethcore/src/account.rs +++ b/ethcore/src/account.rs @@ -166,16 +166,16 @@ impl Account { !self.code_cache.is_empty() || (self.code_cache.is_empty() && self.code_hash == Some(SHA3_EMPTY)) } - /// Provide a database to lookup `code_hash`. Should not be called if it is a contract without code. + /// Provide a database to get `code_hash`. Should not be called if it is a contract without code. pub fn cache_code(&mut self, db: &AccountDB) -> bool { // TODO: fill out self.code_cache; trace!("Account::cache_code: ic={}; self.code_hash={:?}, self.code_cache={}", self.is_cached(), self.code_hash, self.code_cache.pretty()); self.is_cached() || match self.code_hash { - Some(ref h) => match db.lookup(h) { + Some(ref h) => match db.get(h) { Some(x) => { self.code_cache = x.to_vec(); true }, _ => { - warn!("Failed reverse lookup of {}", h); + warn!("Failed reverse get of {}", h); false }, }, diff --git a/ethcore/src/account_db.rs b/ethcore/src/account_db.rs index dc36a40af..bc2afcc73 100644 --- a/ethcore/src/account_db.rs +++ b/ethcore/src/account_db.rs @@ -37,18 +37,18 @@ impl<'db> HashDB for AccountDB<'db>{ unimplemented!() } - fn lookup(&self, key: &H256) -> Option<&[u8]> { + fn get(&self, key: &H256) -> Option<&[u8]> { if key == &SHA3_NULL_RLP { return Some(&NULL_RLP_STATIC); } - self.db.lookup(&combine_key(&self.address_hash, key)) + self.db.get(&combine_key(&self.address_hash, key)) } - fn exists(&self, key: &H256) -> bool { + fn contains(&self, key: &H256) -> bool { if key == &SHA3_NULL_RLP { return true; } - self.db.exists(&combine_key(&self.address_hash, key)) + self.db.contains(&combine_key(&self.address_hash, key)) } fn insert(&mut self, _value: &[u8]) -> H256 { @@ -59,7 +59,7 @@ impl<'db> HashDB for AccountDB<'db>{ unimplemented!() } - fn kill(&mut self, _key: &H256) { + fn remove(&mut self, _key: &H256) { unimplemented!() } } @@ -95,18 +95,18 @@ impl<'db> HashDB for AccountDBMut<'db>{ unimplemented!() } - fn lookup(&self, key: &H256) -> Option<&[u8]> { + fn get(&self, key: &H256) -> Option<&[u8]> { if key == &SHA3_NULL_RLP { return Some(&NULL_RLP_STATIC); } - self.db.lookup(&combine_key(&self.address_hash, key)) + self.db.get(&combine_key(&self.address_hash, key)) } - fn exists(&self, key: &H256) -> bool { + fn contains(&self, key: &H256) -> bool { if key == &SHA3_NULL_RLP { return true; } - self.db.exists(&combine_key(&self.address_hash, key)) + self.db.contains(&combine_key(&self.address_hash, key)) } fn insert(&mut self, value: &[u8]) -> H256 { @@ -127,12 +127,12 @@ impl<'db> HashDB for AccountDBMut<'db>{ self.db.emplace(key, value.to_vec()) } - fn kill(&mut self, key: &H256) { + fn remove(&mut self, key: &H256) { if key == &SHA3_NULL_RLP { return; } let key = combine_key(&self.address_hash, key); - self.db.kill(&key) + self.db.remove(&key) } } diff --git a/ethcore/src/account_provider.rs b/ethcore/src/account_provider.rs new file mode 100644 index 000000000..a71251727 --- /dev/null +++ b/ethcore/src/account_provider.rs @@ -0,0 +1,272 @@ +// 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 . + +//! Account management. + +use std::fmt; +use std::sync::RwLock; +use std::collections::HashMap; +use util::{Address as H160, H256, H520}; +use ethstore::{SecretStore, Error as SSError, SafeAccount, EthStore}; +use ethstore::dir::{KeyDirectory}; +use ethstore::ethkey::{Address as SSAddress, Message as SSMessage, Secret as SSSecret, Random, Generator}; + +/// Type of unlock. +#[derive(Clone)] +enum Unlock { + /// If account is unlocked temporarily, it should be locked after first usage. + Temp, + /// Account unlocked permantently can always sign message. + /// Use with caution. + Perm, +} + +/// Data associated with account. +#[derive(Clone)] +struct AccountData { + unlock: Unlock, + password: String, +} + +/// `AccountProvider` errors. +#[derive(Debug)] +pub enum Error { + /// Returned when account is not unlocked. + NotUnlocked, + /// Returned when signing fails. + SStore(SSError), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match *self { + Error::NotUnlocked => write!(f, "Account is locked"), + Error::SStore(ref e) => write!(f, "{}", e), + } + } +} + +impl From for Error { + fn from(e: SSError) -> Self { + Error::SStore(e) + } +} + +macro_rules! impl_bridge_type { + ($name: ident, $size: expr, $core: ident, $store: ident) => { + /// Primitive + pub struct $name([u8; $size]); + + impl From<[u8; $size]> for $name { + fn from(s: [u8; $size]) -> Self { + $name(s) + } + } + + impl From<$core> for $name { + fn from(s: $core) -> Self { + $name(s.0) + } + } + + impl From<$store> for $name { + fn from(s: $store) -> Self { + $name(s.into()) + } + } + + impl Into<$core> for $name { + fn into(self) -> $core { + $core(self.0) + } + } + + impl Into<$store> for $name { + fn into(self) -> $store { + $store::from(self.0) + } + } + } +} + +impl_bridge_type!(Secret, 32, H256, SSSecret); +impl_bridge_type!(Message, 32, H256, SSMessage); +impl_bridge_type!(Address, 20, H160, SSAddress); + + +struct NullDir; + +impl KeyDirectory for NullDir { + fn load(&self) -> Result, SSError> { + Ok(vec![]) + } + + fn insert(&self, _account: SafeAccount) -> Result<(), SSError> { + Ok(()) + } + + fn remove(&self, _address: &SSAddress) -> Result<(), SSError> { + Ok(()) + } +} + +/// Account management. +/// Responsible for unlocking accounts. +pub struct AccountProvider { + unlocked: RwLock>, + sstore: Box, +} + +impl AccountProvider { + /// Creates new account provider. + pub fn new(sstore: Box) -> Self { + AccountProvider { + unlocked: RwLock::new(HashMap::new()), + sstore: sstore, + } + } + + /// Creates not disk backed provider. + pub fn transient_provider() -> Self { + AccountProvider { + unlocked: RwLock::new(HashMap::new()), + sstore: Box::new(EthStore::open(Box::new(NullDir)).unwrap()) + } + } + + /// Creates new random account. + pub fn new_account(&self, password: &str) -> Result { + let secret = Random.generate().unwrap().secret().clone(); + let address = try!(self.sstore.insert_account(secret, password)); + Ok(Address::from(address).into()) + } + + /// Inserts new account into underlying store. + /// Does not unlock account! + pub fn insert_account(&self, secret: S, password: &str) -> Result where Secret: From { + let s = Secret::from(secret); + let address = try!(self.sstore.insert_account(s.into(), password)); + Ok(Address::from(address).into()) + } + + /// Returns addresses of all accounts. + pub fn accounts(&self) -> Vec { + self.sstore.accounts().into_iter().map(|a| H160(a.into())).collect() + } + + /// Helper method used for unlocking accounts. + fn unlock_account(&self, account: A, password: String, unlock: Unlock) -> Result<(), Error> where Address: From { + let a = Address::from(account); + let account = a.into(); + // verify password by signing dump message + // result may be discarded + let _ = try!(self.sstore.sign(&account, &password, &Default::default())); + + // check if account is already unlocked pernamently, if it is, do nothing + { + let unlocked = self.unlocked.read().unwrap(); + if let Some(data) = unlocked.get(&account) { + if let Unlock::Perm = data.unlock { + return Ok(()) + } + } + } + + let data = AccountData { + unlock: unlock, + password: password, + }; + + let mut unlocked = self.unlocked.write().unwrap(); + unlocked.insert(account, data); + Ok(()) + } + + /// Unlocks account permanently. + pub fn unlock_account_permanently(&self, account: A, password: String) -> Result<(), Error> where Address: From { + self.unlock_account(account, password, Unlock::Perm) + } + + /// Unlocks account temporarily (for one signing). + pub fn unlock_account_temporarily(&self, account: A, password: String) -> Result<(), Error> where Address: From { + self.unlock_account(account, password, Unlock::Temp) + } + + /// Checks if given account is unlocked + pub fn is_unlocked(&self, account: A) -> bool where Address: From { + let account = Address::from(account).into(); + let unlocked = self.unlocked.read().unwrap(); + unlocked.get(&account).is_some() + } + + /// Signs the message. Account must be unlocked. + pub fn sign(&self, account: A, message: M) -> Result where Address: From, Message: From { + let account = Address::from(account).into(); + let message = Message::from(message).into(); + + let data = { + let unlocked = self.unlocked.read().unwrap(); + try!(unlocked.get(&account).ok_or(Error::NotUnlocked)).clone() + }; + + if let Unlock::Temp = data.unlock { + let mut unlocked = self.unlocked.write().unwrap(); + unlocked.remove(&account).expect("data exists: so key must exist: qed"); + } + + let signature = try!(self.sstore.sign(&account, &data.password, &message)); + Ok(H520(signature.into())) + } + + /// Unlocks an account, signs the message, and locks it again. + pub fn sign_with_password(&self, account: A, password: String, message: M) -> Result where Address: From, Message: From { + let account = Address::from(account).into(); + let message = Message::from(message).into(); + let signature = try!(self.sstore.sign(&account, &password, &message)); + Ok(H520(signature.into())) + } +} + +#[cfg(test)] +mod tests { + use super::AccountProvider; + use ethstore::ethkey::{Generator, Random}; + + #[test] + fn unlock_account_temp() { + let kp = Random.generate().unwrap(); + let ap = AccountProvider::transient_provider(); + assert!(ap.insert_account(kp.secret().clone(), "test").is_ok()); + assert!(ap.unlock_account_temporarily(kp.address(), "test1".into()).is_err()); + assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).is_ok()); + assert!(ap.sign(kp.address(), [0u8; 32]).is_ok()); + assert!(ap.sign(kp.address(), [0u8; 32]).is_err()); + } + + #[test] + fn unlock_account_perm() { + let kp = Random.generate().unwrap(); + let ap = AccountProvider::transient_provider(); + assert!(ap.insert_account(kp.secret().clone(), "test").is_ok()); + assert!(ap.unlock_account_permanently(kp.address(), "test1".into()).is_err()); + assert!(ap.unlock_account_permanently(kp.address(), "test".into()).is_ok()); + assert!(ap.sign(kp.address(), [0u8; 32]).is_ok()); + assert!(ap.sign(kp.address(), [0u8; 32]).is_ok()); + assert!(ap.unlock_account_temporarily(kp.address(), "test".into()).is_ok()); + assert!(ap.sign(kp.address(), [0u8; 32]).is_ok()); + assert!(ap.sign(kp.address(), [0u8; 32]).is_ok()); + } +} diff --git a/ethcore/src/basic_authority.rs b/ethcore/src/basic_authority.rs index c732ce711..4426d3059 100644 --- a/ethcore/src/basic_authority.rs +++ b/ethcore/src/basic_authority.rs @@ -17,7 +17,7 @@ //! A blockchain engine that supports a basic, non-BFT proof-of-authority. use common::*; -use util::keys::store::AccountProvider; +use account_provider::AccountProvider; use block::*; use spec::{CommonParams, Spec}; use engine::*; @@ -80,7 +80,7 @@ impl Engine for BasicAuthority { Schedule::new_homestead() } - fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256) { + fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, _gas_ceil_target: U256) { header.difficulty = parent.difficulty; header.gas_limit = { let gas_limit = parent.gas_limit; @@ -105,15 +105,13 @@ impl Engine for BasicAuthority { /// be returned. fn generate_seal(&self, block: &ExecutedBlock, accounts: Option<&AccountProvider>) -> Option> { if let Some(ap) = accounts { - // check to see if author is contained in self.our_params.authorities - if self.our_params.authorities.contains(block.header().author()) { - if let Ok(secret) = ap.account_secret(block.header().author()) { - return Some(block.header().author_seal(&secret)); - } else { - trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable"); - } + let header = block.header(); + let message = header.bare_hash(); + // account should be pernamently unlocked, otherwise sealing will fail + if let Ok(signature) = ap.sign(*block.header().author(), message) { + return Some(vec![encode(&signature).to_vec()]); } else { - trace!(target: "basicauthority", "generate_seal: FAIL: block author {} isn't one of the authorized accounts {:?}", block.header().author(), self.our_params.authorities); + trace!(target: "basicauthority", "generate_seal: FAIL: accounts secret key unavailable"); } } else { trace!(target: "basicauthority", "generate_seal: FAIL: accounts not provided"); @@ -176,16 +174,6 @@ impl Header { pub fn signature(&self) -> H520 { decode(&self.seal()[0]) } - - /// Generate a seal for the block with the given `secret`. - pub fn author_seal(&self, secret: &Secret) -> Vec { - vec![encode(&ec::sign(secret, &self.bare_hash()).unwrap_or(Signature::new())).to_vec()] - } - - /// Set the nonce and mix hash fields of the header. - pub fn sign(&mut self, secret: &Secret) { - self.seal = self.author_seal(secret); - } } /// Create a new test chain spec with `BasicAuthority` consensus engine. @@ -197,7 +185,7 @@ mod tests { use common::*; use block::*; use tests::helpers::*; - use util::keys::{TestAccountProvider, TestAccount}; + use account_provider::AccountProvider; #[test] fn has_valid_metadata() { @@ -215,8 +203,9 @@ mod tests { timestamp: 0, difficulty: 0.into(), last_hashes: vec![], + dao_rescue_block_gas_limit: None, gas_used: 0.into(), - gas_limit: 0.into() + gas_limit: 0.into(), }); assert!(schedule.stack_limit > 0); @@ -251,24 +240,11 @@ mod tests { } } - #[test] - fn can_do_signature_verification() { - let secret = "".sha3(); - let addr = KeyPair::from_secret("".sha3()).unwrap().address(); - - let engine = new_test_authority().engine; - let mut header: Header = Header::default(); - header.set_author(addr); - header.sign(&secret); - - assert!(engine.verify_block_unordered(&header, None).is_ok()); - } - #[test] fn can_generate_seal() { - let addr = KeyPair::from_secret("".sha3()).unwrap().address(); - let accounts = hash_map![addr => TestAccount{unlocked: true, password: Default::default(), secret: "".sha3()}]; - let tap = TestAccountProvider::new(accounts); + let tap = AccountProvider::transient_provider(); + let addr = tap.insert_account("".sha3(), "").unwrap(); + tap.unlock_account_permanently(addr, "".into()).unwrap(); let spec = new_test_authority(); let engine = &spec.engine; @@ -278,10 +254,9 @@ mod tests { spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; let vm_factory = Default::default(); - let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, addr.clone(), 3141562.into(), vec![]).unwrap(); + let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, addr, (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap(); - assert!(b.try_seal(engine.deref(), seal).is_ok()); } } diff --git a/ethcore/src/block.rs b/ethcore/src/block.rs index 74f54a057..103435f40 100644 --- a/ethcore/src/block.rs +++ b/ethcore/src/block.rs @@ -177,6 +177,7 @@ pub struct OpenBlock<'x> { engine: &'x Engine, vm_factory: &'x EvmFactory, last_hashes: LastHashes, + dao_rescue_block_gas_limit: Option, } /// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields, @@ -188,6 +189,7 @@ pub struct ClosedBlock { block: ExecutedBlock, uncle_bytes: Bytes, last_hashes: LastHashes, + dao_rescue_block_gas_limit: Option, unclosed_state: State, } @@ -198,7 +200,6 @@ pub struct ClosedBlock { pub struct LockedBlock { block: ExecutedBlock, uncle_bytes: Bytes, - last_hashes: LastHashes, } /// A block that has a valid seal. @@ -219,9 +220,10 @@ impl<'x> OpenBlock<'x> { db: Box, parent: &Header, last_hashes: LastHashes, + dao_rescue_block_gas_limit: Option, author: Address, - gas_floor_target: U256, - extra_data: Bytes + gas_range_target: (U256, U256), + extra_data: Bytes, ) -> Result { let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce())); let mut r = OpenBlock { @@ -229,6 +231,7 @@ impl<'x> OpenBlock<'x> { engine: engine, vm_factory: vm_factory, last_hashes: last_hashes, + dao_rescue_block_gas_limit: dao_rescue_block_gas_limit, }; r.block.base.header.parent_hash = parent.hash(); @@ -238,7 +241,7 @@ impl<'x> OpenBlock<'x> { r.block.base.header.extra_data = extra_data; r.block.base.header.note_dirty(); - engine.populate_from_parent(&mut r.block.base.header, parent, gas_floor_target); + engine.populate_from_parent(&mut r.block.base.header, parent, gas_range_target.0, gas_range_target.1); engine.on_new_block(&mut r.block); Ok(r) } @@ -285,6 +288,7 @@ impl<'x> OpenBlock<'x> { /// Get the environment info concerning this block. pub fn env_info(&self) -> EnvInfo { // TODO: memoise. + const SOFT_FORK_BLOCK: u64 = 1_800_000; EnvInfo { number: self.block.base.header.number, author: self.block.base.header.author.clone(), @@ -293,6 +297,7 @@ impl<'x> OpenBlock<'x> { last_hashes: self.last_hashes.clone(), // TODO: should be a reference. gas_used: self.block.receipts.last().map_or(U256::zero(), |r| r.gas_used), gas_limit: self.block.base.header.gas_limit.clone(), + dao_rescue_block_gas_limit: if self.block.base.header.number == SOFT_FORK_BLOCK { Some(self.block.base.header.gas_limit) } else { self.dao_rescue_block_gas_limit }, } } @@ -339,6 +344,7 @@ impl<'x> OpenBlock<'x> { block: s.block, uncle_bytes: uncle_bytes, last_hashes: s.last_hashes, + dao_rescue_block_gas_limit: s.dao_rescue_block_gas_limit, unclosed_state: unclosed_state, } } @@ -360,7 +366,6 @@ impl<'x> OpenBlock<'x> { LockedBlock { block: s.block, uncle_bytes: uncle_bytes, - last_hashes: s.last_hashes, } } } @@ -386,7 +391,6 @@ impl ClosedBlock { LockedBlock { block: self.block, uncle_bytes: self.uncle_bytes, - last_hashes: self.last_hashes, } } @@ -400,6 +404,7 @@ impl ClosedBlock { engine: engine, vm_factory: vm_factory, last_hashes: self.last_hashes, + dao_rescue_block_gas_limit: self.dao_rescue_block_gas_limit, } } } @@ -456,7 +461,18 @@ impl IsBlock for SealedBlock { /// Enact the block given by block header, transactions and uncles #[cfg_attr(feature="dev", allow(too_many_arguments))] -pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result { +pub fn enact( + header: &Header, + transactions: &[SignedTransaction], + uncles: &[Header], + engine: &Engine, + tracing: bool, + db: Box, + parent: &Header, + last_hashes: LastHashes, + dao_rescue_block_gas_limit: Option, + vm_factory: &EvmFactory +) -> Result { { if ::log::max_log_level() >= ::log::LogLevel::Trace { let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce())); @@ -464,7 +480,7 @@ pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Head } } - let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, header.author().clone(), 3141562.into(), header.extra_data().clone())); + let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, header.author().clone(), (3141562.into(), 31415620.into()), header.extra_data().clone())); b.set_difficulty(*header.difficulty()); b.set_gas_limit(*header.gas_limit()); b.set_timestamp(header.timestamp()); @@ -474,22 +490,52 @@ pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Head } /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header -pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result { +#[cfg_attr(feature="dev", allow(too_many_arguments))] +pub fn enact_bytes( + block_bytes: &[u8], + engine: &Engine, + tracing: bool, + db: Box, + parent: &Header, + last_hashes: LastHashes, + dao_rescue_block_gas_limit: Option, + vm_factory: &EvmFactory +) -> Result { let block = BlockView::new(block_bytes); let header = block.header(); - enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, vm_factory) + enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory) } /// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header -pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result { +#[cfg_attr(feature="dev", allow(too_many_arguments))] +pub fn enact_verified( + block: &PreverifiedBlock, + engine: &Engine, + tracing: bool, + db: Box, + parent: &Header, + last_hashes: LastHashes, + dao_rescue_block_gas_limit: Option, + vm_factory: &EvmFactory +) -> Result { let view = BlockView::new(&block.bytes); - enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, vm_factory) + enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory) } /// 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, tracing: bool, db: Box, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result { +#[cfg_attr(feature="dev", allow(too_many_arguments))] +pub fn enact_and_seal( + block_bytes: &[u8], + engine: &Engine, + tracing: bool, + db: Box, + parent: &Header, + last_hashes: LastHashes, + dao_rescue_block_gas_limit: Option, + vm_factory: &EvmFactory +) -> Result { let header = BlockView::new(block_bytes).header_view(); - Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, vm_factory)).seal(engine, header.seal()))) + Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)).seal(engine, header.seal()))) } #[cfg(test)] @@ -509,7 +555,7 @@ mod tests { spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; let vm_factory = Default::default(); - let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), 3141562.into(), vec![]).unwrap(); + let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close_and_lock(); let _ = b.seal(engine.deref(), vec![]); } @@ -525,7 +571,7 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); let vm_factory = Default::default(); - let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), 3141562.into(), vec![]).unwrap() + let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap() .close_and_lock().seal(engine.deref(), vec![]).unwrap(); let orig_bytes = b.rlp_bytes(); let orig_db = b.drain(); @@ -533,7 +579,7 @@ mod tests { let mut db_result = get_temp_journal_db(); let mut db = db_result.take(); 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()], &Default::default()).unwrap(); + let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap(); assert_eq!(e.rlp_bytes(), orig_bytes); @@ -553,7 +599,7 @@ mod tests { let mut db = db_result.take(); spec.ensure_db_good(db.as_hashdb_mut()); let vm_factory = Default::default(); - let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), 3141562.into(), vec![]).unwrap(); + let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut uncle1_header = Header::new(); uncle1_header.extra_data = b"uncle1".to_vec(); let mut uncle2_header = Header::new(); @@ -568,7 +614,7 @@ mod tests { let mut db_result = get_temp_journal_db(); let mut db = db_result.take(); 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()], &Default::default()).unwrap(); + let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap(); let bytes = e.rlp_bytes(); assert_eq!(bytes, orig_bytes); diff --git a/ethcore/src/block_queue.rs b/ethcore/src/block_queue.rs index 5e89641c0..ce99dcccd 100644 --- a/ethcore/src/block_queue.rs +++ b/ethcore/src/block_queue.rs @@ -130,7 +130,9 @@ impl QueueSignal { } if self.signalled.compare_and_swap(false, true, AtomicOrdering::Relaxed) == false { - self.message_channel.send(UserMessage(SyncMessage::BlockVerified)).expect("Error sending BlockVerified message"); + if let Err(e) = self.message_channel.send(UserMessage(SyncMessage::BlockVerified)) { + debug!("Error sending BlockVerified message: {:?}", e); + } } } diff --git a/ethcore/src/blockchain/blockchain.rs b/ethcore/src/blockchain/blockchain.rs index 6fb9161d5..4b2246b21 100644 --- a/ethcore/src/blockchain/blockchain.rs +++ b/ethcore/src/blockchain/blockchain.rs @@ -253,12 +253,22 @@ impl BlockChain { // open extras db let mut extras_path = path.to_path_buf(); extras_path.push("extras"); - let extras_db = Database::open_default(extras_path.to_str().unwrap()).unwrap(); + let extras_db = match config.db_cache_size { + None => Database::open_default(extras_path.to_str().unwrap()).unwrap(), + Some(cache_size) => Database::open( + &DatabaseConfig::with_cache(cache_size/2), + extras_path.to_str().unwrap()).unwrap(), + }; // open blocks db let mut blocks_path = path.to_path_buf(); blocks_path.push("blocks"); - let blocks_db = Database::open_default(blocks_path.to_str().unwrap()).unwrap(); + let blocks_db = match config.db_cache_size { + None => Database::open_default(blocks_path.to_str().unwrap()).unwrap(), + Some(cache_size) => Database::open( + &DatabaseConfig::with_cache(cache_size/2), + 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())); diff --git a/ethcore/src/blockchain/config.rs b/ethcore/src/blockchain/config.rs index 9e70ff904..e063d4269 100644 --- a/ethcore/src/blockchain/config.rs +++ b/ethcore/src/blockchain/config.rs @@ -23,6 +23,8 @@ pub struct Config { pub pref_cache_size: usize, /// Maximum cache size in bytes. pub max_cache_size: usize, + /// Backing db cache_size + pub db_cache_size: Option, } impl Default for Config { @@ -30,6 +32,7 @@ impl Default for Config { Config { pref_cache_size: 1 << 14, max_cache_size: 1 << 20, + db_cache_size: None, } } } diff --git a/ethcore/src/client/client.rs b/ethcore/src/client/client.rs index 1c8b1c3b6..5fa6e6475 100644 --- a/ethcore/src/client/client.rs +++ b/ethcore/src/client/client.rs @@ -16,9 +16,9 @@ //! Blockchain database client. -use std::marker::PhantomData; use std::fs::{create_dir, File}; use std::path::PathBuf; +use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; use util::*; use util::panics::*; use views::BlockView; @@ -30,7 +30,8 @@ use engine::Engine; use views::HeaderView; use service::{NetSyncMessage, SyncMessage}; use env_info::LastHashes; -use verification::*; +use verification; +use verification::{PreverifiedBlock, Verifier}; use block::*; use transaction::{LocalizedTransaction, SignedTransaction, Action}; use blockchain::extras::TransactionAddress; @@ -38,7 +39,7 @@ use filter::Filter; use log_entry::LocalizedLogEntry; use block_queue::{BlockQueue, BlockQueueInfo}; use blockchain::{BlockChain, BlockProvider, TreeRoute, ImportRoute}; -use client::{BlockID, TransactionID, UncleID, TraceId, ClientConfig, BlockChainClient, MiningBlockChainClient, TraceFilter, CallAnalytics}; +use client::{BlockID, TransactionID, UncleID, TraceId, ClientConfig, DatabaseCompactionProfile, BlockChainClient, MiningBlockChainClient, TraceFilter, CallAnalytics}; use client::Error as ClientError; use env_info::EnvInfo; use executive::{Executive, Executed, TransactOptions, contract_address}; @@ -51,6 +52,8 @@ pub use types::block_status::BlockStatus; use evm::Factory as EvmFactory; use miner::{Miner, MinerService, TransactionImportResult, AccountDetails}; +const MAX_TX_QUEUE_SIZE: usize = 4096; + impl fmt::Display for BlockChainInfo { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "#{}.{}", self.best_block_number, self.best_block_hash) @@ -81,7 +84,7 @@ impl ClientReport { /// 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 where V: Verifier { +pub struct Client { chain: Arc, tracedb: Arc>, engine: Arc>, @@ -90,9 +93,11 @@ pub struct Client where V: Verifier { report: RwLock, import_lock: Mutex<()>, panic_handler: Arc, - verifier: PhantomData, + verifier: Box, vm_factory: Arc, miner: Arc, + io_channel: IoChannel, + queue_transactions: AtomicUsize, } const HISTORY: u64 = 1200; @@ -103,13 +108,6 @@ const HISTORY: u64 = 1200; // of which you actually want force an upgrade. const CLIENT_DB_VER_STR: &'static str = "5.3"; -impl Client { - /// Create a new client with given spec and root path. - pub fn new(config: ClientConfig, spec: Spec, path: &Path, miner: Arc, message_channel: IoChannel ) -> Result, ClientError> { - Client::::new_with_verifier(config, spec, path, miner, message_channel) - } -} - /// Get the path for the databases given the root path and information on the databases. pub fn get_db_path(path: &Path, pruning: journaldb::Algorithm, genesis_hash: H256) -> PathBuf { let mut dir = path.to_path_buf(); @@ -127,22 +125,35 @@ pub fn append_path(path: &Path, item: &str) -> String { p.to_str().unwrap().to_owned() } -impl Client where V: Verifier { - /// Create a new client with given spec and root path and custom verifier. - pub fn new_with_verifier( +impl Client { + /// Create a new client with given spec and DB path and custom verifier. + pub fn new( config: ClientConfig, spec: Spec, path: &Path, miner: Arc, message_channel: IoChannel) - -> Result>, ClientError> + -> Result, ClientError> { let path = get_db_path(path, config.pruning, spec.genesis_header().hash()); let gb = spec.genesis_block(); let chain = Arc::new(BlockChain::new(config.blockchain, &gb, &path)); let tracedb = Arc::new(try!(TraceDB::new(config.tracing, &path, chain.clone()))); - let mut state_db = journaldb::new(&append_path(&path, "state"), config.pruning); + let mut state_db_config = match config.db_cache_size { + None => DatabaseConfig::default(), + Some(cache_size) => DatabaseConfig::with_cache(cache_size), + }; + + if config.db_compaction == DatabaseCompactionProfile::HDD { + state_db_config = state_db_config.compaction(CompactionProfile::hdd()); + } + + let mut state_db = journaldb::new( + &append_path(&path, "state"), + config.pruning, + state_db_config + ); if state_db.is_empty() && spec.ensure_db_good(state_db.as_hashdb_mut()) { state_db.commit(0, &spec.genesis_header().hash(), None).expect("Error commiting genesis state to state DB"); @@ -150,7 +161,7 @@ impl Client where V: Verifier { let engine = Arc::new(spec.engine); - let block_queue = BlockQueue::new(config.queue, engine.clone(), message_channel); + let block_queue = BlockQueue::new(config.queue, engine.clone(), message_channel.clone()); let panic_handler = PanicHandler::new_in_arc(); panic_handler.forward_from(&block_queue); @@ -163,9 +174,11 @@ impl Client where V: Verifier { report: RwLock::new(Default::default()), import_lock: Mutex::new(()), panic_handler: panic_handler, - verifier: PhantomData, + verifier: verification::new(config.verifier_type), vm_factory: Arc::new(EvmFactory::new(config.vm_type)), miner: miner, + io_channel: message_channel, + queue_transactions: AtomicUsize::new(0), }; Ok(Arc::new(client)) @@ -203,7 +216,7 @@ impl Client where V: Verifier { } // Verify Block Family - let verify_family_result = V::verify_block_family(&header, &block.bytes, engine, self.chain.deref()); + let verify_family_result = self.verifier.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(()); @@ -221,7 +234,7 @@ impl Client where V: Verifier { let last_hashes = self.build_last_hashes(header.parent_hash.clone()); let db = self.state_db.lock().unwrap().boxed_clone(); - let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, &self.vm_factory); + let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, self.dao_rescue_block_gas_limit(header.parent_hash.clone()), &self.vm_factory); if let Err(e) = enact_result { warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); return Err(()); @@ -229,7 +242,7 @@ impl Client where V: Verifier { // Final Verification let locked_block = enact_result.unwrap(); - if let Err(e) = V::verify_block_final(&header, locked_block.block().header()) { + if let Err(e) = self.verifier.verify_block_final(&header, locked_block.block().header()) { warn!(target: "client", "Stage 4 block verification failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e); return Err(()); } @@ -272,6 +285,7 @@ impl Client where V: Verifier { let mut import_results = Vec::with_capacity(max_blocks_to_import); let _import_lock = self.import_lock.lock(); + let _timer = PerfTimer::new("import_verified_blocks"); let blocks = self.block_queue.drain(max_blocks_to_import); let original_best = self.chain_info().best_block_hash; @@ -286,7 +300,7 @@ impl Client where V: Verifier { let closed_block = self.check_and_close_block(&block); if let Err(_) = closed_block { invalid_blocks.insert(header.hash()); - break; + continue; } imported_blocks.push(header.hash()); @@ -349,7 +363,7 @@ impl Client where V: Verifier { invalid: invalid_blocks, enacted: enacted, retracted: retracted, - })).unwrap(); + })).unwrap_or_else(|e| warn!("Error sending IO notification: {:?}", e)); } } @@ -362,6 +376,19 @@ impl Client where V: Verifier { imported } + /// Import transactions from the IO queue + pub fn import_queued_transactions(&self, transactions: &[Bytes]) -> usize { + let _timer = PerfTimer::new("import_queued_transactions"); + self.queue_transactions.fetch_sub(transactions.len(), AtomicOrdering::SeqCst); + let fetch_account = |a: &Address| AccountDetails { + nonce: self.latest_nonce(a), + balance: self.latest_balance(a), + }; + let tx = transactions.iter().filter_map(|bytes| UntrustedRlp::new(&bytes).as_val().ok()).collect(); + let results = self.miner.import_transactions(self, tx, fetch_account); + results.len() + } + /// Attempt to get a copy of a specific block's state. /// /// This will not fail if given BlockID::Latest. @@ -450,7 +477,7 @@ impl Client where V: Verifier { } } -impl BlockChainClient for Client where V: Verifier { +impl BlockChainClient for Client { fn call(&self, t: &SignedTransaction, analytics: CallAnalytics) -> Result { let header = self.block_header(BlockID::Latest).unwrap(); let view = HeaderView::new(&header); @@ -463,6 +490,7 @@ impl BlockChainClient for Client where V: Verifier { last_hashes: last_hashes, gas_used: U256::zero(), gas_limit: U256::max_value(), + dao_rescue_block_gas_limit: self.dao_rescue_block_gas_limit(view.parent_hash()), }; // that's just a copy of the state. let mut state = self.state(); @@ -748,11 +776,27 @@ impl BlockChainClient for Client where V: Verifier { nonce: self.latest_nonce(a), balance: self.latest_balance(a), }; - self.miner.import_transactions(transactions, fetch_account) + self.miner.import_transactions(self, transactions, fetch_account) } - fn all_transactions(&self) -> Vec { - self.miner.all_transactions() + fn queue_transactions(&self, transactions: Vec) { + if self.queue_transactions.load(AtomicOrdering::Relaxed) > MAX_TX_QUEUE_SIZE { + debug!("Ignoring {} transactions: queue is full", transactions.len()); + } else { + let len = transactions.len(); + match self.io_channel.send(NetworkIoMessage::User(SyncMessage::NewTransactions(transactions))) { + Ok(_) => { + self.queue_transactions.fetch_add(len, AtomicOrdering::SeqCst); + } + Err(e) => { + debug!("Ignoring {} transactions: error queueing: {}", len, e); + } + } + } + } + + fn pending_transactions(&self) -> Vec { + self.miner.pending_transactions() } fn take_snapshot(&self, root_dir: &Path) { @@ -794,8 +838,8 @@ impl BlockChainClient for Client where V: Verifier { } } -impl MiningBlockChainClient for Client where V: Verifier { - fn prepare_open_block(&self, author: Address, gas_floor_target: U256, extra_data: Bytes) -> OpenBlock { +impl MiningBlockChainClient for Client { + fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock { let engine = self.engine.deref().deref(); let h = self.chain.best_block_hash(); @@ -806,11 +850,11 @@ impl MiningBlockChainClient for Client where V: Verifier { self.state_db.lock().unwrap().boxed_clone(), &self.chain.block_header(&h).expect("h is best block hash: so it's header must exist: qed"), self.build_last_hashes(h.clone()), + self.dao_rescue_block_gas_limit(h.clone()), author, - gas_floor_target, + gas_range_target, extra_data, - ).expect("OpenBlock::new only fails if parent state root invalid. State root of best block's header is never invalid. \ - Therefore creating an OpenBlock with the best block's header will not fail."); + ).expect("OpenBlock::new only fails if parent state root invalid; state root of best block's header is never invalid; qed"); // Add uncles self.chain @@ -824,10 +868,6 @@ impl MiningBlockChainClient for Client where V: Verifier { open_block } - - fn try_seal(&self, block: LockedBlock, seal: Vec) -> Result { - block.try_seal(self.engine.deref().deref(), seal) - } } impl MayPanic for Client { diff --git a/ethcore/src/client/config.rs b/ethcore/src/client/config.rs index e0b867903..52a875a2f 100644 --- a/ethcore/src/client/config.rs +++ b/ethcore/src/client/config.rs @@ -18,8 +18,22 @@ pub use block_queue::BlockQueueConfig; pub use blockchain::Config as BlockChainConfig; pub use trace::{Config as TraceConfig, Switch}; pub use evm::VMType; +pub use verification::VerifierType; use util::journaldb; +/// Client state db compaction profile +#[derive(Debug, PartialEq)] +pub enum DatabaseCompactionProfile { + /// Default compaction profile + Default, + /// HDD or other slow storage io compaction profile + HDD, +} + +impl Default for DatabaseCompactionProfile { + fn default() -> Self { DatabaseCompactionProfile::Default } +} + /// Client configuration. Includes configs for all sub-systems. #[derive(Debug, Default)] pub struct ClientConfig { @@ -35,4 +49,10 @@ pub struct ClientConfig { pub pruning: journaldb::Algorithm, /// The name of the client instance. pub name: String, + /// State db cache-size if not default + pub db_cache_size: Option, + /// State db compaction profile + pub db_compaction: DatabaseCompactionProfile, + /// Type of block verifier used by client. + pub verifier_type: VerifierType, } diff --git a/ethcore/src/client/mod.rs b/ethcore/src/client/mod.rs index 2baa7c365..9e6bd098c 100644 --- a/ethcore/src/client/mod.rs +++ b/ethcore/src/client/mod.rs @@ -23,7 +23,7 @@ mod test_client; mod trace; pub use self::client::*; -pub use self::config::{ClientConfig, BlockQueueConfig, BlockChainConfig, Switch, VMType}; +pub use self::config::{ClientConfig, DatabaseCompactionProfile, BlockQueueConfig, BlockChainConfig, Switch, VMType}; pub use self::error::Error; pub use types::ids::*; pub use self::test_client::{TestBlockChainClient, EachBlockWith}; @@ -35,13 +35,15 @@ use std::path::Path; use util::bytes::Bytes; use util::hash::{Address, H256, H2048}; use util::numbers::U256; +use util::Itertools; use blockchain::TreeRoute; use block_queue::BlockQueueInfo; -use block::{LockedBlock, SealedBlock, OpenBlock}; +use block::OpenBlock; use header::{BlockNumber, Header}; use transaction::{LocalizedTransaction, SignedTransaction}; use log_entry::LocalizedLogEntry; use filter::Filter; +use views::{HeaderView, BlockView}; use error::{ImportResult, ExecutionError}; use receipt::LocalizedReceipt; use trace::LocalizedTrace; @@ -192,20 +194,68 @@ pub trait BlockChainClient : Sync + Send { /// import transactions from network/other 3rd party fn import_transactions(&self, transactions: Vec) -> Vec>; - /// list all transactions - fn all_transactions(&self) -> Vec; + /// Queue transactions for importing. + fn queue_transactions(&self, transactions: Vec); /// Generate a PV64 snapshot for the current best block, saving it within the /// root directory, whose path is given. fn take_snapshot(&self, root_dir: &Path); + + /// list all transactions + fn pending_transactions(&self) -> Vec; + + /// Get the gas price distribution. + fn gas_price_statistics(&self, sample_size: usize, distribution_size: usize) -> Result, ()> { + let mut h = self.chain_info().best_block_hash; + let mut corpus = Vec::new(); + for _ in 0..sample_size { + let block_bytes = self.block(BlockID::Hash(h)).expect("h is either the best_block_hash or an ancestor; qed"); + let block = BlockView::new(&block_bytes); + let header = block.header_view(); + if header.number() == 0 { + break; + } + block.transaction_views().iter().foreach(|t| corpus.push(t.gas_price())); + h = header.parent_hash().clone(); + } + corpus.sort(); + let n = corpus.len(); + if n > 0 { + Ok((0..(distribution_size + 1)) + .map(|i| corpus[i * (n - 1) / distribution_size]) + .collect::>() + ) + } else { + Err(()) + } + } + + /// Get `Some` gas limit of SOFT_FORK_BLOCK, or `None` if chain is not yet that long. + fn dao_rescue_block_gas_limit(&self, chain_hash: H256) -> Option { + const SOFT_FORK_BLOCK: u64 = 1800000; + // shortcut if the canon chain is already known. + if self.chain_info().best_block_number > SOFT_FORK_BLOCK + 1000 { + return self.block_header(BlockID::Number(SOFT_FORK_BLOCK)).map(|header| HeaderView::new(&header).gas_limit()); + } + // otherwise check according to `chain_hash`. + if let Some(mut header) = self.block_header(BlockID::Hash(chain_hash)) { + if HeaderView::new(&header).number() < SOFT_FORK_BLOCK { + None + } else { + while HeaderView::new(&header).number() != SOFT_FORK_BLOCK { + header = self.block_header(BlockID::Hash(HeaderView::new(&header).parent_hash())).expect("chain is complete; parent of chain entry must be in chain; qed"); + } + Some(HeaderView::new(&header).gas_limit()) + } + } else { + None + } + } } /// Extended client interface used for mining pub trait MiningBlockChainClient : BlockChainClient { - /// Attempts to seal given block. Returns `SealedBlock` on success and the same block in case of error. - fn try_seal(&self, block: LockedBlock, seal: Vec) -> Result; - /// Returns OpenBlock prepared for closing. - fn prepare_open_block(&self, author: Address, gas_floor_target: U256, extra_data: Bytes) + fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes) -> OpenBlock; } diff --git a/ethcore/src/client/test_client.rs b/ethcore/src/client/test_client.rs index 14c8b2b67..8f6ee0f70 100644 --- a/ethcore/src/client/test_client.rs +++ b/ethcore/src/client/test_client.rs @@ -29,9 +29,10 @@ use blockchain::extras::BlockReceipts; use error::{ImportResult}; use evm::Factory as EvmFactory; use miner::{Miner, MinerService}; +use spec::Spec; use block_queue::BlockQueueInfo; -use block::{SealedBlock, LockedBlock, OpenBlock}; +use block::OpenBlock; use executive::Executed; use error::{ExecutionError}; use trace::LocalizedTrace; @@ -105,7 +106,7 @@ impl TestBlockChainClient { execution_result: RwLock::new(None), receipts: RwLock::new(HashMap::new()), queue_size: AtomicUsize::new(0), - miner: Arc::new(Miner::default()), + miner: Arc::new(Miner::with_spec(Spec::new_test())), }; client.add_blocks(1, EachBlockWith::Nothing); // add genesis block client.genesis_hash = client.last_hash.read().unwrap().clone(); @@ -187,7 +188,7 @@ impl TestBlockChainClient { txs.append(&signed_tx); txs.out() }, - _ => rlp::NULL_RLP.to_vec() + _ => rlp::EMPTY_LIST_RLP.to_vec() }; let mut rlp = RlpStream::new_list(3); @@ -240,12 +241,7 @@ impl TestBlockChainClient { } impl MiningBlockChainClient for TestBlockChainClient { - fn try_seal(&self, block: LockedBlock, _seal: Vec) -> Result { - Err(block) - } - - - fn prepare_open_block(&self, _author: Address, _gas_floor_target: U256, _extra_data: Bytes) -> OpenBlock { + fn prepare_open_block(&self, _author: Address, _gas_range_target: (U256, U256), _extra_data: Bytes) -> OpenBlock { unimplemented!(); } } @@ -495,11 +491,17 @@ impl BlockChainClient for TestBlockChainClient { balance: balances[a], }; - self.miner.import_transactions(transactions, &fetch_account) + self.miner.import_transactions(self, transactions, &fetch_account) } - fn all_transactions(&self) -> Vec { - self.miner.all_transactions() + fn queue_transactions(&self, transactions: Vec) { + // import right here + let tx = transactions.into_iter().filter_map(|bytes| UntrustedRlp::new(&bytes).as_val().ok()).collect(); + self.import_transactions(tx); + } + + fn pending_transactions(&self) -> Vec { + self.miner.pending_transactions() } fn take_snapshot(&self, _root_dir: &Path) { diff --git a/ethcore/src/engine.rs b/ethcore/src/engine.rs index ed482db89..e78f84c13 100644 --- a/ethcore/src/engine.rs +++ b/ethcore/src/engine.rs @@ -17,7 +17,7 @@ //! Consensus engine specification use common::*; -use util::keys::store::AccountProvider; +use account_provider::AccountProvider; use block::ExecutedBlock; use spec::CommonParams; use evm::Schedule; @@ -96,7 +96,7 @@ pub trait Engine : Sync + Send { /// Don't forget to call Super::populate_from_parent when subclassing & overriding. // TODO: consider including State in the params. - fn populate_from_parent(&self, header: &mut Header, parent: &Header, _gas_floor_target: U256) { + fn populate_from_parent(&self, header: &mut Header, parent: &Header, _gas_floor_target: U256, _gas_ceil_target: U256) { header.difficulty = parent.difficulty; header.gas_limit = parent.gas_limit; header.note_dirty(); diff --git a/ethcore/src/env_info.rs b/ethcore/src/env_info.rs index e6d15cee6..8304fcc03 100644 --- a/ethcore/src/env_info.rs +++ b/ethcore/src/env_info.rs @@ -39,6 +39,9 @@ pub struct EnvInfo { pub last_hashes: LastHashes, /// The gas used. pub gas_used: U256, + + /// Block gas limit at DAO rescue block SOFT_FORK_BLOCK or None if not yet there. + pub dao_rescue_block_gas_limit: Option, } impl Default for EnvInfo { @@ -51,6 +54,7 @@ impl Default for EnvInfo { gas_limit: 0.into(), last_hashes: vec![], gas_used: 0.into(), + dao_rescue_block_gas_limit: None, } } } @@ -66,6 +70,7 @@ impl From for EnvInfo { timestamp: e.timestamp.into(), last_hashes: (1..cmp::min(number + 1, 257)).map(|i| format!("{}", number - i).as_bytes().sha3()).collect(), gas_used: U256::zero(), + dao_rescue_block_gas_limit: None, } } } diff --git a/ethcore/src/error.rs b/ethcore/src/error.rs index b3b929f45..b928fdd19 100644 --- a/ethcore/src/error.rs +++ b/ethcore/src/error.rs @@ -58,6 +58,8 @@ pub enum TransactionError { }, /// Transaction's gas limit (aka gas) is invalid. InvalidGasLimit(OutOfBounds), + /// Transaction is invalid for some other reason. + DAORescue, } impl fmt::Display for TransactionError { @@ -76,6 +78,7 @@ impl fmt::Display for TransactionError { GasLimitExceeded { limit, got } => format!("Gas limit exceeded. Limit={}, Given={}", limit, got), InvalidGasLimit(ref err) => format!("Invalid gas limit. {}", err), + DAORescue => "Transaction is invalid due to the DAO rescue.".into(), }; f.write_fmt(format_args!("Transaction error ({})", msg)) diff --git a/ethcore/src/ethereum/ethash.rs b/ethcore/src/ethereum/ethash.rs index 746da9069..3400220db 100644 --- a/ethcore/src/ethereum/ethash.rs +++ b/ethcore/src/ethereum/ethash.rs @@ -41,6 +41,8 @@ pub struct EthashParams { pub registrar: Address, /// Homestead transition block number. pub frontier_compatibility_mode_limit: u64, + /// Enable the soft-fork logic. + pub dao_rescue_soft_fork: bool, } impl From for EthashParams { @@ -53,6 +55,7 @@ impl From for EthashParams { block_reward: p.block_reward.into(), registrar: p.registrar.into(), frontier_compatibility_mode_limit: p.frontier_compatibility_mode_limit.into(), + dao_rescue_soft_fork: p.dao_rescue_soft_fork.into(), } } } @@ -101,19 +104,28 @@ impl Engine for Ethash { if env_info.number < self.ethash_params.frontier_compatibility_mode_limit { Schedule::new_frontier() } else { - Schedule::new_homestead() + let mut s = Schedule::new_homestead(); + if self.ethash_params.dao_rescue_soft_fork { + s.reject_dao_transactions = env_info.dao_rescue_block_gas_limit.map_or(false, |x| x <= 4_000_000.into()); + } + s } } - fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256) { + fn populate_from_parent(&self, header: &mut Header, parent: &Header, gas_floor_target: U256, gas_ceil_target: U256) { header.difficulty = self.calculate_difficuty(header, parent); header.gas_limit = { let gas_limit = parent.gas_limit; let bound_divisor = self.ethash_params.gas_limit_bound_divisor; if gas_limit < gas_floor_target { min(gas_floor_target, gas_limit + gas_limit / bound_divisor - 1.into()) + } else if gas_limit > gas_ceil_target { + max(gas_ceil_target, gas_limit - gas_limit / bound_divisor + 1.into()) } else { - max(gas_floor_target, gas_limit - gas_limit / bound_divisor + 1.into() + (header.gas_used * 6.into() / 5.into()) / bound_divisor) + min(gas_ceil_target, + max(gas_floor_target, + gas_limit - gas_limit / bound_divisor + 1.into() + + (header.gas_used * 6.into() / 5.into()) / bound_divisor)) } }; header.note_dirty(); @@ -230,8 +242,7 @@ impl Ethash { let mut target = if header.number < frontier_limit { if header.timestamp >= parent.timestamp + duration_limit { parent.difficulty - (parent.difficulty / difficulty_bound_divisor) - } - else { + } else { parent.difficulty + (parent.difficulty / difficulty_bound_divisor) } } @@ -255,12 +266,21 @@ impl Ethash { /// 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) / U256::from(boundary.as_slice()).into()) + let d = U256::from(*boundary); + if d <= U256::one() { + U256::max_value() + } else { + ((U256::one() << 255) / d) << 1 + } } /// Convert an Ethash difficulty to the target boundary. Basically just `f(x) = 2^256 / x`. pub fn difficulty_to_boundary(difficulty: &U256) -> H256 { - U256::from((U512::one() << 256) / difficulty.into()).into() + if *difficulty <= U256::one() { + U256::max_value().into() + } else { + (((U256::one() << 255) / *difficulty) << 1).into() + } } fn to_ethash(hash: H256) -> EH256 { @@ -291,12 +311,11 @@ impl Header { #[cfg(test)] mod tests { - extern crate ethash; - use common::*; use block::*; use tests::helpers::*; use super::super::new_morden; + use super::Ethash; #[test] fn on_close_block() { @@ -308,7 +327,7 @@ mod tests { spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; let vm_factory = Default::default(); - let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), 3141562.into(), vec![]).unwrap(); + let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let b = b.close(); assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap()); } @@ -323,7 +342,7 @@ mod tests { spec.ensure_db_good(db.as_hashdb_mut()); let last_hashes = vec![genesis_header.hash()]; let vm_factory = Default::default(); - let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), 3141562.into(), vec![]).unwrap(); + let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), (3141562.into(), 31415620.into()), vec![]).unwrap(); let mut uncle = Header::new(); let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106"); uncle.author = uncle_author.clone(); @@ -351,7 +370,8 @@ mod tests { difficulty: 0.into(), last_hashes: vec![], gas_used: 0.into(), - gas_limit: 0.into() + gas_limit: 0.into(), + dao_rescue_block_gas_limit: None, }); assert!(schedule.stack_limit > 0); @@ -363,7 +383,8 @@ mod tests { difficulty: 0.into(), last_hashes: vec![], gas_used: 0.into(), - gas_limit: 0.into() + gas_limit: 0.into(), + dao_rescue_block_gas_limit: None, }); assert!(!schedule.have_delegate_call); @@ -509,5 +530,15 @@ mod tests { } } + #[test] + fn test_difficulty_to_boundary() { + // result of f(0) is undefined, so do not assert the result + let _ = Ethash::difficulty_to_boundary(&U256::from(0)); + assert_eq!(Ethash::difficulty_to_boundary(&U256::from(1)), H256::from(U256::max_value())); + assert_eq!(Ethash::difficulty_to_boundary(&U256::from(2)), H256::from_str("8000000000000000000000000000000000000000000000000000000000000000").unwrap()); + assert_eq!(Ethash::difficulty_to_boundary(&U256::from(4)), H256::from_str("4000000000000000000000000000000000000000000000000000000000000000").unwrap()); + assert_eq!(Ethash::difficulty_to_boundary(&U256::from(32)), H256::from_str("0800000000000000000000000000000000000000000000000000000000000000").unwrap()); + } + // TODO: difficulty test } diff --git a/ethcore/src/ethereum/mod.rs b/ethcore/src/ethereum/mod.rs index 9c9e48342..ed75576c6 100644 --- a/ethcore/src/ethereum/mod.rs +++ b/ethcore/src/ethereum/mod.rs @@ -33,7 +33,12 @@ use super::spec::*; pub fn new_olympic() -> Spec { Spec::load(include_bytes!("../../res/ethereum/olympic.json")) } /// Create a new Frontier mainnet chain spec. -pub fn new_frontier() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier.json")) } +pub fn new_frontier(dao_rescue: bool) -> Spec { + Spec::load(match dao_rescue { + true => include_bytes!("../../res/ethereum/frontier_dao_rescue.json"), + false => include_bytes!("../../res/ethereum/frontier.json"), + }) +} /// Create a new Frontier chain spec as though it never changes to Homestead. pub fn new_frontier_test() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier_test.json")) } @@ -84,7 +89,7 @@ mod tests { #[test] fn frontier() { - let frontier = new_frontier(); + let frontier = new_frontier(true); assert_eq!(frontier.state_root(), H256::from_str("d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544").unwrap()); let genesis = frontier.genesis_block(); diff --git a/ethcore/src/evm/jit.rs b/ethcore/src/evm/jit.rs index d46ad917f..4f43d327b 100644 --- a/ethcore/src/evm/jit.rs +++ b/ethcore/src/evm/jit.rs @@ -16,9 +16,8 @@ //! Just in time compiler execution environment. use common::*; -use trace::VMTracer; use evmjit; -use evm::{self, Error, GasLeft}; +use evm::{self, GasLeft}; /// Should be used to convert jit types to ethcore trait FromJit: Sized { @@ -303,7 +302,7 @@ impl<'a> evmjit::Ext for ExtAdapter<'a> { #[derive(Default)] pub struct JitEvm { - ctxt: Option, + context: Option, } impl evm::Evm for JitEvm { @@ -347,7 +346,7 @@ impl evm::Evm for JitEvm { data.timestamp = ext.env_info().timestamp as i64; self.context = Some(unsafe { evmjit::ContextHandle::new(data, schedule, &mut ext_handle) }); - let context = self.context.as_ref_mut().unwrap(); + let mut context = self.context.as_mut().unwrap(); let res = context.exec(); match res { diff --git a/ethcore/src/evm/schedule.rs b/ethcore/src/evm/schedule.rs index f82157239..188e72373 100644 --- a/ethcore/src/evm/schedule.rs +++ b/ethcore/src/evm/schedule.rs @@ -80,6 +80,8 @@ pub struct Schedule { pub tx_data_non_zero_gas: usize, /// Gas price for copying memory pub copy_gas: usize, + /// DAO Rescue softfork block + pub reject_dao_transactions: bool, } impl Schedule { @@ -126,6 +128,7 @@ impl Schedule { tx_data_zero_gas: 4, tx_data_non_zero_gas: 68, copy_gas: 3, + reject_dao_transactions: false, } } } diff --git a/ethcore/src/externalities.rs b/ethcore/src/externalities.rs index 66509440a..80941c4b4 100644 --- a/ethcore/src/externalities.rs +++ b/ethcore/src/externalities.rs @@ -318,7 +318,8 @@ mod tests { difficulty: 0.into(), last_hashes: vec![], gas_used: 0.into(), - gas_limit: 0.into() + gas_limit: 0.into(), + dao_rescue_block_gas_limit: None, } } diff --git a/ethcore/src/json_tests/chain.rs b/ethcore/src/json_tests/chain.rs index 2bee5eb2a..c8e967d76 100644 --- a/ethcore/src/json_tests/chain.rs +++ b/ethcore/src/json_tests/chain.rs @@ -22,6 +22,7 @@ use tests::helpers::*; use devtools::*; use spec::Genesis; use ethjson; +use ethjson::blockchain::BlockChain; use miner::Miner; pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { @@ -41,20 +42,28 @@ pub fn json_chain_test(json_data: &[u8], era: ChainEra) -> Vec { flush!(" - {}...", name); - let mut spec = match era { - ChainEra::Frontier => ethereum::new_frontier_test(), - ChainEra::Homestead => ethereum::new_homestead_test(), + let spec = |blockchain: &BlockChain| { + let genesis = Genesis::from(blockchain.genesis()); + let state = From::from(blockchain.pre_state.clone()); + let mut spec = match era { + ChainEra::Frontier => ethereum::new_frontier_test(), + ChainEra::Homestead => ethereum::new_homestead_test(), + }; + spec.set_genesis_state(state); + spec.overwrite_genesis_params(genesis); + assert!(spec.is_state_root_valid()); + spec }; - let genesis = Genesis::from(blockchain.genesis()); - let state = From::from(blockchain.pre_state.clone()); - spec.set_genesis_state(state); - spec.overwrite_genesis_params(genesis); - assert!(spec.is_state_root_valid()); - let temp = RandomTempPath::new(); { - let client = Client::new(ClientConfig::default(), spec, temp.as_path(), Arc::new(Miner::default()), IoChannel::disconnected()).unwrap(); + let client = Client::new( + ClientConfig::default(), + spec(&blockchain), + temp.as_path(), + Arc::new(Miner::with_spec(spec(&blockchain))), + IoChannel::disconnected() + ).unwrap(); for b in &blockchain.blocks_rlp() { if Block::is_good(&b) { let _ = client.import_block(b.clone()); diff --git a/ethcore/src/lib.rs b/ethcore/src/lib.rs index d34e3a512..6e87b95d1 100644 --- a/ethcore/src/lib.rs +++ b/ethcore/src/lib.rs @@ -91,10 +91,12 @@ extern crate ethjson; extern crate bloomchain; #[macro_use] extern crate ethcore_ipc as ipc; extern crate rayon; +pub extern crate ethstore; #[cfg(test)] extern crate ethcore_devtools as devtools; #[cfg(feature = "jit" )] extern crate evmjit; +pub mod account_provider; pub mod basic_authority; pub mod block; pub mod block_queue; @@ -141,4 +143,4 @@ mod json_tests; pub use types::*; pub use evm::get_info; -pub use executive::contract_address; \ No newline at end of file +pub use executive::contract_address; diff --git a/ethcore/src/miner/miner.rs b/ethcore/src/miner/miner.rs index ceddb31bc..803706c56 100644 --- a/ethcore/src/miner/miner.rs +++ b/ethcore/src/miner/miner.rs @@ -18,7 +18,7 @@ use rayon::prelude::*; use std::sync::atomic::AtomicBool; use util::*; -use util::keys::store::{AccountProvider}; +use account_provider::AccountProvider; use views::{BlockView, HeaderView}; use client::{MiningBlockChainClient, Executive, Executed, EnvInfo, TransactOptions, BlockID, CallAnalytics}; use block::{ClosedBlock, IsBlock}; @@ -29,16 +29,59 @@ use spec::Spec; use engine::Engine; use miner::{MinerService, MinerStatus, TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin}; +/// Different possible definitions for pending transaction set. +#[derive(Debug)] +pub enum PendingSet { + /// Always just the transactions in the queue. These have had only cheap checks. + AlwaysQueue, + /// Always just the transactions in the sealing block. These have had full checks but + /// may be empty if the node is not actively mining or has force_sealing enabled. + AlwaysSealing, + /// Try the sealing block, but if it is not currently sealing, fallback to the queue. + SealingOrElseQueue, +} + +/// Configures the behaviour of the miner. +#[derive(Debug)] +pub struct MinerOptions { + /// Force the miner to reseal, even when nobody has asked for work. + pub force_sealing: bool, + /// Reseal on receipt of new external transactions. + pub reseal_on_external_tx: bool, + /// Reseal on receipt of new local transactions. + pub reseal_on_own_tx: bool, + /// Maximum amount of gas to bother considering for block insertion. + pub tx_gas_limit: U256, + /// Maximum size of the transaction queue. + pub tx_queue_size: usize, + /// Whether we should fallback to providing all the queue's transactions or just pending. + pub pending_set: PendingSet, +} + +impl Default for MinerOptions { + fn default() -> Self { + MinerOptions { + force_sealing: false, + reseal_on_external_tx: true, + reseal_on_own_tx: true, + tx_gas_limit: !U256::zero(), + tx_queue_size: 1024, + pending_set: PendingSet::AlwaysQueue, + } + } +} + /// Keeps track of transactions using priority queue and holds currently mined block. pub struct Miner { + // NOTE [ToDr] When locking always lock in this order! transaction_queue: Mutex, + sealing_work: Mutex>, // for sealing... - force_sealing: bool, + options: MinerOptions, sealing_enabled: AtomicBool, sealing_block_last_request: Mutex, - sealing_work: Mutex>, - gas_floor_target: RwLock, + gas_range_target: RwLock<(U256, U256)>, author: RwLock
, extra_data: RwLock, spec: Spec, @@ -46,52 +89,35 @@ pub struct Miner { accounts: Option>, } -impl Default for Miner { - fn default() -> Miner { +impl Miner { + /// Creates new instance of miner without accounts, but with given spec. + pub fn with_spec(spec: Spec) -> Miner { Miner { transaction_queue: Mutex::new(TransactionQueue::new()), - force_sealing: false, + options: Default::default(), sealing_enabled: AtomicBool::new(false), sealing_block_last_request: Mutex::new(0), sealing_work: Mutex::new(UsingQueue::new(5)), - gas_floor_target: RwLock::new(U256::zero()), - author: RwLock::new(Address::default()), - extra_data: RwLock::new(Vec::new()), - accounts: None, - spec: Spec::new_test(), - } - } -} - -impl Miner { - /// Creates new instance of miner - pub fn new(force_sealing: bool, spec: Spec) -> Arc { - Arc::new(Miner { - transaction_queue: Mutex::new(TransactionQueue::new()), - force_sealing: force_sealing, - sealing_enabled: AtomicBool::new(force_sealing), - sealing_block_last_request: Mutex::new(0), - sealing_work: Mutex::new(UsingQueue::new(5)), - gas_floor_target: RwLock::new(U256::zero()), + gas_range_target: RwLock::new((U256::zero(), U256::zero())), author: RwLock::new(Address::default()), extra_data: RwLock::new(Vec::new()), accounts: None, spec: spec, - }) + } } /// Creates new instance of miner - pub fn with_accounts(force_sealing: bool, spec: Spec, accounts: Arc) -> Arc { + pub fn new(options: MinerOptions, spec: Spec, accounts: Option>) -> Arc { Arc::new(Miner { - transaction_queue: Mutex::new(TransactionQueue::new()), - force_sealing: force_sealing, - sealing_enabled: AtomicBool::new(force_sealing), + transaction_queue: Mutex::new(TransactionQueue::with_limits(options.tx_queue_size, options.tx_gas_limit)), + sealing_enabled: AtomicBool::new(options.force_sealing), + options: options, sealing_block_last_request: Mutex::new(0), sealing_work: Mutex::new(UsingQueue::new(5)), - gas_floor_target: RwLock::new(U256::zero()), + gas_range_target: RwLock::new((U256::zero(), U256::zero())), author: RwLock::new(Address::default()), extra_data: RwLock::new(Vec::new()), - accounts: Some(accounts), + accounts: accounts, spec: spec, }) } @@ -105,34 +131,37 @@ impl Miner { #[cfg_attr(feature="dev", allow(cyclomatic_complexity))] fn prepare_sealing(&self, chain: &MiningBlockChainClient) { trace!(target: "miner", "prepare_sealing: entering"); - let transactions = self.transaction_queue.lock().unwrap().top_transactions(); - let mut sealing_work = self.sealing_work.lock().unwrap(); - let best_hash = chain.best_block_header().sha3(); + let (transactions, mut open_block) = { + let transactions = {self.transaction_queue.lock().unwrap().top_transactions()}; + let mut sealing_work = self.sealing_work.lock().unwrap(); + let best_hash = chain.best_block_header().sha3(); /* - // check to see if last ClosedBlock in would_seals is actually same parent block. - // if so - // duplicate, re-open and push any new transactions. - // if at least one was pushed successfully, close and enqueue new ClosedBlock; - // otherwise, leave everything alone. - // otherwise, author a fresh block. + // check to see if last ClosedBlock in would_seals is actually same parent block. + // if so + // duplicate, re-open and push any new transactions. + // if at least one was pushed successfully, close and enqueue new ClosedBlock; + // otherwise, leave everything alone. + // otherwise, author a fresh block. */ - let mut open_block = match sealing_work.pop_if(|b| b.block().fields().header.parent_hash() == &best_hash) { - Some(old_block) => { - trace!(target: "miner", "Already have previous work; updating and returning"); - // add transactions to old_block - let e = self.engine(); - old_block.reopen(e, chain.vm_factory()) - } - None => { - // block not found - create it. - trace!(target: "miner", "No existing work - making new block"); - chain.prepare_open_block( - self.author(), - self.gas_floor_target(), - self.extra_data() - ) - } + let open_block = match sealing_work.pop_if(|b| b.block().fields().header.parent_hash() == &best_hash) { + Some(old_block) => { + trace!(target: "miner", "Already have previous work; updating and returning"); + // add transactions to old_block + let e = self.engine(); + old_block.reopen(e, chain.vm_factory()) + } + None => { + // block not found - create it. + trace!(target: "miner", "No existing work - making new block"); + chain.prepare_open_block( + self.author(), + (self.gas_floor_target(), self.gas_ceil_target()), + self.extra_data() + ) + } + }; + (transactions, open_block) }; let mut invalid_transactions = HashSet::new(); @@ -162,14 +191,16 @@ impl Miner { let block = open_block.close(); - let mut queue = self.transaction_queue.lock().unwrap(); let fetch_account = |a: &Address| AccountDetails { nonce: chain.latest_nonce(a), balance: chain.latest_balance(a), }; - for hash in invalid_transactions.into_iter() { - queue.remove_invalid(&hash, &fetch_account); + { + let mut queue = self.transaction_queue.lock().unwrap(); + for hash in invalid_transactions.into_iter() { + queue.remove_invalid(&hash, &fetch_account); + } } if !block.transactions().is_empty() { @@ -181,7 +212,7 @@ impl Miner { }); if let Some(seal) = s { trace!(target: "miner", "prepare_sealing: managed internal seal. importing..."); - if let Ok(sealed) = chain.try_seal(block.lock(), seal) { + if let Ok(sealed) = block.lock().try_seal(self.engine(), seal) { if let Ok(_) = chain.import_block(sealed.rlp_bytes()) { trace!(target: "miner", "prepare_sealing: sealed internally and imported. leaving."); } else { @@ -195,6 +226,8 @@ impl Miner { trace!(target: "miner", "prepare_sealing: unable to generate seal internally"); } } + + let mut sealing_work = self.sealing_work.lock().unwrap(); if sealing_work.peek_last_ref().map_or(true, |pb| pb.block().fields().header.hash() != block.block().fields().header.hash()) { trace!(target: "miner", "Pushing a new, refreshed or borrowed pending {}...", block.block().fields().header.hash()); sealing_work.push(block); @@ -266,6 +299,7 @@ impl MinerService for Miner { last_hashes: last_hashes, gas_used: U256::zero(), gas_limit: U256::max_value(), + dao_rescue_block_gas_limit: chain.dao_rescue_block_gas_limit(header.parent_hash().clone()), }; // that's just a copy of the state. let mut state = block.state().clone(); @@ -332,7 +366,11 @@ impl MinerService for Miner { /// Set the gas limit we wish to target when sealing a new block. fn set_gas_floor_target(&self, target: U256) { - *self.gas_floor_target.write().unwrap() = target; + self.gas_range_target.write().unwrap().0 = target; + } + + fn set_gas_ceil_target(&self, target: U256) { + self.gas_range_target.write().unwrap().1 = target; } fn set_minimal_gas_price(&self, min_gas_price: U256) { @@ -349,7 +387,7 @@ impl MinerService for Miner { } fn sensible_gas_limit(&self) -> U256 { - *self.gas_floor_target.read().unwrap() / 5.into() + self.gas_range_target.read().unwrap().0 / 5.into() } fn transactions_limit(&self) -> usize { @@ -360,6 +398,10 @@ impl MinerService for Miner { self.transaction_queue.lock().unwrap().set_limit(limit) } + fn set_tx_gas_limit(&self, limit: U256) { + self.transaction_queue.lock().unwrap().set_tx_gas_limit(limit) + } + /// Get the author that we will seal blocks as. fn author(&self) -> Address { *self.author.read().unwrap() @@ -372,21 +414,36 @@ impl MinerService for Miner { /// Get the gas limit we wish to target when sealing a new block. fn gas_floor_target(&self) -> U256 { - *self.gas_floor_target.read().unwrap() + self.gas_range_target.read().unwrap().0 } - fn import_transactions(&self, transactions: Vec, fetch_account: T) -> + /// Get the gas limit we wish to target when sealing a new block. + fn gas_ceil_target(&self) -> U256 { + self.gas_range_target.read().unwrap().1 + } + + fn import_transactions(&self, chain: &MiningBlockChainClient, transactions: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails { - let mut transaction_queue = self.transaction_queue.lock().unwrap(); - transactions.into_iter() - .map(|tx| transaction_queue.add(tx, &fetch_account, TransactionOrigin::External)) - .collect() + let results: Vec> = { + let mut transaction_queue = self.transaction_queue.lock().unwrap(); + transactions.into_iter() + .map(|tx| transaction_queue.add(tx, &fetch_account, TransactionOrigin::External)) + .collect() + }; + if !results.is_empty() && self.options.reseal_on_external_tx { + self.update_sealing(chain); + } + results } - fn import_own_transaction(&self, chain: &MiningBlockChainClient, transaction: SignedTransaction, fetch_account: T) -> - Result - where T: Fn(&Address) -> AccountDetails { + fn import_own_transaction( + &self, + chain: &MiningBlockChainClient, + transaction: SignedTransaction, + fetch_account: T + ) -> Result where T: Fn(&Address) -> AccountDetails { + let hash = transaction.hash(); trace!(target: "own_tx", "Importing transaction: {:?}", transaction); @@ -409,7 +466,7 @@ impl MinerService for Miner { import }; - if imported.is_ok() { + if imported.is_ok() && self.options.reseal_on_own_tx { // Make sure to do it after transaction is imported and lock is droped. // We need to create pending block and enable sealing let prepared = self.enable_and_prepare_sealing(chain); @@ -423,39 +480,48 @@ impl MinerService for Miner { imported } - fn pending_transactions_hashes(&self) -> Vec { - match (self.sealing_enabled.load(atomic::Ordering::Relaxed), self.sealing_work.lock().unwrap().peek_last_ref()) { - (true, Some(pending)) => pending.transactions().iter().map(|t| t.hash()).collect(), - _ => { - let queue = self.transaction_queue.lock().unwrap(); - queue.pending_hashes() - } - } - } - - fn transaction(&self, hash: &H256) -> Option { - match (self.sealing_enabled.load(atomic::Ordering::Relaxed), self.sealing_work.lock().unwrap().peek_last_ref()) { - (true, Some(pending)) => pending.transactions().iter().find(|t| &t.hash() == hash).cloned(), - _ => { - let queue = self.transaction_queue.lock().unwrap(); - queue.find(hash) - } - } - } - fn all_transactions(&self) -> Vec { let queue = self.transaction_queue.lock().unwrap(); queue.top_transactions() } fn pending_transactions(&self) -> Vec { + let queue = self.transaction_queue.lock().unwrap(); + let sw = self.sealing_work.lock().unwrap(); // TODO: should only use the sealing_work when it's current (it could be an old block) - match (self.sealing_enabled.load(atomic::Ordering::Relaxed), self.sealing_work.lock().unwrap().peek_last_ref()) { - (true, Some(pending)) => pending.transactions().clone(), - _ => { - let queue = self.transaction_queue.lock().unwrap(); - queue.top_transactions() - } + let sealing_set = match self.sealing_enabled.load(atomic::Ordering::Relaxed) { + true => sw.peek_last_ref(), + false => None, + }; + match (&self.options.pending_set, sealing_set) { + (&PendingSet::AlwaysQueue, _) | (&PendingSet::SealingOrElseQueue, None) => queue.top_transactions(), + (_, sealing) => sealing.map_or_else(Vec::new, |s| s.transactions().clone()), + } + } + + fn pending_transactions_hashes(&self) -> Vec { + let queue = self.transaction_queue.lock().unwrap(); + let sw = self.sealing_work.lock().unwrap(); + let sealing_set = match self.sealing_enabled.load(atomic::Ordering::Relaxed) { + true => sw.peek_last_ref(), + false => None, + }; + match (&self.options.pending_set, sealing_set) { + (&PendingSet::AlwaysQueue, _) | (&PendingSet::SealingOrElseQueue, None) => queue.pending_hashes(), + (_, sealing) => sealing.map_or_else(Vec::new, |s| s.transactions().iter().map(|t| t.hash()).collect()), + } + } + + fn transaction(&self, hash: &H256) -> Option { + let queue = self.transaction_queue.lock().unwrap(); + let sw = self.sealing_work.lock().unwrap(); + let sealing_set = match self.sealing_enabled.load(atomic::Ordering::Relaxed) { + true => sw.peek_last_ref(), + false => None, + }; + match (&self.options.pending_set, sealing_set) { + (&PendingSet::AlwaysQueue, _) | (&PendingSet::SealingOrElseQueue, None) => queue.find(hash), + (_, sealing) => sealing.and_then(|s| s.transactions().iter().find(|t| &t.hash() == hash).cloned()), } } @@ -483,7 +549,7 @@ impl MinerService for Miner { let current_no = chain.chain_info().best_block_number; let has_local_transactions = self.transaction_queue.lock().unwrap().has_local_pending_transactions(); let last_request = *self.sealing_block_last_request.lock().unwrap(); - let should_disable_sealing = !self.force_sealing + let should_disable_sealing = !self.options.force_sealing && !has_local_transactions && current_no > last_request && current_no - last_request > SEALING_TIMEOUT_IN_BLOCKS; @@ -492,7 +558,7 @@ impl MinerService for Miner { trace!(target: "miner", "Miner sleeping (current {}, last {})", current_no, last_request); self.sealing_enabled.store(false, atomic::Ordering::Relaxed); self.sealing_work.lock().unwrap().reset(); - } else if self.sealing_enabled.load(atomic::Ordering::Relaxed) { + } else { self.prepare_sealing(chain); } } @@ -510,7 +576,7 @@ impl MinerService for Miner { fn submit_seal(&self, chain: &MiningBlockChainClient, pow_hash: H256, seal: Vec) -> Result<(), Error> { if let Some(b) = self.sealing_work.lock().unwrap().take_used_if(|b| &b.hash() == &pow_hash) { - match chain.try_seal(b.lock(), seal) { + match b.lock().try_seal(self.engine(), seal) { Err(_) => { info!(target: "miner", "Mined block rejected, PoW was invalid."); Err(Error::PowInvalid) @@ -559,7 +625,7 @@ impl MinerService for Miner { for tx in &txs { let _sender = tx.sender(); } - let _ = self.import_transactions(txs, |a| AccountDetails { + let _ = self.import_transactions(chain, txs, |a| AccountDetails { nonce: chain.latest_nonce(a), balance: chain.latest_balance(a), }); @@ -598,6 +664,7 @@ mod tests { use util::*; use client::{TestBlockChainClient, EachBlockWith}; use block::*; + use spec::Spec; // TODO [ToDr] To uncomment` when TestBlockChainClient can actually return a ClosedBlock. #[ignore] @@ -605,7 +672,7 @@ mod tests { fn should_prepare_block_to_seal() { // given let client = TestBlockChainClient::default(); - let miner = Miner::default(); + let miner = Miner::with_spec(Spec::new_test()); // when let sealing_work = miner.map_sealing_work(&client, |_| ()); @@ -617,7 +684,7 @@ mod tests { fn should_still_work_after_a_couple_of_blocks() { // given let client = TestBlockChainClient::default(); - let miner = Miner::default(); + let miner = Miner::with_spec(Spec::new_test()); let res = miner.map_sealing_work(&client, |b| b.block().fields().header.hash()); assert!(res.is_some()); diff --git a/ethcore/src/miner/mod.rs b/ethcore/src/miner/mod.rs index 71727f51d..e65d6048a 100644 --- a/ethcore/src/miner/mod.rs +++ b/ethcore/src/miner/mod.rs @@ -28,11 +28,12 @@ //! extern crate ethcore; //! use std::env; //! use util::network::{NetworkService, NetworkConfiguration}; +//! use ethcore::ethereum; //! use ethcore::client::{Client, ClientConfig}; //! use ethcore::miner::{Miner, MinerService}; //! //! fn main() { -//! let miner: Miner = Miner::default(); +//! let miner: Miner = Miner::with_spec(ethereum::new_frontier(true)); //! // get status //! assert_eq!(miner.status().transactions_in_pending_queue, 0); //! @@ -46,7 +47,7 @@ mod external; mod transaction_queue; pub use self::transaction_queue::{TransactionQueue, AccountDetails, TransactionImportResult, TransactionOrigin}; -pub use self::miner::{Miner}; +pub use self::miner::{Miner, MinerOptions, PendingSet}; pub use self::external::{ExternalMiner, ExternalMinerService}; use std::collections::BTreeMap; @@ -81,20 +82,30 @@ pub trait MinerService : Send + Sync { /// Set minimal gas price of transaction to be accepted for mining. fn set_minimal_gas_price(&self, min_gas_price: U256); - /// Get the gas limit we wish to target when sealing a new block. + /// Get the lower bound of the gas limit we wish to target when sealing a new block. fn gas_floor_target(&self) -> U256; - /// Set the gas limit we wish to target when sealing a new block. + /// Get the upper bound of the gas limit we wish to target when sealing a new block. + fn gas_ceil_target(&self) -> U256; + + // TODO: coalesce into single set_range function. + /// Set the lower bound of gas limit we wish to target when sealing a new block. fn set_gas_floor_target(&self, target: U256); + /// Set the upper bound of gas limit we wish to target when sealing a new block. + fn set_gas_ceil_target(&self, target: U256); + /// Get current transactions limit in queue. fn transactions_limit(&self) -> usize; /// Set maximal number of transactions kept in the queue (both current and future). fn set_transactions_limit(&self, limit: usize); + /// Set maximum amount of gas allowed for any single transaction to mine. + fn set_tx_gas_limit(&self, limit: U256); + /// Imports transactions to transaction queue. - fn import_transactions(&self, transactions: Vec, fetch_account: T) -> + fn import_transactions(&self, chain: &MiningBlockChainClient, transactions: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails, Self: Sized; diff --git a/ethcore/src/miner/transaction_queue.rs b/ethcore/src/miner/transaction_queue.rs index 8f34d78d1..17ca18272 100644 --- a/ethcore/src/miner/transaction_queue.rs +++ b/ethcore/src/miner/transaction_queue.rs @@ -167,16 +167,17 @@ impl PartialOrd for TransactionOrder { impl Ord for TransactionOrder { fn cmp(&self, b: &TransactionOrder) -> Ordering { - // Local transactions should always have priority - if self.origin != b.origin { - return self.origin.cmp(&b.origin); - } - // First check nonce_height if self.nonce_height != b.nonce_height { return self.nonce_height.cmp(&b.nonce_height); } + // Local transactions should always have priority + // NOTE nonce has to be checked first, cause otherwise the order might be wrong. + if self.origin != b.origin { + return self.origin.cmp(&b.origin); + } + // Then compare gas_prices let a_gas = self.gas_price; let b_gas = b.gas_price; @@ -235,22 +236,22 @@ impl TransactionSet { self.by_priority.insert(order.clone()); let r = self.by_address.insert(sender, nonce, order); // If transaction was replaced remove it from priority queue - if let Some(ref order) = r { - self.by_priority.remove(order); + if let Some(ref old_order) = r { + self.by_priority.remove(old_order); } + assert_eq!(self.by_priority.len(), self.by_address.len()); r } /// Remove low priority transactions if there is more then specified by given `limit`. /// /// It drops transactions from this set but also removes associated `VerifiedTransaction`. - /// Returns addresses and highes nonces of transactions removed because of limit. + /// Returns addresses and lowest nonces of transactions removed because of limit. fn enforce_limit(&mut self, by_hash: &mut HashMap) -> Option> { let len = self.by_priority.len(); if len <= self.limit { return None; } - let to_drop : Vec<(Address, U256)> = { self.by_priority .iter() @@ -269,8 +270,8 @@ impl TransactionSet { by_hash.remove(&order.hash) .expect("Hash found in `by_priorty` matches the one dropped; so it is included in `by_hash`"); - let max = removed.get(&sender).map_or(nonce, |val| cmp::max(*val, nonce)); - removed.insert(sender, max); + let min = removed.get(&sender).map_or(nonce, |val| cmp::min(*val, nonce)); + removed.insert(sender, min); removed })) } @@ -279,8 +280,10 @@ impl TransactionSet { fn drop(&mut self, sender: &Address, nonce: &U256) -> Option { if let Some(tx_order) = self.by_address.remove(sender, nonce) { self.by_priority.remove(&tx_order); + assert_eq!(self.by_priority.len(), self.by_address.len()); return Some(tx_order); } + assert_eq!(self.by_priority.len(), self.by_address.len()); None } @@ -331,6 +334,8 @@ const GAS_LIMIT_HYSTERESIS: usize = 10; // % pub struct TransactionQueue { /// Gas Price threshold for transactions that can be imported to this queue (defaults to 0) minimal_gas_price: U256, + /// The maximum amount of gas any individual transaction may use. + tx_gas_limit: U256, /// Current gas limit (block gas limit * factor). Transactions above the limit will not be accepted (default to !0) gas_limit: U256, /// Priority queue for transactions that can go to block @@ -352,11 +357,11 @@ impl Default for TransactionQueue { impl TransactionQueue { /// Creates new instance of this Queue pub fn new() -> Self { - Self::with_limit(1024) + Self::with_limits(1024, !U256::zero()) } /// Create new instance of this Queue with specified limits - pub fn with_limit(limit: usize) -> Self { + pub fn with_limits(limit: usize, tx_gas_limit: U256) -> Self { let current = TransactionSet { by_priority: BTreeSet::new(), by_address: Table::new(), @@ -371,6 +376,7 @@ impl TransactionQueue { TransactionQueue { minimal_gas_price: U256::zero(), + tx_gas_limit: tx_gas_limit, gas_limit: !U256::zero(), current: current, future: future, @@ -415,6 +421,12 @@ impl TransactionQueue { }; } + /// Set the new limit for the amount of gas any individual transaction may have. + /// Any transaction already imported to the queue is not affected. + pub fn set_tx_gas_limit(&mut self, limit: U256) { + self.tx_gas_limit = limit; + } + /// Returns current status for this queue pub fn status(&self) -> TransactionQueueStatus { TransactionQueueStatus { @@ -425,14 +437,16 @@ impl TransactionQueue { /// Add signed transaction to queue to be verified and imported pub fn add(&mut self, tx: SignedTransaction, fetch_account: &T, origin: TransactionOrigin) -> Result - where T: Fn(&Address) -> AccountDetails { + where T: Fn(&Address) -> AccountDetails { trace!(target: "miner", "Importing: {:?}", tx.hash()); if tx.gas_price < self.minimal_gas_price { trace!(target: "miner", "Dropping transaction below minimal gas price threshold: {:?} (gp: {} < {})", - tx.hash(), tx.gas_price, self.minimal_gas_price + tx.hash(), + tx.gas_price, + self.minimal_gas_price ); return Err(Error::Transaction(TransactionError::InsufficientGasPrice { @@ -443,10 +457,13 @@ impl TransactionQueue { try!(tx.check_low_s()); - if tx.gas > self.gas_limit { + if tx.gas > self.gas_limit || tx.gas > self.tx_gas_limit { trace!(target: "miner", - "Dropping transaction above gas limit: {:?} ({} > {})", - tx.hash(), tx.gas, self.gas_limit + "Dropping transaction above gas limit: {:?} ({} > min({}, {}))", + tx.hash(), + tx.gas, + self.gas_limit, + self.tx_gas_limit ); return Err(Error::Transaction(TransactionError::GasLimitExceeded { @@ -460,15 +477,22 @@ impl TransactionQueue { let cost = vtx.transaction.value + vtx.transaction.gas_price * vtx.transaction.gas; if client_account.balance < cost { - trace!(target: "miner", "Dropping transaction without sufficient balance: {:?} ({} < {})", - vtx.hash(), client_account.balance, cost); + trace!(target: "miner", + "Dropping transaction without sufficient balance: {:?} ({} < {})", + vtx.hash(), + client_account.balance, + cost + ); + return Err(Error::Transaction(TransactionError::InsufficientBalance { cost: cost, balance: client_account.balance })); } - self.import_tx(vtx, client_account.nonce).map_err(Error::Transaction) + let r = self.import_tx(vtx, client_account.nonce).map_err(Error::Transaction); + assert_eq!(self.future.by_priority.len() + self.current.by_priority.len(), self.by_hash.len()); + r } /// Removes all transactions from particular sender up to (excluding) given client (state) nonce. @@ -484,6 +508,7 @@ impl TransactionQueue { // And now lets check if there is some batch of transactions in future // that should be placed in current. It should also update last_nonces. self.move_matching_future_to_current(sender, client_nonce, client_nonce); + assert_eq!(self.future.by_priority.len() + self.current.by_priority.len(), self.by_hash.len()); } /// Removes invalid transaction identified by hash from queue. @@ -493,6 +518,8 @@ impl TransactionQueue { /// If gap is introduced marks subsequent transactions as future pub fn remove_invalid(&mut self, transaction_hash: &H256, fetch_account: &T) where T: Fn(&Address) -> AccountDetails { + + assert_eq!(self.future.by_priority.len() + self.current.by_priority.len(), self.by_hash.len()); let transaction = self.by_hash.remove(transaction_hash); if transaction.is_none() { // We don't know this transaction @@ -511,22 +538,17 @@ impl TransactionQueue { // And now lets check if there is some chain of transactions in future // that should be placed in current self.move_matching_future_to_current(sender, current_nonce, current_nonce); + assert_eq!(self.future.by_priority.len() + self.current.by_priority.len(), self.by_hash.len()); return; } // Remove from current let order = self.current.drop(&sender, &nonce); if order.is_some() { - // We will either move transaction to future or remove it completely - // so there will be no transactions from this sender in current - self.last_nonces.remove(&sender); - // First update height of transactions in future to avoid collisions - self.update_future(&sender, current_nonce); - // This should move all current transactions to future and remove old transactions - self.move_all_to_future(&sender, current_nonce); - // And now lets check if there is some chain of transactions in future - // that should be placed in current. It should also update last_nonces. - self.move_matching_future_to_current(sender, current_nonce, current_nonce); + // This will keep consistency in queue + // Moves all to future and then promotes a batch from current: + self.remove_all(sender, current_nonce); + assert_eq!(self.future.by_priority.len() + self.current.by_priority.len(), self.by_hash.len()); return; } } @@ -545,7 +567,7 @@ impl TransactionQueue { } else { trace!(target: "miner", "Removing old transaction: {:?} (nonce: {} < {})", order.hash, k, current_nonce); // Remove the transaction completely - self.by_hash.remove(&order.hash); + self.by_hash.remove(&order.hash).expect("All transactions in `future` are also in `by_hash`"); } } } @@ -565,7 +587,7 @@ impl TransactionQueue { self.future.insert(*sender, k, order.update_height(k, current_nonce)); } else { trace!(target: "miner", "Removing old transaction: {:?} (nonce: {} < {})", order.hash, k, current_nonce); - self.by_hash.remove(&order.hash); + self.by_hash.remove(&order.hash).expect("All transactions in `future` are also in `by_hash`"); } } self.future.enforce_limit(&mut self.by_hash); @@ -664,21 +686,27 @@ impl TransactionQueue { .cloned() .map_or(state_nonce, |n| n + U256::one()); - // Check height - if nonce > next_nonce { - // We have a gap - put to future - try!(check_too_cheap(Self::replace_transaction(tx, next_nonce, &mut self.future, &mut self.by_hash))); - try!(check_if_removed(&address, &nonce, self.future.enforce_limit(&mut self.by_hash))); - return Ok(TransactionImportResult::Future); - } else if nonce < state_nonce { + // The transaction might be old, let's check that. + // This has to be the first test, otherwise calculating + // nonce height would result in overflow. + if nonce < state_nonce { // Droping transaction trace!(target: "miner", "Dropping old transaction: {:?} (nonce: {} < {})", tx.hash(), nonce, next_nonce); return Err(TransactionError::Old); + } else if nonce > next_nonce { + // We have a gap - put to future. + // Update nonces of transactions in future (remove old transactions) + self.update_future(&address, state_nonce); + // Insert transaction (or replace old one with lower gas price) + try!(check_too_cheap(Self::replace_transaction(tx, state_nonce, &mut self.future, &mut self.by_hash))); + // Return an error if this transaction is not imported because of limit. + try!(check_if_removed(&address, &nonce, self.future.enforce_limit(&mut self.by_hash))); + return Ok(TransactionImportResult::Future); } - try!(check_too_cheap(Self::replace_transaction(tx, state_nonce, &mut self.current, &mut self.by_hash))); // Keep track of highest nonce stored in current - self.last_nonces.insert(address, nonce); + let new_max = self.last_nonces.get(&address).map_or(nonce, |n| cmp::max(nonce, *n)); + self.last_nonces.insert(address, new_max); // Update nonces of transactions in future self.update_future(&address, state_nonce); // Maybe there are some more items waiting in future? @@ -687,15 +715,16 @@ impl TransactionQueue { // same (sender, nonce), but above function would not move it. if let Some(order) = self.future.drop(&address, &nonce) { // Let's insert that transaction to current (if it has higher gas_price) - let future_tx = self.by_hash.remove(&order.hash).unwrap(); - try!(check_too_cheap(Self::replace_transaction(future_tx, state_nonce, &mut self.current, &mut self.by_hash))); + let future_tx = self.by_hash.remove(&order.hash).expect("All transactions in `future` are always in `by_hash`."); + // if transaction in `current` (then one we are importing) is replaced it means that it has to low gas_price + try!(check_too_cheap(!Self::replace_transaction(future_tx, state_nonce, &mut self.current, &mut self.by_hash))); } // Also enforce the limit let removed = self.current.enforce_limit(&mut self.by_hash); // If some transaction were removed because of limit we need to update last_nonces also. self.update_last_nonces(&removed); - // Trigger error if we were removed. + // Trigger error if the transaction we are importing was removed. try!(check_if_removed(&address, &nonce, removed)); trace!(target: "miner", "status: {:?}", self.status()); @@ -703,9 +732,9 @@ impl TransactionQueue { } /// Updates - fn update_last_nonces(&mut self, removed_max_nonces: &Option>) { - if let Some(ref max_nonces) = *removed_max_nonces { - for (sender, nonce) in max_nonces.iter() { + fn update_last_nonces(&mut self, removed_min_nonces: &Option>) { + if let Some(ref min_nonces) = *removed_min_nonces { + for (sender, nonce) in min_nonces.iter() { if *nonce == U256::zero() { self.last_nonces.remove(sender); } else { @@ -728,7 +757,9 @@ impl TransactionQueue { let address = tx.sender(); let nonce = tx.nonce(); - by_hash.insert(hash, tx); + let old_hash = by_hash.insert(hash, tx); + assert!(old_hash.is_none(), "Each hash has to be inserted exactly once."); + if let Some(old) = set.insert(address, nonce, order.clone()) { // There was already transaction in queue. Let's check which one should stay @@ -738,11 +769,11 @@ impl TransactionQueue { // Put back old transaction since it has greater priority (higher gas_price) set.insert(address, nonce, old); // and remove new one - by_hash.remove(&hash); + by_hash.remove(&hash).expect("The hash has been just inserted and no other line is altering `by_hash`."); false } else { // Make sure we remove old transaction entirely - by_hash.remove(&old.hash); + by_hash.remove(&old.hash).expect("The hash is coming from `future` so it has to be in `by_hash`."); true } } else { @@ -762,7 +793,7 @@ fn check_too_cheap(is_in: bool) -> Result<(), TransactionError> { fn check_if_removed(sender: &Address, nonce: &U256, dropped: Option>) -> Result<(), TransactionError> { match dropped { Some(ref dropped) => match dropped.get(sender) { - Some(max) if nonce <= max => { + Some(min) if nonce >= min => { Err(TransactionError::LimitReached) }, _ => Ok(()), @@ -939,7 +970,7 @@ mod test { let res = txq.add(tx2.clone(), &default_nonce, TransactionOrigin::External); // and then there should be only one transaction in current (the one with higher gas_price) - assert_eq!(unwrap_tx_err(res), TransactionError::TooCheapToReplace); + assert_eq!(res.unwrap(), TransactionImportResult::Current); assert_eq!(txq.status().pending, 1); assert_eq!(txq.status().future, 0); assert_eq!(txq.current.by_priority.len(), 1); @@ -1087,7 +1118,28 @@ mod test { } #[test] - fn should_prioritize_local_transactions() { + fn should_prioritize_local_transactions_within_same_nonce_height() { + // given + let mut txq = TransactionQueue::new(); + let tx = new_tx(); + // the second one has same nonce but higher `gas_price` + let (_, tx2) = new_similar_txs(); + + // when + // first insert the one with higher gas price + txq.add(tx2.clone(), &default_nonce, TransactionOrigin::External).unwrap(); + // then the one with lower gas price, but local + txq.add(tx.clone(), &default_nonce, TransactionOrigin::Local).unwrap(); + + // then + let top = txq.top_transactions(); + assert_eq!(top[0], tx); // local should be first + assert_eq!(top[1], tx2); + assert_eq!(top.len(), 2); + } + + #[test] + fn should_not_prioritize_local_transactions_with_different_nonce_height() { // given let mut txq = TransactionQueue::new(); let (tx, tx2) = new_txs(U256::from(1)); @@ -1098,8 +1150,8 @@ mod test { // then let top = txq.top_transactions(); - assert_eq!(top[0], tx2); - assert_eq!(top[1], tx); + assert_eq!(top[0], tx); + assert_eq!(top[1], tx2); assert_eq!(top.len(), 2); } @@ -1255,7 +1307,7 @@ mod test { #[test] fn should_drop_old_transactions_when_hitting_the_limit() { // given - let mut txq = TransactionQueue::with_limit(1); + let mut txq = TransactionQueue::with_limits(1, !U256::zero()); let (tx, tx2) = new_txs(U256::one()); let sender = tx.sender().unwrap(); let nonce = tx.nonce; @@ -1277,7 +1329,7 @@ mod test { #[test] fn should_return_correct_nonces_when_dropped_because_of_limit() { // given - let mut txq = TransactionQueue::with_limit(2); + let mut txq = TransactionQueue::with_limits(2, !U256::zero()); let tx = new_tx(); let (tx1, tx2) = new_txs(U256::one()); let sender = tx1.sender().unwrap(); @@ -1298,7 +1350,7 @@ mod test { #[test] fn should_limit_future_transactions() { - let mut txq = TransactionQueue::with_limit(1); + let mut txq = TransactionQueue::with_limits(1, !U256::zero()); txq.current.set_limit(10); let (tx1, tx2) = new_txs_with_gas_price_diff(U256::from(4), U256::from(1)); let (tx3, tx4) = new_txs_with_gas_price_diff(U256::from(4), U256::from(2)); @@ -1555,4 +1607,54 @@ mod test { assert_eq!(txq.has_local_pending_transactions(), true); } + #[test] + fn should_keep_right_order_in_future() { + // given + let mut txq = TransactionQueue::with_limits(1, !U256::zero()); + let (tx1, tx2) = new_txs(U256::from(1)); + let prev_nonce = |a: &Address| AccountDetails { nonce: default_nonce(a).nonce - U256::one(), balance: + default_nonce(a).balance }; + + // when + assert_eq!(txq.add(tx2, &prev_nonce, TransactionOrigin::External).unwrap(), TransactionImportResult::Future); + assert_eq!(txq.add(tx1.clone(), &prev_nonce, TransactionOrigin::External).unwrap(), TransactionImportResult::Future); + + // then + assert_eq!(txq.future.by_priority.len(), 1); + assert_eq!(txq.future.by_priority.iter().next().unwrap().hash, tx1.hash()); + } + + #[test] + fn should_return_correct_last_nonce() { + // given + let mut txq = TransactionQueue::new(); + let (tx1, tx2, tx2_2, tx3) = { + let keypair = KeyPair::create().unwrap(); + let secret = &keypair.secret(); + let nonce = U256::from(123); + let tx = new_unsigned_tx(nonce); + let tx2 = new_unsigned_tx(nonce + 1.into()); + let mut tx2_2 = new_unsigned_tx(nonce + 1.into()); + tx2_2.gas_price = U256::from(5); + let tx3 = new_unsigned_tx(nonce + 2.into()); + + + (tx.sign(secret), tx2.sign(secret), tx2_2.sign(secret), tx3.sign(secret)) + }; + let sender = tx1.sender().unwrap(); + txq.add(tx1, &default_nonce, TransactionOrigin::Local).unwrap(); + txq.add(tx2, &default_nonce, TransactionOrigin::Local).unwrap(); + txq.add(tx3, &default_nonce, TransactionOrigin::Local).unwrap(); + assert_eq!(txq.future.by_priority.len(), 0); + assert_eq!(txq.current.by_priority.len(), 3); + + // when + let res = txq.add(tx2_2, &default_nonce, TransactionOrigin::Local); + + // then + assert_eq!(txq.last_nonce(&sender).unwrap(), 125.into()); + assert_eq!(res.unwrap(), TransactionImportResult::Current); + assert_eq!(txq.current.by_priority.len(), 3); + } + } diff --git a/ethcore/src/service.rs b/ethcore/src/service.rs index 13f1c9f74..98fb3ad23 100644 --- a/ethcore/src/service.rs +++ b/ethcore/src/service.rs @@ -41,6 +41,12 @@ pub enum SyncMessage { NewChainHead, /// A block is ready BlockVerified, + /// New transaction RLPs are ready to be imported + NewTransactions(Vec), + /// Start network command. + StartNetwork, + /// Stop network command. + StopNetwork, } /// IO Message type used for Network service @@ -48,17 +54,20 @@ pub type NetSyncMessage = NetworkIoMessage; /// Client service setup. Creates and registers client and network services with the IO subsystem. pub struct ClientService { - net_service: NetworkService, + net_service: Arc>, client: Arc, panic_handler: Arc } impl ClientService { /// Start the service in a separate thread. - pub fn start(config: ClientConfig, spec: Spec, net_config: NetworkConfiguration, db_path: &Path, miner: Arc) -> Result { + pub fn start(config: ClientConfig, spec: Spec, net_config: NetworkConfiguration, db_path: &Path, miner: Arc, enable_network: bool) -> Result { let panic_handler = PanicHandler::new_in_arc(); - let mut net_service = try!(NetworkService::start(net_config)); + let net_service = try!(NetworkService::new(net_config)); panic_handler.forward_from(&net_service); + if enable_network { + try!(net_service.start()); + } info!("Starting {}", net_service.host_info()); info!("Configured for {} using {:?} engine", spec.name, spec.engine.name()); @@ -70,7 +79,7 @@ impl ClientService { try!(net_service.io().register_handler(client_io)); Ok(ClientService { - net_service: net_service, + net_service: Arc::new(net_service), client: client, panic_handler: panic_handler, }) @@ -82,8 +91,8 @@ impl ClientService { } /// Get general IO interface - pub fn io(&mut self) -> &mut IoService { - self.net_service.io() + pub fn register_io_handler(&self, handler: Arc + Send>) -> Result<(), IoError> { + self.net_service.io().register_handler(handler) } /// Get client interface @@ -92,8 +101,8 @@ impl ClientService { } /// Get network service component - pub fn network(&mut self) -> &mut NetworkService { - &mut self.net_service + pub fn network(&mut self) -> Arc> { + self.net_service.clone() } } @@ -129,6 +138,9 @@ impl IoHandler for ClientIoHandler { SyncMessage::BlockVerified => { self.client.import_verified_blocks(&io.channel()); }, + SyncMessage::NewTransactions(ref transactions) => { + self.client.import_queued_transactions(&transactions); + }, _ => {}, // ignore other messages } } @@ -147,9 +159,15 @@ mod tests { #[test] fn it_can_be_started() { - let spec = get_test_spec(); let temp_path = RandomTempPath::new(); - let service = ClientService::start(ClientConfig::default(), spec, NetworkConfiguration::new_local(), &temp_path.as_path(), Arc::new(Miner::default())); + let service = ClientService::start( + ClientConfig::default(), + get_test_spec(), + NetworkConfiguration::new_local(), + &temp_path.as_path(), + Arc::new(Miner::with_spec(get_test_spec())), + false + ); assert!(service.is_ok()); } } diff --git a/ethcore/src/snapshot/account.rs b/ethcore/src/snapshot/account.rs index d39c612e8..36ff2662a 100644 --- a/ethcore/src/snapshot/account.rs +++ b/ethcore/src/snapshot/account.rs @@ -85,7 +85,7 @@ impl Account { if self.code_hash == SHA3_EMPTY { account_stream.append(&false).append_empty_data(); } else { - match acct_db.lookup(&self.code_hash) { + match acct_db.get(&self.code_hash) { Some(c) => { account_stream.append(&true).append(&c); } diff --git a/ethcore/src/spec/spec.rs b/ethcore/src/spec/spec.rs index 743f1bd9b..02b311b24 100644 --- a/ethcore/src/spec/spec.rs +++ b/ethcore/src/spec/spec.rs @@ -244,6 +244,11 @@ impl Spec { pub fn new_test() -> Spec { Spec::load(include_bytes!("../../res/null_morden.json")) } + + /// Create a new Spec which is a NullEngine consensus with a premine of address whose secret is sha3(''). + pub fn new_null() -> Spec { + Spec::load(include_bytes!("../../res/null.json")) + } } #[cfg(test)] diff --git a/ethcore/src/state.rs b/ethcore/src/state.rs index 204cea618..e7981abba 100644 --- a/ethcore/src/state.rs +++ b/ethcore/src/state.rs @@ -222,6 +222,30 @@ impl State { let options = TransactOptions { tracing: tracing, vm_tracing: false, check_nonce: true }; let e = try!(Executive::new(self, env_info, engine, vm_factory).transact(t, options)); + let broken_dao = H256::from("6a5d24750f78441e56fec050dc52fe8e911976485b7472faac7464a176a67caa"); + + // dao attack soft fork + if engine.schedule(&env_info).reject_dao_transactions { + let whitelisted = if let Action::Call(to) = t.action { + to == Address::from("Da4a4626d3E16e094De3225A751aAb7128e96526") || + to == Address::from("2ba9D006C1D72E67A70b5526Fc6b4b0C0fd6D334") + } else { false }; + if !whitelisted { + // collect all the addresses which have changed. + let addresses = self.cache.borrow().iter().map(|(addr, _)| addr.clone()).collect::>(); + + for a in &addresses { + if self.code(a).map_or(false, |c| c.sha3() == broken_dao) { + // Figure out if the balance has been reduced. + let maybe_original = SecTrieDB::new(self.db.as_hashdb(), &self.root).expect(SEC_TRIE_DB_UNWRAP_STR).get(&a).map(Account::from_rlp); + if maybe_original.map_or(false, |original| *original.balance() > self.balance(a)) { + return Err(Error::Transaction(TransactionError::DAORescue)); + } + } + } + } + } + // TODO uncomment once to_pod() works correctly. // trace!("Applied transaction. Diff:\n{}\n", state_diff::diff_pod(&old, &self.to_pod())); self.commit(); diff --git a/ethcore/src/tests/client.rs b/ethcore/src/tests/client.rs index 789943942..63302cb30 100644 --- a/ethcore/src/tests/client.rs +++ b/ethcore/src/tests/client.rs @@ -24,7 +24,7 @@ use miner::Miner; #[test] fn imports_from_empty() { let dir = RandomTempPath::new(); - let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::default()), IoChannel::disconnected()).unwrap(); + let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::with_spec(get_test_spec())), IoChannel::disconnected()).unwrap(); client.import_verified_blocks(&IoChannel::disconnected()); client.flush_queue(); } @@ -42,7 +42,7 @@ fn returns_state_root_basic() { #[test] fn imports_good_block() { let dir = RandomTempPath::new(); - let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::default()), IoChannel::disconnected()).unwrap(); + let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::with_spec(get_test_spec())), IoChannel::disconnected()).unwrap(); let good_block = get_good_dummy_block(); if let Err(_) = client.import_block(good_block) { panic!("error importing block being good by definition"); @@ -57,7 +57,7 @@ fn imports_good_block() { #[test] fn query_none_block() { let dir = RandomTempPath::new(); - let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::default()), IoChannel::disconnected()).unwrap(); + let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::with_spec(get_test_spec())), IoChannel::disconnected()).unwrap(); let non_existant = client.block_header(BlockID::Number(188)); assert!(non_existant.is_none()); @@ -112,6 +112,19 @@ fn can_collect_garbage() { assert!(client.blockchain_cache_info().blocks < 100 * 1024); } +#[test] +#[cfg_attr(feature="dev", allow(useless_vec))] +fn can_generate_gas_price_statistics() { + let client_result = generate_dummy_client_with_data(16, 1, &vec_into![0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); + let client = client_result.reference(); + let s = client.gas_price_statistics(8, 8).unwrap(); + assert_eq!(s, vec_into![8, 8, 9, 10, 11, 12, 13, 14, 15]); + let s = client.gas_price_statistics(16, 8).unwrap(); + assert_eq!(s, vec_into![0, 1, 3, 5, 7, 9, 11, 13, 15]); + let s = client.gas_price_statistics(32, 8).unwrap(); + assert_eq!(s, vec_into![0, 1, 3, 5, 7, 9, 11, 13, 15]); +} + #[test] fn can_handle_long_fork() { let client_result = generate_dummy_client(1200); @@ -137,8 +150,7 @@ fn can_mine() { let client_result = get_test_client_with_blocks(vec![dummy_blocks[0].clone()]); let client = client_result.reference(); - let b = client.prepare_open_block(Address::default(), 31415926.into(), vec![]).close(); + let b = client.prepare_open_block(Address::default(), (3141562.into(), 31415620.into()), vec![]).close(); assert_eq!(*b.block().header().parent_hash(), BlockView::new(&dummy_blocks[0]).header_view().sha3()); - assert!(client.try_seal(b.lock(), vec![]).is_ok()); } diff --git a/ethcore/src/tests/helpers.rs b/ethcore/src/tests/helpers.rs index 3b27ef4a4..15b346919 100644 --- a/ethcore/src/tests/helpers.rs +++ b/ethcore/src/tests/helpers.rs @@ -17,6 +17,7 @@ use client::{BlockChainClient, Client, ClientConfig}; use common::*; use spec::*; +use block::{OpenBlock}; use blockchain::{BlockChain, Config as BlockChainConfig}; use state::*; use evm::Schedule; @@ -85,6 +86,7 @@ impl Engine for TestEngine { } } +// TODO: move everything over to get_null_spec. pub fn get_test_spec() -> Spec { Spec::new_test() } @@ -126,7 +128,7 @@ fn create_unverifiable_block(order: u32, parent_hash: H256) -> Bytes { create_test_block(&create_unverifiable_block_header(order, parent_hash)) } -pub fn create_test_block_with_data(header: &Header, transactions: &[&SignedTransaction], uncles: &[Header]) -> Bytes { +pub fn create_test_block_with_data(header: &Header, transactions: &[SignedTransaction], uncles: &[Header]) -> Bytes { let mut rlp = RlpStream::new_list(3); rlp.append(header); rlp.begin_list(transactions.len()); @@ -138,33 +140,75 @@ pub fn create_test_block_with_data(header: &Header, transactions: &[&SignedTrans } pub fn generate_dummy_client(block_number: u32) -> GuardedTempResult> { + generate_dummy_client_with_spec_and_data(Spec::new_test, block_number, 0, &[]) +} + +pub fn generate_dummy_client_with_data(block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult> { + generate_dummy_client_with_spec_and_data(Spec::new_null, block_number, txs_per_block, tx_gas_prices) +} + +pub fn generate_dummy_client_with_spec_and_data(get_test_spec: F, block_number: u32, txs_per_block: usize, tx_gas_prices: &[U256]) -> GuardedTempResult> where F: Fn()->Spec { let dir = RandomTempPath::new(); - let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::default()), IoChannel::disconnected()).unwrap(); let test_spec = get_test_spec(); + let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::with_spec(get_test_spec())), IoChannel::disconnected()).unwrap(); let test_engine = &test_spec.engine; - let state_root = test_spec.genesis_header().state_root; - let mut rolling_hash = test_spec.genesis_header().hash(); - let mut rolling_block_number = 1; + + let mut db_result = get_temp_journal_db(); + let mut db = db_result.take(); + test_spec.ensure_db_good(db.as_hashdb_mut()); + let vm_factory = Default::default(); + let genesis_header = test_spec.genesis_header(); + let mut rolling_timestamp = 40; + let mut last_hashes = vec![]; + let mut last_header = genesis_header.clone(); + let kp = KeyPair::from_secret("".sha3()).unwrap() ; + let author = kp.address(); + + let mut n = 0; for _ in 0..block_number { - let mut header = Header::new(); + last_hashes.push(last_header.hash()); - header.gas_limit = test_engine.params().min_gas_limit; - header.difficulty = U256::from(0x20000); - header.timestamp = rolling_timestamp; - header.number = rolling_block_number; - header.parent_hash = rolling_hash; - header.state_root = state_root.clone(); + // forge block. + let mut b = OpenBlock::new( + test_engine.deref(), + &vm_factory, + false, + db, + &last_header, + last_hashes.clone(), + None, + author.clone(), + (3141562.into(), 31415620.into()), + vec![] + ).unwrap(); + b.set_difficulty(U256::from(0x20000)); + rolling_timestamp += 10; + b.set_timestamp(rolling_timestamp); - rolling_hash = header.hash(); - rolling_block_number = rolling_block_number + 1; - rolling_timestamp = rolling_timestamp + 10; + // first block we don't have any balance, so can't send any transactions. + for _ in 0..txs_per_block { + b.push_transaction(Transaction { + nonce: n.into(), + gas_price: tx_gas_prices[n % tx_gas_prices.len()], + gas: 100000.into(), + action: Action::Create, + data: vec![], + value: U256::zero(), + }.sign(kp.secret()), None).unwrap(); + n += 1; + } - if let Err(e) = client.import_block(create_test_block(&header)) { + let b = b.close_and_lock().seal(test_engine.deref(), vec![]).unwrap(); + + if let Err(e) = client.import_block(b.rlp_bytes()) { panic!("error importing block which is valid by definition: {:?}", e); } + + last_header = BlockView::new(&b.rlp_bytes()).header(); + db = b.drain(); } client.flush_queue(); client.import_verified_blocks(&IoChannel::disconnected()); @@ -206,7 +250,7 @@ pub fn push_blocks_to_client(client: &Arc, timestamp_salt: u64, starting pub fn get_test_client_with_blocks(blocks: Vec) -> GuardedTempResult> { let dir = RandomTempPath::new(); - let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::default()), IoChannel::disconnected()).unwrap(); + let client = Client::new(ClientConfig::default(), get_test_spec(), dir.as_path(), Arc::new(Miner::with_spec(get_test_spec())), IoChannel::disconnected()).unwrap(); for block in &blocks { if let Err(_) = client.import_block(block.clone()) { panic!("panic importing block which is well-formed"); @@ -259,7 +303,7 @@ pub fn generate_dummy_empty_blockchain() -> GuardedTempResult { pub fn get_temp_journal_db() -> GuardedTempResult> { let temp = RandomTempPath::new(); - let journal_db = journaldb::new(temp.as_str(), journaldb::Algorithm::EarlyMerge); + let journal_db = journaldb::new(temp.as_str(), journaldb::Algorithm::EarlyMerge, DatabaseConfig::default()); GuardedTempResult { _temp: temp, result: Some(journal_db) @@ -276,7 +320,7 @@ pub fn get_temp_state() -> GuardedTempResult { } pub fn get_temp_journal_db_in(path: &Path) -> Box { - journaldb::new(path.to_str().unwrap(), journaldb::Algorithm::EarlyMerge) + journaldb::new(path.to_str().unwrap(), journaldb::Algorithm::EarlyMerge, DatabaseConfig::default()) } pub fn get_temp_state_in(path: &Path) -> State { diff --git a/ethcore/src/trace/config.rs b/ethcore/src/trace/config.rs index 76c62b43d..2876baa28 100644 --- a/ethcore/src/trace/config.rs +++ b/ethcore/src/trace/config.rs @@ -48,6 +48,8 @@ pub struct Config { pub enabled: Switch, /// Traces blooms configuration. pub blooms: BloomConfig, + /// Database cache-size if not default + pub db_cache_size: Option, } impl Default for Config { @@ -57,7 +59,8 @@ impl Default for Config { blooms: BloomConfig { levels: 3, elements_per_index: 16, - } + }, + db_cache_size: None, } } } diff --git a/ethcore/src/trace/db.rs b/ethcore/src/trace/db.rs index e40fa1b00..07f5f9c27 100644 --- a/ethcore/src/trace/db.rs +++ b/ethcore/src/trace/db.rs @@ -22,7 +22,7 @@ use std::sync::{RwLock, Arc}; use std::path::Path; use bloomchain::{Number, Config as BloomConfig}; use bloomchain::group::{BloomGroupDatabase, BloomGroupChain, GroupPosition, BloomGroup}; -use util::{H256, H264, Database, DBTransaction}; +use util::{H256, H264, Database, DatabaseConfig, DBTransaction}; use header::BlockNumber; use trace::{BlockTraces, LocalizedTrace, Config, Switch, Filter, Database as TraceDatabase, ImportRequest, DatabaseExtras, Error}; @@ -118,7 +118,12 @@ impl TraceDB where T: DatabaseExtras { pub fn new(config: Config, path: &Path, extras: Arc) -> Result { let mut tracedb_path = path.to_path_buf(); tracedb_path.push("tracedb"); - let tracesdb = Database::open_default(tracedb_path.to_str().unwrap()).unwrap(); + let tracesdb = match config.db_cache_size { + None => Database::open_default(tracedb_path.to_str().unwrap()).unwrap(), + Some(db_cache) => Database::open( + &DatabaseConfig::with_cache(db_cache), + tracedb_path.to_str().unwrap()).unwrap(), + }; // check if in previously tracing was enabled let old_tracing = match tracesdb.get(b"enabled").unwrap() { diff --git a/ethcore/src/types/transaction.rs b/ethcore/src/types/transaction.rs index a6b4c1781..a8e1c66e4 100644 --- a/ethcore/src/types/transaction.rs +++ b/ethcore/src/types/transaction.rs @@ -140,8 +140,13 @@ impl Transaction { /// Signs the transaction as coming from `sender`. pub fn sign(self, secret: &Secret) -> SignedTransaction { - let sig = ec::sign(secret, &self.hash()); - let (r, s, v) = sig.unwrap().to_rsv(); + let sig = ec::sign(secret, &self.hash()).unwrap(); + self.with_signature(sig) + } + + /// Signs the transaction with signature. + pub fn with_signature(self, sig: H520) -> SignedTransaction { + let (r, s, v) = sig.to_rsv(); SignedTransaction { unsigned: self, r: r, diff --git a/ethcore/src/verification/canon_verifier.rs b/ethcore/src/verification/canon_verifier.rs index 30e368f1b..e0ebf1b7c 100644 --- a/ethcore/src/verification/canon_verifier.rs +++ b/ethcore/src/verification/canon_verifier.rs @@ -24,11 +24,11 @@ use super::verification; pub struct CanonVerifier; impl Verifier for CanonVerifier { - fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: &BlockProvider) -> Result<(), Error> { + fn verify_block_family(&self, 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> { + fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error> { verification::verify_block_final(expected, got) } } diff --git a/ethcore/src/verification/mod.rs b/ethcore/src/verification/mod.rs index fe1f406cc..10aee21f4 100644 --- a/ethcore/src/verification/mod.rs +++ b/ethcore/src/verification/mod.rs @@ -17,11 +17,32 @@ pub mod verification; pub mod verifier; mod canon_verifier; -#[cfg(test)] mod noop_verifier; pub use self::verification::*; pub use self::verifier::Verifier; pub use self::canon_verifier::CanonVerifier; -#[cfg(test)] pub use self::noop_verifier::NoopVerifier; + +/// Verifier type. +#[derive(Debug)] +pub enum VerifierType { + /// Verifies block normally. + Canon, + /// Does not verify block at all. + /// Used in tests. + Noop, +} + +impl Default for VerifierType { + fn default() -> Self { + VerifierType::Canon + } +} + +pub fn new(v: VerifierType) -> Box { + match v { + VerifierType::Canon => Box::new(CanonVerifier), + VerifierType::Noop => Box::new(NoopVerifier), + } +} diff --git a/ethcore/src/verification/noop_verifier.rs b/ethcore/src/verification/noop_verifier.rs index 20c15c3f1..99d1d594c 100644 --- a/ethcore/src/verification/noop_verifier.rs +++ b/ethcore/src/verification/noop_verifier.rs @@ -24,11 +24,11 @@ use super::Verifier; pub struct NoopVerifier; impl Verifier for NoopVerifier { - fn verify_block_family(_header: &Header, _bytes: &[u8], _engine: &Engine, _bc: &BlockProvider) -> Result<(), Error> { + fn verify_block_family(&self, _header: &Header, _bytes: &[u8], _engine: &Engine, _bc: &BlockProvider) -> Result<(), Error> { Ok(()) } - fn verify_block_final(_expected: &Header, _got: &Header) -> Result<(), Error> { + fn verify_block_final(&self, _expected: &Header, _got: &Header) -> Result<(), Error> { Ok(()) } } diff --git a/ethcore/src/verification/verification.rs b/ethcore/src/verification/verification.rs index 6511a8ddd..c6b75416b 100644 --- a/ethcore/src/verification/verification.rs +++ b/ethcore/src/verification/verification.rs @@ -361,7 +361,7 @@ mod tests { nonce: U256::from(2) }.sign(&keypair.secret()); - let good_transactions = [ &tr1, &tr2 ]; + let good_transactions = [ tr1.clone(), tr2.clone() ]; let diff_inc = U256::from(0x40); diff --git a/ethcore/src/verification/verifier.rs b/ethcore/src/verification/verifier.rs index cc5edce29..5db81a4eb 100644 --- a/ethcore/src/verification/verifier.rs +++ b/ethcore/src/verification/verifier.rs @@ -21,6 +21,6 @@ use header::Header; /// Should be used to verify blocks. pub trait Verifier: Send + Sync { - fn verify_block_family(header: &Header, bytes: &[u8], engine: &Engine, bc: &BlockProvider) -> Result<(), Error>; - fn verify_block_final(expected: &Header, got: &Header) -> Result<(), Error>; + fn verify_block_family(&self, header: &Header, bytes: &[u8], engine: &Engine, bc: &BlockProvider) -> Result<(), Error>; + fn verify_block_final(&self, expected: &Header, got: &Header) -> Result<(), Error>; } diff --git a/ethcore/src/views.rs b/ethcore/src/views.rs deleted file mode 100644 index 8fec56a5e..000000000 --- a/ethcore/src/views.rs +++ /dev/null @@ -1,339 +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 . - -//! Block oriented views onto rlp. -use util::*; -use header::*; -use transaction::*; - -/// View onto transaction rlp. -pub struct TransactionView<'a> { - rlp: Rlp<'a> -} - -impl<'a> TransactionView<'a> { - /// Creates new view onto block from raw bytes. - pub fn new(bytes: &'a [u8]) -> TransactionView<'a> { - TransactionView { - rlp: Rlp::new(bytes) - } - } - - /// Creates new view onto block from rlp. - pub fn new_from_rlp(rlp: Rlp<'a>) -> TransactionView<'a> { - TransactionView { - rlp: rlp - } - } - - /// Return reference to underlaying rlp. - pub fn rlp(&self) -> &Rlp<'a> { - &self.rlp - } - - /// Get the nonce field of the transaction. - pub fn nonce(&self) -> U256 { self.rlp.val_at(0) } - - /// Get the gas_price field of the transaction. - pub fn gas_price(&self) -> U256 { self.rlp.val_at(1) } - - /// Get the gas field of the transaction. - pub fn gas(&self) -> U256 { self.rlp.val_at(2) } - - /// Get the value field of the transaction. - pub fn value(&self) -> U256 { self.rlp.val_at(4) } - - /// Get the data field of the transaction. - pub fn data(&self) -> Bytes { self.rlp.val_at(5) } - - /// Get the v field of the transaction. - pub fn v(&self) -> u8 { let r: u16 = self.rlp.val_at(6); r as u8 } - - /// Get the r field of the transaction. - pub fn r(&self) -> U256 { self.rlp.val_at(7) } - - /// Get the s field of the transaction. - pub fn s(&self) -> U256 { self.rlp.val_at(8) } - - // TODO: something like pub fn action(&self) -> Action { self.rlp.val_at(3) } -} - -impl<'a> Hashable for TransactionView<'a> { - fn sha3(&self) -> H256 { - self.rlp.as_raw().sha3() - } -} - -/// View onto transaction rlp. -pub struct AccountView<'a> { - rlp: Rlp<'a> -} - -impl<'a> AccountView<'a> { - /// Creates new view onto block from raw bytes. - pub fn new(bytes: &'a [u8]) -> AccountView<'a> { - AccountView { - rlp: Rlp::new(bytes) - } - } - - /// Creates new view onto block from rlp. - pub fn new_from_rlp(rlp: Rlp<'a>) -> AccountView<'a> { - AccountView { - rlp: rlp - } - } - - /// Return reference to underlaying rlp. - pub fn rlp(&self) -> &Rlp<'a> { - &self.rlp - } - - /// Get the nonce field of the transaction. - pub fn nonce(&self) -> U256 { self.rlp.val_at(0) } - - /// Get the gas_price field of the transaction. - pub fn balance(&self) -> U256 { self.rlp.val_at(1) } - - /// Get the gas field of the transaction. - pub fn storage_root(&self) -> H256 { self.rlp.val_at(2) } - - /// Get the value field of the transaction. - pub fn code_hash(&self) -> H256 { self.rlp.val_at(3) } -} - -/// View onto block rlp. -pub struct BlockView<'a> { - rlp: Rlp<'a> -} - -impl<'a> BlockView<'a> { - /// Creates new view onto block from raw bytes. - pub fn new(bytes: &'a [u8]) -> BlockView<'a> { - BlockView { - rlp: Rlp::new(bytes) - } - } - - /// Creates new view onto block from rlp. - pub fn new_from_rlp(rlp: Rlp<'a>) -> BlockView<'a> { - BlockView { - rlp: rlp - } - } - - /// Return reference to underlaying rlp. - pub fn rlp(&self) -> &Rlp<'a> { - &self.rlp - } - - /// Create new Header object from header rlp. - pub fn header(&self) -> Header { - self.rlp.val_at(0) - } - - /// Create new header view onto block head rlp. - pub fn header_view(&self) -> HeaderView<'a> { - HeaderView::new_from_rlp(self.rlp.at(0)) - } - - /// Return List of transactions in given block. - pub fn transactions(&self) -> Vec { - self.rlp.val_at(1) - } - - /// Return List of transactions with additional localization info. - pub fn localized_transactions(&self) -> Vec { - let header = self.header_view(); - let block_hash = header.sha3(); - let block_number = header.number(); - self.transactions() - .into_iter() - .enumerate() - .map(|(i, t)| LocalizedTransaction { - signed: t, - block_hash: block_hash.clone(), - block_number: block_number, - transaction_index: i - }).collect() - } - - /// Return number of transactions in given block, without deserializing them. - pub fn transactions_count(&self) -> usize { - self.rlp.at(1).iter().count() - } - - /// Return List of transactions in given block. - pub fn transaction_views(&self) -> Vec { - self.rlp.at(1).iter().map(TransactionView::new_from_rlp).collect() - } - - /// Return transaction hashes. - pub fn transaction_hashes(&self) -> Vec { - self.rlp.at(1).iter().map(|rlp| rlp.as_raw().sha3()).collect() - } - - /// Returns transaction at given index without deserializing unnecessary data. - pub fn transaction_at(&self, index: usize) -> Option { - self.rlp.at(1).iter().nth(index).map(|rlp| rlp.as_val()) - } - - /// Returns localized transaction at given index. - pub fn localized_transaction_at(&self, index: usize) -> Option { - let header = self.header_view(); - let block_hash = header.sha3(); - let block_number = header.number(); - self.transaction_at(index).map(|t| LocalizedTransaction { - signed: t, - block_hash: block_hash, - block_number: block_number, - transaction_index: index - }) - } - - /// Return list of uncles of given block. - pub fn uncles(&self) -> Vec
{ - self.rlp.val_at(2) - } - - /// Return number of uncles in given block, without deserializing them. - pub fn uncles_count(&self) -> usize { - self.rlp.at(2).iter().count() - } - - /// Return List of transactions in given block. - pub fn uncle_views(&self) -> Vec { - self.rlp.at(2).iter().map(HeaderView::new_from_rlp).collect() - } - - /// Return list of uncle hashes of given block. - pub fn uncle_hashes(&self) -> Vec { - self.rlp.at(2).iter().map(|rlp| rlp.as_raw().sha3()).collect() - } - - /// Return nth uncle. - pub fn uncle_at(&self, index: usize) -> Option
{ - self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_val()) - } -} - -impl<'a> Hashable for BlockView<'a> { - fn sha3(&self) -> H256 { - self.header_view().sha3() - } -} - -/// View onto block header rlp. -pub struct HeaderView<'a> { - rlp: Rlp<'a> -} - -impl<'a> HeaderView<'a> { - /// Creates new view onto header from raw bytes. - pub fn new(bytes: &'a [u8]) -> HeaderView<'a> { - HeaderView { - rlp: Rlp::new(bytes) - } - } - - /// Creates new view onto header from rlp. - pub fn new_from_rlp(rlp: Rlp<'a>) -> HeaderView<'a> { - HeaderView { - rlp: rlp - } - } - - /// Returns header hash. - pub fn hash(&self) -> H256 { self.sha3() } - - /// Returns raw rlp. - pub fn rlp(&self) -> &Rlp<'a> { &self.rlp } - - /// Returns parent hash. - pub fn parent_hash(&self) -> H256 { self.rlp.val_at(0) } - - /// Returns uncles hash. - pub fn uncles_hash(&self) -> H256 { self.rlp.val_at(1) } - - /// Returns author. - pub fn author(&self) -> Address { self.rlp.val_at(2) } - - /// Returns state root. - pub fn state_root(&self) -> H256 { self.rlp.val_at(3) } - - /// Returns transactions root. - pub fn transactions_root(&self) -> H256 { self.rlp.val_at(4) } - - /// Returns block receipts root. - pub fn receipts_root(&self) -> H256 { self.rlp.val_at(5) } - - /// Returns block log bloom. - pub fn log_bloom(&self) -> H2048 { self.rlp.val_at(6) } - - /// Returns block difficulty. - pub fn difficulty(&self) -> U256 { self.rlp.val_at(7) } - - /// Returns block number. - pub fn number(&self) -> BlockNumber { self.rlp.val_at(8) } - - /// Returns block gas limit. - pub fn gas_limit(&self) -> U256 { self.rlp.val_at(9) } - - /// Returns block gas used. - pub fn gas_used(&self) -> U256 { self.rlp.val_at(10) } - - /// Returns timestamp. - pub fn timestamp(&self) -> u64 { self.rlp.val_at(11) } - - /// Returns block extra data. - pub fn extra_data(&self) -> Bytes { self.rlp.val_at(12) } - - /// Returns a vector of post-RLP-encoded seal fields. - pub fn seal(&self) -> Vec { - let mut seal = vec![]; - for i in 13..self.rlp.item_count() { - seal.push(self.rlp.at(i).as_raw().to_vec()); - } - seal - } -} - -impl<'a> Hashable for HeaderView<'a> { - fn sha3(&self) -> H256 { - self.rlp.as_raw().sha3() - } -} - -#[cfg(test)] -mod tests { - use rustc_serialize::hex::FromHex; - use super::BlockView; - - #[test] - fn test_header_view_seal_fields() { - // that's rlp of block created with ethash engine. - let block_rlp = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap(); - let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap(); - let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap(); - - let block_view = BlockView::new(&block_rlp); - let header_view = block_view.header_view(); - let seal_fields = header_view.seal(); - assert_eq!(seal_fields.len(), 2); - assert_eq!(seal_fields[0], mix_hash); - assert_eq!(seal_fields[1], nonce); - } -} diff --git a/ethcore/src/views/block.rs b/ethcore/src/views/block.rs new file mode 100644 index 000000000..82b8fb805 --- /dev/null +++ b/ethcore/src/views/block.rs @@ -0,0 +1,167 @@ +// 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 . + +//! View onto block rlp. + +use util::*; +use header::*; +use transaction::*; +use super::{TransactionView, HeaderView}; + +/// View onto block rlp. +pub struct BlockView<'a> { + rlp: Rlp<'a> +} + +impl<'a> BlockView<'a> { + /// Creates new view onto block from raw bytes. + pub fn new(bytes: &'a [u8]) -> BlockView<'a> { + BlockView { + rlp: Rlp::new(bytes) + } + } + + /// Creates new view onto block from rlp. + pub fn new_from_rlp(rlp: Rlp<'a>) -> BlockView<'a> { + BlockView { + rlp: rlp + } + } + + /// Block header hash. + pub fn hash(&self) -> H256 { + self.sha3() + } + + /// Return reference to underlaying rlp. + pub fn rlp(&self) -> &Rlp<'a> { + &self.rlp + } + + /// Create new Header object from header rlp. + pub fn header(&self) -> Header { + self.rlp.val_at(0) + } + + /// Create new header view obto block head rlp. + pub fn header_view(&self) -> HeaderView<'a> { + HeaderView::new_from_rlp(self.rlp.at(0)) + } + + /// Return List of transactions in given block. + pub fn transactions(&self) -> Vec { + self.rlp.val_at(1) + } + + /// Return List of transactions with additional localization info. + pub fn localized_transactions(&self) -> Vec { + let header = self.header_view(); + let block_hash = header.sha3(); + let block_number = header.number(); + self.transactions() + .into_iter() + .enumerate() + .map(|(i, t)| LocalizedTransaction { + signed: t, + block_hash: block_hash.clone(), + block_number: block_number, + transaction_index: i + }).collect() + } + + /// Return number of transactions in given block, without deserializing them. + pub fn transactions_count(&self) -> usize { + self.rlp.at(1).iter().count() + } + + /// Return List of transactions in given block. + pub fn transaction_views(&self) -> Vec { + self.rlp.at(1).iter().map(TransactionView::new_from_rlp).collect() + } + + /// Return transaction hashes. + pub fn transaction_hashes(&self) -> Vec { + self.rlp.at(1).iter().map(|rlp| rlp.as_raw().sha3()).collect() + } + + /// Returns transaction at given index without deserializing unnecessary data. + pub fn transaction_at(&self, index: usize) -> Option { + self.rlp.at(1).iter().nth(index).map(|rlp| rlp.as_val()) + } + + /// Returns localized transaction at given index. + pub fn localized_transaction_at(&self, index: usize) -> Option { + let header = self.header_view(); + let block_hash = header.sha3(); + let block_number = header.number(); + self.transaction_at(index).map(|t| LocalizedTransaction { + signed: t, + block_hash: block_hash, + block_number: block_number, + transaction_index: index + }) + } + + /// Return list of uncles of given block. + pub fn uncles(&self) -> Vec
{ + self.rlp.val_at(2) + } + + /// Return number of uncles in given block, without deserializing them. + pub fn uncles_count(&self) -> usize { + self.rlp.at(2).iter().count() + } + + /// Return List of transactions in given block. + pub fn uncle_views(&self) -> Vec { + self.rlp.at(2).iter().map(HeaderView::new_from_rlp).collect() + } + + /// Return list of uncle hashes of given block. + pub fn uncle_hashes(&self) -> Vec { + self.rlp.at(2).iter().map(|rlp| rlp.as_raw().sha3()).collect() + } + + /// Return nth uncle. + pub fn uncle_at(&self, index: usize) -> Option
{ + self.rlp.at(2).iter().nth(index).map(|rlp| rlp.as_val()) + } +} + +impl<'a> Hashable for BlockView<'a> { + fn sha3(&self) -> H256 { + self.header_view().sha3() + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use rustc_serialize::hex::FromHex; + use util::H256; + use super::BlockView; + + #[test] + fn test_block_view() { + // that's rlp of block created with ethash engine. + let rlp = "f90261f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23f862f86002018304cb2f94ec0e71ad0a90ffe1909d27dac207f7680abba42d01801ba03a347e72953c860f32b1eb2c78a680d8734b2ea08085d949d729479796f218d5a047ea6239d9e31ccac8af3366f5ca37184d26e7646e3191a3aeb81c4cf74de500c0".from_hex().unwrap(); + + let view = BlockView::new(&rlp); + assert_eq!(view.hash(), H256::from_str("2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259").unwrap()); + assert_eq!(view.transactions_count(), 1); + assert_eq!(view.uncles_count(), 0); + } +} diff --git a/ethcore/src/views/header.rs b/ethcore/src/views/header.rs new file mode 100644 index 000000000..70b59fbfa --- /dev/null +++ b/ethcore/src/views/header.rs @@ -0,0 +1,134 @@ +// 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 . + +//! View onto block header rlp + +use util::{Rlp, U256, Bytes, Hashable, H256, Address, H2048, View}; +use header::BlockNumber; + +/// View onto block header rlp. +pub struct HeaderView<'a> { + rlp: Rlp<'a> +} + +impl<'a> HeaderView<'a> { + /// Creates new view onto header from raw bytes. + pub fn new(bytes: &'a [u8]) -> HeaderView<'a> { + HeaderView { + rlp: Rlp::new(bytes) + } + } + + /// Creates new view onto header from rlp. + pub fn new_from_rlp(rlp: Rlp<'a>) -> HeaderView<'a> { + HeaderView { + rlp: rlp + } + } + + /// Returns header hash. + pub fn hash(&self) -> H256 { self.sha3() } + + /// Returns raw rlp. + pub fn rlp(&self) -> &Rlp<'a> { &self.rlp } + + /// Returns parent hash. + pub fn parent_hash(&self) -> H256 { self.rlp.val_at(0) } + + /// Returns uncles hash. + pub fn uncles_hash(&self) -> H256 { self.rlp.val_at(1) } + + /// Returns author. + pub fn author(&self) -> Address { self.rlp.val_at(2) } + + /// Returns state root. + pub fn state_root(&self) -> H256 { self.rlp.val_at(3) } + + /// Returns transactions root. + pub fn transactions_root(&self) -> H256 { self.rlp.val_at(4) } + + /// Returns block receipts root. + pub fn receipts_root(&self) -> H256 { self.rlp.val_at(5) } + + /// Returns block log bloom. + pub fn log_bloom(&self) -> H2048 { self.rlp.val_at(6) } + + /// Returns block difficulty. + pub fn difficulty(&self) -> U256 { self.rlp.val_at(7) } + + /// Returns block number. + pub fn number(&self) -> BlockNumber { self.rlp.val_at(8) } + + /// Returns block gas limit. + pub fn gas_limit(&self) -> U256 { self.rlp.val_at(9) } + + /// Returns block gas used. + pub fn gas_used(&self) -> U256 { self.rlp.val_at(10) } + + /// Returns timestamp. + pub fn timestamp(&self) -> u64 { self.rlp.val_at(11) } + + /// Returns block extra data. + pub fn extra_data(&self) -> Bytes { self.rlp.val_at(12) } + + /// Returns a vector of post-RLP-encoded seal fields. + pub fn seal(&self) -> Vec { + let mut seal = vec![]; + for i in 13..self.rlp.item_count() { + seal.push(self.rlp.at(i).as_raw().to_vec()); + } + seal + } +} + +impl<'a> Hashable for HeaderView<'a> { + fn sha3(&self) -> H256 { + self.rlp.as_raw().sha3() + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use rustc_serialize::hex::FromHex; + use util::{H256, Address, H2048, U256}; + use super::HeaderView; + + #[test] + fn test_header_view() { + // that's rlp of block header created with ethash engine. + let rlp = "f901f9a0d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347948888f1f195afa192cfee860698584c030f4c9db1a05fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25a088d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158a007c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1b90100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008302008003832fefba82524d84568e932a80a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd88ab4e252a7e8c2a23".from_hex().unwrap(); + let mix_hash = "a0a0349d8c3df71f1a48a9df7d03fd5f14aeee7d91332c009ecaff0a71ead405bd".from_hex().unwrap(); + let nonce = "88ab4e252a7e8c2a23".from_hex().unwrap(); + + let view = HeaderView::new(&rlp); + assert_eq!(view.hash(), H256::from_str("2c9747e804293bd3f1a986484343f23bc88fd5be75dfe9d5c2860aff61e6f259").unwrap()); + assert_eq!(view.parent_hash(), H256::from_str("d405da4e66f1445d455195229624e133f5baafe72b5cf7b3c36c12c8146e98b7").unwrap()); + assert_eq!(view.uncles_hash(), H256::from_str("1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347").unwrap()); + assert_eq!(view.author(), Address::from_str("8888f1f195afa192cfee860698584c030f4c9db1").unwrap()); + assert_eq!(view.state_root(), H256::from_str("5fb2b4bfdef7b314451cb138a534d225c922fc0e5fbe25e451142732c3e25c25").unwrap()); + assert_eq!(view.transactions_root(), H256::from_str("88d2ec6b9860aae1a2c3b299f72b6a5d70d7f7ba4722c78f2c49ba96273c2158").unwrap()); + assert_eq!(view.receipts_root(), H256::from_str("07c6fdfa8eea7e86b81f5b0fc0f78f90cc19f4aa60d323151e0cac660199e9a1").unwrap()); + assert_eq!(view.log_bloom(), H2048::default()); + assert_eq!(view.difficulty(), U256::from(0x02_00_80)); + assert_eq!(view.number(), 3); + assert_eq!(view.gas_limit(), U256::from(0x2f_ef_ba)); + assert_eq!(view.gas_used(), U256::from(0x52_4d)); + assert_eq!(view.timestamp(), 0x56_8e_93_2a); + assert_eq!(view.extra_data(), vec![] as Vec); + assert_eq!(view.seal(), vec![mix_hash, nonce]); + } +} diff --git a/util/src/keys/mod.rs b/ethcore/src/views/mod.rs similarity index 72% rename from util/src/keys/mod.rs rename to ethcore/src/views/mod.rs index 39c39aeef..c0102be3d 100644 --- a/util/src/keys/mod.rs +++ b/ethcore/src/views/mod.rs @@ -14,13 +14,12 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -//! Key management module +//! Block oriented views onto rlp. -pub mod directory; -pub mod store; -mod geth_import; -mod test_account_provider; +mod block; +mod header; +mod transaction; -pub use self::store::AccountProvider; -pub use self::test_account_provider::{TestAccount, TestAccountProvider}; -pub use self::geth_import::import_keys_paths; +pub use self::block::BlockView; +pub use self::header::HeaderView; +pub use self::transaction::TransactionView; diff --git a/ethcore/src/views/transaction.rs b/ethcore/src/views/transaction.rs new file mode 100644 index 000000000..d83290909 --- /dev/null +++ b/ethcore/src/views/transaction.rs @@ -0,0 +1,97 @@ +// 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 . + +//! View onto transaction rlp +use util::{Rlp, U256, Bytes, Hashable, H256, View}; + +/// View onto transaction rlp. +pub struct TransactionView<'a> { + rlp: Rlp<'a> +} + +impl<'a> TransactionView<'a> { + /// Creates new view onto block from raw bytes. + pub fn new(bytes: &'a [u8]) -> TransactionView<'a> { + TransactionView { + rlp: Rlp::new(bytes) + } + } + + /// Creates new view onto block from rlp. + pub fn new_from_rlp(rlp: Rlp<'a>) -> TransactionView<'a> { + TransactionView { + rlp: rlp + } + } + + /// Return reference to underlaying rlp. + pub fn rlp(&self) -> &Rlp<'a> { + &self.rlp + } + + /// Get the nonce field of the transaction. + pub fn nonce(&self) -> U256 { self.rlp.val_at(0) } + + /// Get the gas_price field of the transaction. + pub fn gas_price(&self) -> U256 { self.rlp.val_at(1) } + + /// Get the gas field of the transaction. + pub fn gas(&self) -> U256 { self.rlp.val_at(2) } + + /// Get the value field of the transaction. + pub fn value(&self) -> U256 { self.rlp.val_at(4) } + + /// Get the data field of the transaction. + pub fn data(&self) -> Bytes { self.rlp.val_at(5) } + + /// Get the v field of the transaction. + pub fn v(&self) -> u8 { let r: u16 = self.rlp.val_at(6); r as u8 } + + /// Get the r field of the transaction. + pub fn r(&self) -> U256 { self.rlp.val_at(7) } + + /// Get the s field of the transaction. + pub fn s(&self) -> U256 { self.rlp.val_at(8) } +} + +impl<'a> Hashable for TransactionView<'a> { + fn sha3(&self) -> H256 { + self.rlp.as_raw().sha3() + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use rustc_serialize::hex::FromHex; + use util::U256; + use super::TransactionView; + + #[test] + fn test_transaction_view() { + let rlp = "f87c80018261a894095e7baea6a6c7c4c2dfeb977efac326af552d870a9d00000000000000000000000000000000000000000000000000000000001ba048b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353a0efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804".from_hex().unwrap(); + + let view = TransactionView::new(&rlp); + assert_eq!(view.nonce(), U256::from(0)); + assert_eq!(view.gas_price(), U256::from(1)); + assert_eq!(view.gas(), U256::from(0x61a8)); + assert_eq!(view.value(), U256::from(0xa)); + assert_eq!(view.data(), "0000000000000000000000000000000000000000000000000000000000".from_hex().unwrap()); + assert_eq!(view.r(), U256::from_str("48b55bfa915ac795c431978d8a6a992b628d557da5ff759b307d495a36649353").unwrap()); + assert_eq!(view.s(), U256::from_str("efffd310ac743f371de3b9f7f9cb56c0b28ad43601b4ab949f53faa07bd2c804").unwrap()); + assert_eq!(view.v(), 0x1b); + } +} diff --git a/ethkey/.gitignore b/ethkey/.gitignore new file mode 100644 index 000000000..c6262ea6a --- /dev/null +++ b/ethkey/.gitignore @@ -0,0 +1,2 @@ +target +*.swp diff --git a/ethkey/.travis.yml b/ethkey/.travis.yml new file mode 100644 index 000000000..e1d6f9b13 --- /dev/null +++ b/ethkey/.travis.yml @@ -0,0 +1,23 @@ +sudo: false +language: rust +branches: + only: + - master +matrix: + fast_finish: false + include: + - rust: stable + - rust: beta + - rust: nightly +after_success: | + [ $TRAVIS_BRANCH = master ] && + [ $TRAVIS_PULL_REQUEST = false ] && + [ $TRAVIS_RUST_VERSION = stable ] && + cargo doc --no-deps --verbose && + echo '' > target/doc/index.html && + pip install --user ghp-import && + /home/travis/.local/bin/ghp-import -n target/doc && + git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages +env: + global: + - secure: LBkFAH5fAhzHRP7kYQZnOCavOuPS2vEDv49KGfTsY/7MmW0De4c0sz0a3/0IdFqqIMLYLV2uMO86S0p6FBaq6/GIdobLsGZZ3cFReYFI+vb8sylYF/+D/aQ/UOjpEOD8HP6G3YmV5buSyL8uiPlmYbqwBAe4z6ELEbh/16gRuIqQLYQtpYPxMCD3tZzSux81b45K2khETZ7E+ap3LUG3rFTXxjEgx9leIZlVY+Qk4U5D9gFnJnjmxDPyIqzn2dORnw5jcpp3eSUEvSvSgjz4TAVg7Gw789jDl2dyr26U1wp1E5bB9AqZVYOb4l8vcQ6QiHrCvu7Wgl32O6XYkwMjDaDUB68bm5MTsUrwDWgKGx4xeurIBil5doHFlCGZ98RrzPxdgoCd6hCI459dA8jEwdXAfOkZ80RycZlryHCwn68x3dlnJoqVyg8viYo6H6G0GdH/dIhuwbnLDdWZsODehN8eJEy9KKQ4tPp+PjBcgKm1Wz5MzKFSIwfFInic7hjTVXGozHSvgvXJE0BI2bPbjVNCdZa5kGAAUAhBNXyTn7PbC7hYbmwAalzaOIjoYcdQLmUEz2J2gSOK8xW2gMU0Z2I+IylA0oh8xB/r2Q5sqLHT3LPLdzoETsyzaQjWFcFdXdsbbcG59DnFC9s2Jq7KqeODp6EJG4cw0ofKpBuDRes= diff --git a/ethkey/Cargo.toml b/ethkey/Cargo.toml new file mode 100644 index 000000000..c7b99e45c --- /dev/null +++ b/ethkey/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "ethkey" +version = "0.2.0" +authors = ["debris "] + +[dependencies] +rand = "0.3.14" +lazy_static = "0.2.1" +tiny-keccak = "1.0" +eth-secp256k1 = { git = "https://github.com/ethcore/rust-secp256k1" } +rustc-serialize = "0.3" +docopt = { version = "0.6", optional = true } + +[features] +default = [] +cli = ["docopt"] + +[[bin]] +name = "ethkey" +path = "src/bin/main.rs" +doc = false diff --git a/ethkey/README.md b/ethkey/README.md new file mode 100644 index 000000000..726047481 --- /dev/null +++ b/ethkey/README.md @@ -0,0 +1,168 @@ +# ethkey + +[![Build Status][travis-image]][travis-url] + +[travis-image]: https://travis-ci.org/ethcore/ethkey.svg?branch=master +[travis-url]: https://travis-ci.org/ethcore/ethkey + +Ethereum keys generator. + +[Documentation](http://ethcore.github.io/ethkey/ethkey/index.html) + +### Usage + +``` +Ethereum keys generator. + Copyright 2016 Ethcore (UK) Limited + +Usage: + ethkey info [options] + ethkey generate random [options] + ethkey generate prefix [options] + ethkey generate brain [options] + ethkey sign + ethkey verify public + ethkey verify address
+ ethkey [-h | --help] + +Options: + -h, --help Display this message and exit. + -s, --secret Display only the secret. + -p, --public Display only the public. + -a, --address Display only the address. + +Commands: + info Display public and address of the secret. + generate Generates new ethereum key. + random Random generation. + prefix Random generation, but address must start with a prefix + brain Generate new key from string seed. + sign Sign message using secret. + verify Verify signer of the signature. +``` + +### Examples + +#### `info ` +*Display info about private key.* + +- `` - ethereum secret, 32 bytes long + +``` +ethkey info 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55 +``` + +``` +secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55 +public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 +address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5 +``` + +-- + +#### `generate brain ` +*Generate new brain-wallet keypair using 16384 iterations.* + +- `` - brain-wallet seed, any string + + +``` +ethkey generate brain "this is sparta" +``` + +``` +secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55 +public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 +address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5 +``` + +-- + +#### `generate random` +*Generate new keypair randomly.* + +``` +ethkey generate random +``` + +``` +secret: 7d29fab185a33e2cd955812397354c472d2b84615b645aa135ff539f6b0d70d5 +public: 35f222d88b80151857a2877826d940104887376a94c1cbd2c8c7c192eb701df88a18a4ecb8b05b1466c5b3706042027b5e079fe3a3683e66d822b0e047aa3418 +address: a8fa5dd30a87bb9e3288d604eb74949c515ab66e +``` + +-- + +#### `generate prefix ` +*Generate new keypair randomly with address starting with prefix.* + +- `` - desired address prefix, 0 - 32 bytes long. +- `` - maximum number of tries before generation is assumed to be a failure. + +``` +ethkey generate prefix ff 1000 +``` + +``` +secret: 2075b1d9c124ea673de7273758ed6de14802a9da8a73ceb74533d7c312ff6acd +public: 48dbce4508566a05509980a5dd1335599fcdac6f9858ba67018cecb9f09b8c4066dc4c18ae2722112fd4d9ac36d626793fffffb26071dfeb0c2300df994bd173 +address: fff7e25dff2aa60f61f9d98130c8646a01f31649 +``` + +-- + +#### `sign ` +*Sign a message with a secret.* + +- `` - ethereum secret, 32 bytes long +- `` - message to sign, 32 bytes long + +``` +ethkey sign 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55 bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987 +``` + +``` +c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200 +``` + +-- + +#### `verify public ` +*Verify the signature.* + +- `` - ethereum public, 64 bytes long +- `` - message signature, 65 bytes long +- `` - message, 32 bytes long + +``` +ethkey verify public 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200 bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987 +``` + +``` +true +``` + +-- + +#### `verify address
` +*Verify the signature.* + +- `
` - ethereum address, 20 bytes long +- `` - message signature, 65 bytes long +- `` - message, 32 bytes long + +``` +ethkey verify address 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200 bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987 +``` + +``` +true +``` + + +# Ethcore toolchain +*this project is a part of the ethcore toolchain* + +- [**ethkey**](https://github.com/ethcore/ethkey) - Ethereum keys generator and signer. +- [**ethstore**](https://github.com/ethcore/ethstore) - Ethereum key management. +- [**ethabi**](https://github.com/ethcore/ethabi) - Ethereum function calls encoding. diff --git a/ethkey/src/bin/ethkey.rs b/ethkey/src/bin/ethkey.rs new file mode 100644 index 000000000..c7a7939fd --- /dev/null +++ b/ethkey/src/bin/ethkey.rs @@ -0,0 +1,312 @@ +// 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 . + +extern crate docopt; +extern crate rustc_serialize; +extern crate ethkey; + +use std::str::FromStr; +use std::{env, fmt, process}; +use std::num::ParseIntError; +use docopt::Docopt; +use rustc_serialize::hex::{FromHex, FromHexError}; +use ethkey::{KeyPair, Random, Brain, Prefix, Error as EthkeyError, Generator, Secret, Message, Public, Signature, Address, sign, verify_public, verify_address}; + +pub const USAGE: &'static str = r#" +Ethereum keys generator. + Copyright 2016 Ethcore (UK) Limited + +Usage: + ethkey info [options] + ethkey generate random [options] + ethkey generate prefix [options] + ethkey generate brain [options] + ethkey sign + ethkey verify public + ethkey verify address
+ ethkey [-h | --help] + +Options: + -h, --help Display this message and exit. + -s, --secret Display only the secret. + -p, --public Display only the public. + -a, --address Display only the address. + +Commands: + info Display public and address of the secret. + generate Generates new ethereum key. + random Random generation. + prefix Random generation, but address must start with a prefix + brain Generate new key from string seed. + sign Sign message using secret. + verify Verify signer of the signature. +"#; + +#[derive(Debug, RustcDecodable)] +struct Args { + cmd_info: bool, + cmd_generate: bool, + cmd_random: bool, + cmd_prefix: bool, + cmd_brain: bool, + cmd_sign: bool, + cmd_verify: bool, + cmd_public: bool, + cmd_address: bool, + arg_prefix: String, + arg_iterations: String, + arg_seed: String, + arg_secret: String, + arg_message: String, + arg_public: String, + arg_address: String, + arg_signature: String, + flag_secret: bool, + flag_public: bool, + flag_address: bool, +} + +#[derive(Debug)] +enum Error { + Ethkey(EthkeyError), + FromHex(FromHexError), + ParseInt(ParseIntError), +} + +impl From for Error { + fn from(err: EthkeyError) -> Self { + Error::Ethkey(err) + } +} + +impl From for Error { + fn from(err: FromHexError) -> Self { + Error::FromHex(err) + } +} + +impl From for Error { + fn from(err: ParseIntError) -> Self { + Error::ParseInt(err) + } +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match *self { + Error::Ethkey(ref e) => write!(f, "{}", e), + Error::FromHex(ref e) => write!(f, "{}", e), + Error::ParseInt(ref e) => write!(f, "{}", e), + } + } +} + +enum DisplayMode { + KeyPair, + Secret, + Public, + Address, +} + +impl DisplayMode { + fn new(args: &Args) -> Self { + if args.flag_secret { + DisplayMode::Secret + } else if args.flag_public { + DisplayMode::Public + } else if args.flag_address { + DisplayMode::Address + } else { + DisplayMode::KeyPair + } + } +} + +fn main() { + match execute(env::args()) { + Ok(ok) => println!("{}", ok), + Err(err) => { + println!("{}", err); + process::exit(1); + }, + } +} + +fn display(keypair: KeyPair, mode: DisplayMode) -> String { + match mode { + DisplayMode::KeyPair => format!("{}", keypair), + DisplayMode::Secret => format!("{}", keypair.secret()), + DisplayMode::Public => format!("{}", keypair.public()), + DisplayMode::Address => format!("{}", keypair.address()), + } +} + +fn execute(command: I) -> Result where I: IntoIterator, S: AsRef { + let args: Args = Docopt::new(USAGE) + .and_then(|d| d.argv(command).decode()) + .unwrap_or_else(|e| e.exit()); + + return if args.cmd_info { + let display_mode = DisplayMode::new(&args); + let secret = try!(Secret::from_str(&args.arg_secret)); + let keypair = try!(KeyPair::from_secret(secret)); + Ok(display(keypair, display_mode)) + } else if args.cmd_generate { + let display_mode = DisplayMode::new(&args); + let keypair = if args.cmd_random { + Random.generate() + } else if args.cmd_prefix { + let prefix = try!(args.arg_prefix.from_hex()); + let iterations = try!(usize::from_str_radix(&args.arg_iterations, 10)); + Prefix::new(prefix, iterations).generate() + } else if args.cmd_brain { + Brain::new(args.arg_seed).generate() + } else { + unreachable!(); + }; + Ok(display(try!(keypair), display_mode)) + } else if args.cmd_sign { + let secret = try!(Secret::from_str(&args.arg_secret)); + let message = try!(Message::from_str(&args.arg_message)); + let signature = try!(sign(&secret, &message)); + Ok(format!("{}", signature)) + } else if args.cmd_verify { + let signature = try!(Signature::from_str(&args.arg_signature)); + let message = try!(Message::from_str(&args.arg_message)); + let ok = if args.cmd_public { + let public = try!(Public::from_str(&args.arg_public)); + try!(verify_public(&public, &signature, &message)) + } else if args.cmd_address { + let address = try!(Address::from_str(&args.arg_address)); + try!(verify_address(&address, &signature, &message)) + } else { + unreachable!(); + }; + Ok(format!("{}", ok)) + } else { + unreachable!(); + } +} + +#[cfg(test)] +mod tests { + use super::execute; + + #[test] + fn info() { + let command = vec!["ethkey", "info", "17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55"] + .into_iter() + .map(Into::into) + .collect::>(); + + let expected = +"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55 +public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 +address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); + assert_eq!(execute(command).unwrap(), expected); + } + + #[test] + fn brain() { + let command = vec!["ethkey", "generate", "brain", "this is sparta"] + .into_iter() + .map(Into::into) + .collect::>(); + + let expected = +"secret: 17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55 +public: 689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124 +address: 26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); + assert_eq!(execute(command).unwrap(), expected); + } + + #[test] + fn secret() { + let command = vec!["ethkey", "generate", "brain", "this is sparta", "--secret"] + .into_iter() + .map(Into::into) + .collect::>(); + + let expected = "17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55".to_owned(); + assert_eq!(execute(command).unwrap(), expected); + } + + #[test] + fn public() { + let command = vec!["ethkey", "generate", "brain", "this is sparta", "--public"] + .into_iter() + .map(Into::into) + .collect::>(); + + let expected = "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124".to_owned(); + assert_eq!(execute(command).unwrap(), expected); + } + + #[test] + fn address() { + let command = vec!["ethkey", "generate", "brain", "this is sparta", "--address"] + .into_iter() + .map(Into::into) + .collect::>(); + + let expected = "26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5".to_owned(); + assert_eq!(execute(command).unwrap(), expected); + } + + #[test] + fn sign() { + let command = vec!["ethkey", "sign", "17d08f5fe8c77af811caa0c9a187e668ce3b74a99acc3f6d976f075fa8e0be55", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987"] + .into_iter() + .map(Into::into) + .collect::>(); + + let expected = "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200".to_owned(); + assert_eq!(execute(command).unwrap(), expected); + } + + #[test] + fn verify_valid_public() { + let command = vec!["ethkey", "verify", "public", "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987"] + .into_iter() + .map(Into::into) + .collect::>(); + + let expected = "true".to_owned(); + assert_eq!(execute(command).unwrap(), expected); + } + + #[test] + fn verify_valid_address() { + let command = vec!["ethkey", "verify", "address", "26d1ec50b4e62c1d1a40d16e7cacc6a6580757d5", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec987"] + .into_iter() + .map(Into::into) + .collect::>(); + + let expected = "true".to_owned(); + assert_eq!(execute(command).unwrap(), expected); + } + + #[test] + fn verify_invalid() { + let command = vec!["ethkey", "verify", "public", "689268c0ff57a20cd299fa60d3fb374862aff565b20b5f1767906a99e6e09f3ff04ca2b2a5cd22f62941db103c0356df1a8ed20ce322cab2483db67685afd124", "c1878cf60417151c766a712653d26ef350c8c75393458b7a9be715f053215af63dfd3b02c2ae65a8677917a8efa3172acb71cb90196e42106953ea0363c5aaf200", "bd50b7370c3f96733b31744c6c45079e7ae6c8d299613246d28ebcef507ec986"] + .into_iter() + .map(Into::into) + .collect::>(); + + let expected = "false".to_owned(); + assert_eq!(execute(command).unwrap(), expected); + } +} diff --git a/ethkey/src/bin/main.rs b/ethkey/src/bin/main.rs new file mode 100644 index 000000000..7c7512a97 --- /dev/null +++ b/ethkey/src/bin/main.rs @@ -0,0 +1,21 @@ +// 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 . + +#[cfg(feature = "cli")] +include!("ethkey.rs"); + +#[cfg(not(feature = "cli"))] +fn main() {} diff --git a/ethkey/src/brain.rs b/ethkey/src/brain.rs new file mode 100644 index 000000000..f7f9322e0 --- /dev/null +++ b/ethkey/src/brain.rs @@ -0,0 +1,62 @@ +// 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 . + +use keccak::Keccak256; +use super::{KeyPair, Error, Generator, Secret}; + +/// Simple brainwallet. +pub struct Brain(String); + +impl Brain { + pub fn new(s: String) -> Self { + Brain(s) + } +} + +impl Generator for Brain { + fn generate(self) -> Result { + let seed = self.0; + let mut secret = seed.bytes().collect::>().keccak256(); + + let mut i = 0; + loop { + secret = secret.keccak256(); + + match i > 16384 { + false => i += 1, + true => { + let result = KeyPair::from_secret(Secret::from(secret.clone())); + if result.is_ok() { + return result + } + }, + } + } + } +} + +#[cfg(test)] +mod tests { + use {Brain, Generator}; + + #[test] + fn test_brain() { + let words = "this is sparta!".to_owned(); + let first_keypair = Brain(words.clone()).generate().unwrap(); + let second_keypair = Brain(words.clone()).generate().unwrap(); + assert_eq!(first_keypair.secret(), second_keypair.secret()); + } +} diff --git a/ethkey/src/error.rs b/ethkey/src/error.rs new file mode 100644 index 000000000..328e85856 --- /dev/null +++ b/ethkey/src/error.rs @@ -0,0 +1,69 @@ +// 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 . + +use std::fmt; + +#[derive(Debug)] +/// Crypto error +pub enum Error { + /// Invalid secret key + InvalidSecret, + /// Invalid public key + InvalidPublic, + /// Invalid address + InvalidAddress, + /// Invalid EC signature + InvalidSignature, + /// Invalid AES message + InvalidMessage, + /// IO Error + Io(::std::io::Error), + /// Custom + Custom(String), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let msg = match *self { + Error::InvalidSecret => "Invalid secret key".into(), + Error::InvalidPublic => "Invalid public key".into(), + Error::InvalidAddress => "Invalid address".into(), + Error::InvalidSignature => "Invalid EC signature".into(), + Error::InvalidMessage => "Invalid AES message".into(), + Error::Io(ref err) => format!("I/O error: {}", err), + Error::Custom(ref s) => s.clone(), + }; + + f.write_fmt(format_args!("Crypto error ({})", msg)) + } +} + +impl From<::secp256k1::Error> for Error { + fn from(e: ::secp256k1::Error) -> Error { + match e { + ::secp256k1::Error::InvalidMessage => Error::InvalidMessage, + ::secp256k1::Error::InvalidPublicKey => Error::InvalidPublic, + ::secp256k1::Error::InvalidSecretKey => Error::InvalidSecret, + _ => Error::InvalidSignature, + } + } +} + +impl From<::std::io::Error> for Error { + fn from(err: ::std::io::Error) -> Error { + Error::Io(err) + } +} diff --git a/ethkey/src/keccak.rs b/ethkey/src/keccak.rs new file mode 100644 index 000000000..18b31a868 --- /dev/null +++ b/ethkey/src/keccak.rs @@ -0,0 +1,31 @@ +// 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 . + +use tiny_keccak::Keccak; + +pub trait Keccak256 { + fn keccak256(&self) -> T where T: Sized; +} + +impl Keccak256<[u8; 32]> for [u8] { + fn keccak256(&self) -> [u8; 32] { + let mut keccak = Keccak::new_keccak256(); + let mut result = [0u8; 32]; + keccak.update(self); + keccak.finalize(&mut result); + result + } +} diff --git a/ethkey/src/keypair.rs b/ethkey/src/keypair.rs new file mode 100644 index 000000000..fa7c1a85e --- /dev/null +++ b/ethkey/src/keypair.rs @@ -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 . + +use std::fmt; +use secp256k1::key; +use rustc_serialize::hex::ToHex; +use keccak::Keccak256; +use super::{Secret, Public, Address, SECP256K1, Error}; + +pub fn public_to_address(public: &Public) -> Address { + let hash = public.keccak256(); + let mut result = Address::default(); + result.copy_from_slice(&hash[12..]); + result +} + +/// secp256k1 key pair +pub struct KeyPair { + secret: Secret, + public: Public, +} + +impl fmt::Display for KeyPair { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + try!(writeln!(f, "secret: {}", self.secret.to_hex())); + try!(writeln!(f, "public: {}", self.public.to_hex())); + write!(f, "address: {}", self.address().to_hex()) + } +} + +impl KeyPair { + /// Create a pair from secret key + pub fn from_secret(secret: Secret) -> Result { + let context = &SECP256K1; + let s: key::SecretKey = try!(key::SecretKey::from_slice(context, &secret[..])); + let pub_key = try!(key::PublicKey::from_secret_key(context, &s)); + let serialized = pub_key.serialize_vec(context, false); + + let mut public = Public::default(); + public.copy_from_slice(&serialized[1..65]); + + let keypair = KeyPair { + secret: secret, + public: public, + }; + + Ok(keypair) + } + + pub fn from_keypair(sec: key::SecretKey, publ: key::PublicKey) -> Self { + let context = &SECP256K1; + let serialized = publ.serialize_vec(context, false); + let mut secret = Secret::default(); + secret.copy_from_slice(&sec[0..32]); + let mut public = Public::default(); + public.copy_from_slice(&serialized[1..65]); + + KeyPair { + secret: secret, + public: public, + } + } + + pub fn secret(&self) -> &Secret { + &self.secret + } + + pub fn public(&self) -> &Public { + &self.public + } + + pub fn address(&self) -> Address { + public_to_address(&self.public) + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use {KeyPair, Secret}; + + #[test] + fn from_secret() { + let secret = Secret::from_str("a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65").unwrap(); + let _ = KeyPair::from_secret(secret).unwrap(); + } + + #[test] + fn keypair_display() { + let expected = +"secret: a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65 +public: 8ce0db0b0359ffc5866ba61903cc2518c3675ef2cf380a7e54bde7ea20e6fa1ab45b7617346cd11b7610001ee6ae5b0155c41cad9527cbcdff44ec67848943a4 +address: 5b073e9233944b5e729e46d618f0d8edf3d9c34a".to_owned(); + let secret = Secret::from_str("a100df7a048e50ed308ea696dc600215098141cb391e9527329df289f9383f65").unwrap(); + let kp = KeyPair::from_secret(secret).unwrap(); + assert_eq!(format!("{}", kp), expected); + } +} diff --git a/ethkey/src/lib.rs b/ethkey/src/lib.rs new file mode 100644 index 000000000..045bbb520 --- /dev/null +++ b/ethkey/src/lib.rs @@ -0,0 +1,49 @@ +// 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 . + +extern crate rand; +#[macro_use] +extern crate lazy_static; +extern crate tiny_keccak; +extern crate secp256k1; +extern crate rustc_serialize; + +mod brain; +mod error; +mod keypair; +mod keccak; +mod prefix; +mod primitive; +mod random; +mod signature; + +lazy_static! { + static ref SECP256K1: secp256k1::Secp256k1 = secp256k1::Secp256k1::new(); +} + +/// Generates new keypair. +pub trait Generator { + /// Should be called to generate new keypair. + fn generate(self) -> Result; +} + +pub use self::brain::Brain; +pub use self::error::Error; +pub use self::keypair::{KeyPair, public_to_address}; +pub use self::primitive::{Secret, Public, Address, Message}; +pub use self::prefix::Prefix; +pub use self::random::Random; +pub use self::signature::{sign, verify_public, verify_address, recover, Signature}; diff --git a/ethkey/src/prefix.rs b/ethkey/src/prefix.rs new file mode 100644 index 000000000..ad5e02c4a --- /dev/null +++ b/ethkey/src/prefix.rs @@ -0,0 +1,57 @@ +// 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 . + +use super::{Random, Generator, KeyPair, Error}; + +/// Tries to find keypair with address starting with given prefix. +pub struct Prefix { + prefix: Vec, + iterations: usize, +} + +impl Prefix { + pub fn new(prefix: Vec, iterations: usize) -> Self { + Prefix { + prefix: prefix, + iterations: iterations, + } + } +} + +impl Generator for Prefix { + fn generate(self) -> Result { + for _ in 0..self.iterations { + let keypair = try!(Random.generate()); + if keypair.address().starts_with(&self.prefix) { + return Ok(keypair) + } + } + + Err(Error::Custom("Could not find keypair".into())) + } +} + +#[cfg(test)] +mod tests { + use {Generator, Prefix}; + + #[test] + fn prefix_generator() { + let prefix = vec![0xffu8]; + let keypair = Prefix::new(prefix.clone(), usize::max_value()).generate().unwrap(); + assert!(keypair.address().starts_with(&prefix)); + } +} diff --git a/ethkey/src/primitive.rs b/ethkey/src/primitive.rs new file mode 100644 index 000000000..761a3000f --- /dev/null +++ b/ethkey/src/primitive.rs @@ -0,0 +1,138 @@ +// 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 . + +use std::ops::{Deref, DerefMut}; +use std::{fmt, cmp, hash}; +use std::str::FromStr; +use rustc_serialize::hex::{ToHex, FromHex}; +use Error; + +macro_rules! impl_primitive { + ($name: ident, $size: expr, $err: expr) => { + + #[repr(C)] + #[derive(Eq)] + pub struct $name([u8; $size]); + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{}", self.to_hex()) + } + } + + impl fmt::Display for $name { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{}", self.to_hex()) + } + } + + impl FromStr for $name { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s.from_hex() { + Ok(ref hex) if hex.len() == $size => { + let mut res = $name::default(); + res.copy_from_slice(hex); + Ok(res) + }, + _ => Err($err) + } + } + } + + impl PartialEq for $name { + fn eq(&self, other: &Self) -> bool { + let self_ref: &[u8] = &self.0; + let other_ref: &[u8] = &other.0; + self_ref == other_ref + } + } + + impl PartialOrd for $name { + fn partial_cmp(&self, other: &Self) -> Option { + let self_ref: &[u8] = &self.0; + let other_ref: &[u8] = &other.0; + self_ref.partial_cmp(other_ref) + } + } + + impl Ord for $name { + fn cmp(&self, other: &Self) -> cmp::Ordering { + let self_ref: &[u8] = &self.0; + let other_ref: &[u8] = &other.0; + self_ref.cmp(other_ref) + } + } + + impl Clone for $name { + fn clone(&self) -> Self { + let mut res = Self::default(); + res.copy_from_slice(&self.0); + res + } + } + + impl Default for $name { + fn default() -> Self { + $name([0u8; $size]) + } + } + + impl From<[u8; $size]> for $name { + fn from(s: [u8; $size]) -> Self { + $name(s) + } + } + + impl Into<[u8; $size]> for $name { + fn into(self) -> [u8; $size] { + self.0 + } + } + + impl hash::Hash for $name { + fn hash(&self, state: &mut H) where H: hash::Hasher { + let self_ref: &[u8] = &self.0; + self_ref.hash(state) + } + } + + impl Deref for $name { + type Target = [u8; $size]; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl DerefMut for $name { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } + } + } +} + +impl_primitive!(Address, 20, Error::InvalidAddress); +impl_primitive!(Secret, 32, Error::InvalidSecret); +impl_primitive!(Message, 32, Error::InvalidMessage); +impl_primitive!(Public, 64, Error::InvalidPublic); + +#[cfg(test)] +mod tests { + +} diff --git a/ethkey/src/random.rs b/ethkey/src/random.rs new file mode 100644 index 000000000..ea4cdaec6 --- /dev/null +++ b/ethkey/src/random.rs @@ -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 . + +use rand::os::OsRng; +use super::{Generator, KeyPair, Error, SECP256K1}; + +/// Randomly generates new keypair. +pub struct Random; + +impl Generator for Random { + fn generate(self) -> Result { + let context = &SECP256K1; + let mut rng = try!(OsRng::new()); + let (sec, publ) = try!(context.generate_keypair(&mut rng)); + + Ok(KeyPair::from_keypair(sec, publ)) + } +} + diff --git a/ethkey/src/signature.rs b/ethkey/src/signature.rs new file mode 100644 index 000000000..616db7bc9 --- /dev/null +++ b/ethkey/src/signature.rs @@ -0,0 +1,207 @@ +// 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 . + +use std::ops::{Deref, DerefMut}; +use std::{mem, fmt}; +use std::str::FromStr; +use secp256k1::{Message as SecpMessage, RecoverableSignature, RecoveryId, Error as SecpError}; +use secp256k1::key::{SecretKey, PublicKey}; +use rustc_serialize::hex::{ToHex, FromHex}; +use {Secret, Public, SECP256K1, Error, Message, public_to_address, Address}; + +#[repr(C)] +#[derive(Eq)] +pub struct Signature([u8; 65]); + +impl Signature { + /// Get a slice into the 'r' portion of the data. + pub fn r(&self) -> &[u8] { + &self.0[0..32] + } + + /// Get a slice into the 's' portion of the data. + pub fn s(&self) -> &[u8] { + &self.0[32..64] + } + + /// Get the recovery byte. + pub fn v(&self) -> u8 { + self.0[64] + } +} + +// manual implementation large arrays don't have trait impls by default. +// remove when integer generics exist +impl ::std::cmp::PartialEq for Signature { + fn eq(&self, other: &Self) -> bool { + &self.0[..] == &other.0[..] + } +} + +// also manual for the same reason, but the pretty printing might be useful. +impl fmt::Debug for Signature { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + f.debug_struct("Signature") + .field("r", &self.0[0..32].to_hex()) + .field("s", &self.0[32..64].to_hex()) + .field("v", &self.0[64..65].to_hex()) + .finish() + } +} + +impl fmt::Display for Signature { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + write!(f, "{}", self.to_hex()) + } +} + +impl FromStr for Signature { + type Err = Error; + + fn from_str(s: &str) -> Result { + match s.from_hex() { + Ok(ref hex) if hex.len() == 65 => { + let mut data = [0; 65]; + data.copy_from_slice(&hex[0..65]); + Ok(Signature(data)) + }, + _ => Err(Error::InvalidSignature) + } + } +} + +impl Default for Signature { + fn default() -> Self { + Signature([0; 65]) + } +} + +impl From<[u8; 65]> for Signature { + fn from(s: [u8; 65]) -> Self { + Signature(s) + } +} + +impl Into<[u8; 65]> for Signature { + fn into(self) -> [u8; 65] { + self.0 + } +} + +impl Deref for Signature { + type Target = [u8; 65]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for Signature { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +pub fn sign(secret: &Secret, message: &Message) -> Result { + let context = &SECP256K1; + // no way to create from raw byte array. + let sec: &SecretKey = unsafe { mem::transmute(secret) }; + let s = try!(context.sign_recoverable(&try!(SecpMessage::from_slice(&message[..])), sec)); + let (rec_id, data) = s.serialize_compact(context); + let mut data_arr = [0; 65]; + + // no need to check if s is low, it always is + data_arr[0..64].copy_from_slice(&data[0..64]); + data_arr[64] = rec_id.to_i32() as u8; + Ok(Signature(data_arr)) +} + +pub fn verify_public(public: &Public, signature: &Signature, message: &Message) -> Result { + let context = &SECP256K1; + let rsig = try!(RecoverableSignature::from_compact(context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32)))); + let sig = rsig.to_standard(context); + + let pdata: [u8; 65] = { + let mut temp = [4u8; 65]; + temp[1..65].copy_from_slice(public.deref()); + temp + }; + + let publ = try!(PublicKey::from_slice(context, &pdata)); + match context.verify(&try!(SecpMessage::from_slice(&message[..])), &sig, &publ) { + Ok(_) => Ok(true), + Err(SecpError::IncorrectSignature) => Ok(false), + Err(x) => Err(Error::from(x)) + } +} + +pub fn verify_address(address: &Address, signature: &Signature, message: &Message) -> Result { + let public = try!(recover(signature, message)); + let recovered_address = public_to_address(&public); + Ok(address == &recovered_address) +} + +pub fn recover(signature: &Signature, message: &Message) -> Result { + let context = &SECP256K1; + let rsig = try!(RecoverableSignature::from_compact(context, &signature[0..64], try!(RecoveryId::from_i32(signature[64] as i32)))); + let pubkey = try!(context.recover(&try!(SecpMessage::from_slice(&message[..])), &rsig)); + let serialized = pubkey.serialize_vec(context, false); + + let mut public = Public::default(); + public.copy_from_slice(&serialized[1..65]); + Ok(public) +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use {Generator, Random, Message}; + use super::{sign, verify_public, verify_address, recover, Signature}; + + #[test] + fn signature_to_and_from_str() { + let keypair = Random.generate().unwrap(); + let message = Message::default(); + let signature = sign(keypair.secret(), &message).unwrap(); + let string = format!("{}", signature); + let deserialized = Signature::from_str(&string).unwrap(); + assert_eq!(signature, deserialized); + } + + #[test] + fn sign_and_recover_public() { + let keypair = Random.generate().unwrap(); + let message = Message::default(); + let signature = sign(keypair.secret(), &message).unwrap(); + assert_eq!(keypair.public(), &recover(&signature, &message).unwrap()); + } + + #[test] + fn sign_and_verify_public() { + let keypair = Random.generate().unwrap(); + let message = Message::default(); + let signature = sign(keypair.secret(), &message).unwrap(); + assert!(verify_public(keypair.public(), &signature, &message).unwrap()); + } + + #[test] + fn sign_and_verify_address() { + let keypair = Random.generate().unwrap(); + let message = Message::default(); + let signature = sign(keypair.secret(), &message).unwrap(); + assert!(verify_address(&keypair.address(), &signature, &message).unwrap()); + } +} diff --git a/ethstore/.editorconfig b/ethstore/.editorconfig new file mode 100644 index 000000000..0ac22f073 --- /dev/null +++ b/ethstore/.editorconfig @@ -0,0 +1,11 @@ +root = true +[*] +indent_style=tab +indent_size=tab +tab_width=4 +end_of_line=lf +charset=utf-8 +trim_trailing_whitespace=true +max_line_length=120 +insert_final_newline=true + diff --git a/ethstore/.gitignore b/ethstore/.gitignore new file mode 100644 index 000000000..c6262ea6a --- /dev/null +++ b/ethstore/.gitignore @@ -0,0 +1,2 @@ +target +*.swp diff --git a/ethstore/.travis.yml b/ethstore/.travis.yml new file mode 100644 index 000000000..8113e488e --- /dev/null +++ b/ethstore/.travis.yml @@ -0,0 +1,23 @@ +sudo: false +language: rust +branches: + only: + - master +matrix: + fast_finish: false + include: + - rust: stable + - rust: beta + - rust: nightly +after_success: | + [ $TRAVIS_BRANCH = master ] && + [ $TRAVIS_PULL_REQUEST = false ] && + [ $TRAVIS_RUST_VERSION = stable ] && + cargo doc --no-deps --verbose && + echo '' > target/doc/index.html && + pip install --user ghp-import && + /home/travis/.local/bin/ghp-import -n target/doc && + git push -fq https://${GH_TOKEN}@github.com/${TRAVIS_REPO_SLUG}.git gh-pages +env: + global: + - secure: C4l7WR0jS84WNmd3MvmpPXQz4wRh4CLDS6bP3BqSHXadz8FPKejtMJZscLYAk5kIkDcVsTAYb88RsEFRrYOA4wkS6vhZBtryYRaJ68MlkyEU/77SYwm86rkQINIDw65O73dUD5LbWWCUoYkenGu26u/UnfayHfJBAyKw5IHkVKf6eDqu7E8ojKSEOXbWgBHjq6uixI8IESb15UjIE0AQ1Od+6cqhsz/caPhTMT3CJGjoCoVGWChwWSQZ+Ppb+xB83C/1h58UVwE9sZEyIPKwVP6socnHPmtR+VEUI6a7YIsOk6ZadKLtyy4523w4HqHNx1/dYjmsknbGpkF4D0DRp5L3D4t4J6URCkJIHfSRrBF5l2QbLMMuSf+KWMWuFOrOF5DBryobRKAVmIL5AjfvFsxtBNzYLPyVBs0ntbPuN5WeUPhadam00za9Z1ZvOUJxfNfyy9R67u6FdD9xkw2m/9hO7KJLDeZ4TSCRFrzfl/7WQprfjCwhZ+reKPgHH0Ufy1/Kh/WEuEBfZDa+z3mWWHlslqH2uBPH3+pvhzdVQGLB/5GZdJNeg/nJYJDCqHyWUKxkw+OMSvI0J8W0GiHV4TuY9V3p+rYjU2Zj69u3/xO/IvKrFtB9xdeJMrLiFQ2cD5vgzQOLCKo80f53NitUjdVSoWrY/NcYopBU4VHZMlk= diff --git a/ethstore/Cargo.toml b/ethstore/Cargo.toml new file mode 100644 index 000000000..cfb5b9fbc --- /dev/null +++ b/ethstore/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "ethstore" +version = "0.1.0" +authors = ["debris "] +build = "build.rs" + +[dependencies] +libc = "0.2.11" +rand = "0.3.14" +ethkey = { path = "../ethkey" } +serde = "0.7" +serde_json = "0.7" +serde_macros = { version = "0.7", optional = true } +rustc-serialize = "0.3" +rust-crypto = "0.2.36" +tiny-keccak = "1.0" +docopt = { version = "0.6", optional = true } + +[build-dependencies] +serde_codegen = { version = "0.7", optional = true } +syntex = "0.33.0" + +[features] +default = ["serde_codegen"] +nightly = ["serde_macros"] +cli = ["docopt"] + +[[bin]] +name = "ethstore" +doc = false diff --git a/ethstore/README.md b/ethstore/README.md new file mode 100644 index 000000000..0b85d99b4 --- /dev/null +++ b/ethstore/README.md @@ -0,0 +1,185 @@ +# ethstore + +[![Build Status][travis-image]][travis-url] + +[travis-image]: https://travis-ci.org/ethcore/ethstore.svg?branch=master +[travis-url]: https://travis-ci.org/ethcore/ethstore + +Ethereum key management. + +[Documentation](http://ethcore.github.io/ethstore/ethstore/index.html) + +### Usage + +``` +Ethereum key management. + Copyright 2016 Ethcore (UK) Limited + +Usage: + ethstore insert [--dir DIR] + ethstore change-pwd
[--dir DIR] + ethstore list [--dir DIR] + ethstore import [--src DIR] [--dir DIR] + ethstore import-wallet [--dir DIR] + ethstore remove
[--dir DIR] + ethstore sign
[--dir DIR] + ethstore [-h | --help] + +Options: + -h, --help Display this message and exit. + --dir DIR Specify the secret store directory. It may be either + parity, parity-test, geth, geth-test + or a path [default: parity]. + --src DIR Specify import source. It may be either + parity, parity-test, get, geth-test + or a path [default: geth]. + +Commands: + insert Save account with password. + change-pwd Change account password. + list List accounts. + import Import accounts from src. + import-wallet Import presale wallet. + remove Remove account. + sign Sign message. +``` + +### Examples + +#### `insert [--dir DIR]` +*Encrypt secret with a password and save it in secret store.* + +- `` - ethereum secret, 32 bytes long +- `` - account password, file path +- `[--dir DIR]` - secret store directory, It may be either parity, parity-test, geth, geth-test or a path. default: parity + +``` +ethstore insert 7d29fab185a33e2cd955812397354c472d2b84615b645aa135ff539f6b0d70d5 password.txt +``` + +``` +a8fa5dd30a87bb9e3288d604eb74949c515ab66e +``` + +-- + +``` +ethstore insert `ethkey generate random -s` "this is sparta" +``` + +``` +24edfff680d536a5f6fe862d36df6f8f6f40f115 +``` + +-- + +#### `change-pwd
[--dir DIR]` +*Change account password.* + +- `
` - ethereum address, 20 bytes long +- `` - old account password, file path +- `` - new account password, file path +- `[--dir DIR]` - secret store directory, It may be either parity, parity-test, geth, geth-test or a path. default: parity + +``` +ethstore change-pwd a8fa5dd30a87bb9e3288d604eb74949c515ab66e old_pwd.txt new_pwd.txt +``` + +``` +true +``` + +-- + +#### `list [--dir DIR]` +*List secret store accounts.* + +- `[--dir DIR]` - secret store directory, It may be either parity, parity-test, geth, geth-test or a path. default: parity + +``` +ethstore list +``` + +``` + 0: 24edfff680d536a5f6fe862d36df6f8f6f40f115 + 1: 6edddfc6349aff20bc6467ccf276c5b52487f7a8 + 2: e6a3d25a7cb7cd21cb720df5b5e8afd154af1bbb +``` + +-- + +#### `import [--src DIR] [--dir DIR]` +*Import accounts from src.* + +- `[--src DIR]` - secret store directory, It may be either parity, parity-test, geth, geth-test or a path. default: geth +- `[--dir DIR]` - secret store directory, It may be either parity, parity-test, geth, geth-test or a path. default: parity + +``` +ethstore import +``` + +``` + 0: e6a3d25a7cb7cd21cb720df5b5e8afd154af1bbb + 1: 6edddfc6349aff20bc6467ccf276c5b52487f7a8 +``` + +-- + +#### `import-wallet [--dir DIR]` +*Import account from presale wallet.* + +- `` - presale wallet path +- `` - account password, file path +- `[--dir DIR]` - secret store directory, It may be either parity, parity-test, geth, geth-test or a path. default: parity + +``` +ethstore import-wallet ethwallet.json password.txt +``` + +``` +e6a3d25a7cb7cd21cb720df5b5e8afd154af1bbb +``` + +-- + +#### `remove
[--dir DIR]` +*Remove account from secret store.* + +- `
` - ethereum address, 20 bytes long +- `` - account password, file path +- `[--dir DIR]` - secret store directory, It may be either parity, parity-test, geth, geth-test or a path. default: parity + +``` +ethstore remove a8fa5dd30a87bb9e3288d604eb74949c515ab66e password.txt +``` + +``` +true +``` + +-- + +#### `sign
[--dir DIR]` +*Sign message with account's secret.* + +- `
` - ethereum address, 20 bytes long +- `` - account password, file path +- `` - message to sign, 32 bytes long +- `[--dir DIR]` - secret store directory, It may be either parity, parity-test, geth, geth-test or a path. default: parity + +``` +ethstore sign 24edfff680d536a5f6fe862d36df6f8f6f40f115 password.txt 7d29fab185a33e2cd955812397354c472d2b84615b645aa135ff539f6b0d70d5 +``` + +``` +c6649f9555232d90ff716d7e552a744c5af771574425a74860e12f763479eb1b708c1f3a7dc0a0a7f7a81e0a0ca88c6deacf469222bb3d9c5bf0847f98bae54901 +``` + +-- + +# Ethcore toolchain +*this project is a part of the ethcore toolchain* + +- [**ethkey**](https://github.com/ethcore/ethkey) - Ethereum keys generator and signer. +- [**ethstore**](https://github.com/ethcore/ethstore) - Ethereum key management. +- [**ethabi**](https://github.com/ethcore/ethabi) - Ethereum function calls encoding. diff --git a/ethstore/build.rs b/ethstore/build.rs new file mode 100644 index 000000000..1c4e05f84 --- /dev/null +++ b/ethstore/build.rs @@ -0,0 +1,45 @@ +// 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 . + +#[cfg(not(feature = "serde_macros"))] +mod inner { + extern crate syntex; + extern crate serde_codegen; + + use std::env; + use std::path::Path; + + pub fn main() { + let out_dir = env::var_os("OUT_DIR").unwrap(); + + let src = Path::new("src/json/mod.rs.in"); + let dst = Path::new(&out_dir).join("mod.rs"); + + let mut registry = syntex::Registry::new(); + + serde_codegen::register(&mut registry); + registry.expand("", &src, &dst).unwrap(); + } +} + +#[cfg(feature = "serde_macros")] +mod inner { + pub fn main() {} +} + +fn main() { + inner::main(); +} diff --git a/ethstore/src/account/cipher.rs b/ethstore/src/account/cipher.rs new file mode 100644 index 000000000..1b9d49b26 --- /dev/null +++ b/ethstore/src/account/cipher.rs @@ -0,0 +1,59 @@ +// 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 . + +use json; + +#[derive(Debug, PartialEq, Clone)] +pub struct Aes128Ctr { + pub iv: [u8; 16], +} + +#[derive(Debug, PartialEq, Clone)] +pub enum Cipher { + Aes128Ctr(Aes128Ctr), +} + +impl From for Aes128Ctr { + fn from(json: json::Aes128Ctr) -> Self { + Aes128Ctr { + iv: json.iv.into() + } + } +} + +impl Into for Aes128Ctr { + fn into(self) -> json::Aes128Ctr { + json::Aes128Ctr { + iv: From::from(self.iv) + } + } +} + +impl From for Cipher { + fn from(json: json::Cipher) -> Self { + match json { + json::Cipher::Aes128Ctr(params) => Cipher::Aes128Ctr(From::from(params)), + } + } +} + +impl Into for Cipher { + fn into(self) -> json::Cipher { + match self { + Cipher::Aes128Ctr(params) => json::Cipher::Aes128Ctr(params.into()), + } + } +} diff --git a/ethstore/src/account/kdf.rs b/ethstore/src/account/kdf.rs new file mode 100644 index 000000000..0cabce625 --- /dev/null +++ b/ethstore/src/account/kdf.rs @@ -0,0 +1,125 @@ +// 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 . + +use json; + +#[derive(Debug, PartialEq, Clone)] +pub enum Prf { + HmacSha256, +} + +#[derive(Debug, PartialEq, Clone)] +pub struct Pbkdf2 { + pub c: u32, + pub dklen: u32, + pub prf: Prf, + pub salt: [u8; 32], +} + +#[derive(Debug, PartialEq, Clone)] +pub struct Scrypt { + pub dklen: u32, + pub p: u32, + pub n: u32, + pub r: u32, + pub salt: [u8; 32], +} + +#[derive(Debug, PartialEq, Clone)] +pub enum Kdf { + Pbkdf2(Pbkdf2), + Scrypt(Scrypt), +} + +impl From for Prf { + fn from(json: json::Prf) -> Self { + match json { + json::Prf::HmacSha256 => Prf::HmacSha256, + } + } +} + +impl Into for Prf { + fn into(self) -> json::Prf { + match self { + Prf::HmacSha256 => json::Prf::HmacSha256, + } + } +} + +impl From for Pbkdf2 { + fn from(json: json::Pbkdf2) -> Self { + Pbkdf2 { + c: json.c, + dklen: json.dklen, + prf: From::from(json.prf), + salt: json.salt.into(), + } + } +} + +impl Into for Pbkdf2 { + fn into(self) -> json::Pbkdf2 { + json::Pbkdf2 { + c: self.c, + dklen: self.dklen, + prf: self.prf.into(), + salt: From::from(self.salt), + } + } +} + +impl From for Scrypt { + fn from(json: json::Scrypt) -> Self { + Scrypt { + dklen: json.dklen, + p: json.p, + n: json.n, + r: json.r, + salt: json.salt.into(), + } + } +} + +impl Into for Scrypt { + fn into(self) -> json::Scrypt { + json::Scrypt { + dklen: self.dklen, + p: self.p, + n: self.n, + r: self.r, + salt: From::from(self.salt), + } + } +} + +impl From for Kdf { + fn from(json: json::Kdf) -> Self { + match json { + json::Kdf::Pbkdf2(params) => Kdf::Pbkdf2(From::from(params)), + json::Kdf::Scrypt(params) => Kdf::Scrypt(From::from(params)), + } + } +} + +impl Into for Kdf { + fn into(self) -> json::Kdf { + match self { + Kdf::Pbkdf2(params) => json::Kdf::Pbkdf2(params.into()), + Kdf::Scrypt(params) => json::Kdf::Scrypt(params.into()), + } + } +} diff --git a/ethstore/src/account/mod.rs b/ethstore/src/account/mod.rs new file mode 100644 index 000000000..b4c3e1113 --- /dev/null +++ b/ethstore/src/account/mod.rs @@ -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 . + +mod cipher; +mod kdf; +mod safe_account; +mod version; + +pub use self::cipher::{Cipher, Aes128Ctr}; +pub use self::kdf::{Kdf, Pbkdf2, Scrypt, Prf}; +pub use self::safe_account::{SafeAccount, Crypto}; +pub use self::version::Version; diff --git a/ethstore/src/account/safe_account.rs b/ethstore/src/account/safe_account.rs new file mode 100644 index 000000000..eba2c41d3 --- /dev/null +++ b/ethstore/src/account/safe_account.rs @@ -0,0 +1,216 @@ +// 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 . + +use std::ops::{Deref, DerefMut}; +use ethkey::{KeyPair, sign, Address, Secret, Signature, Message}; +use {json, Error, crypto}; +use crypto::Keccak256; +use random::Random; +use account::{Version, Cipher, Kdf, Aes128Ctr, Pbkdf2, Prf}; + +#[derive(Debug, PartialEq, Clone)] +pub struct Crypto { + pub cipher: Cipher, + pub ciphertext: [u8; 32], + pub kdf: Kdf, + pub mac: [u8; 32], +} + +#[derive(Debug, PartialEq, Clone)] +pub struct SafeAccount { + pub id: [u8; 16], + pub version: Version, + pub address: Address, + pub crypto: Crypto, +} + +impl From for Crypto { + fn from(json: json::Crypto) -> Self { + Crypto { + cipher: From::from(json.cipher), + ciphertext: json.ciphertext.into(), + kdf: From::from(json.kdf), + mac: json.mac.into(), + } + } +} + +impl Into for Crypto { + fn into(self) -> json::Crypto { + json::Crypto { + cipher: self.cipher.into(), + ciphertext: From::from(self.ciphertext), + kdf: self.kdf.into(), + mac: From::from(self.mac), + } + } +} + +impl From for SafeAccount { + fn from(json: json::KeyFile) -> Self { + SafeAccount { + id: json.id.into(), + version: From::from(json.version), + address: From::from(json.address), //json.address.into(), + crypto: From::from(json.crypto), + } + } +} + +impl Into for SafeAccount { + fn into(self) -> json::KeyFile { + json::KeyFile { + id: From::from(self.id), + version: self.version.into(), + address: self.address.into(), //From::from(self.address), + crypto: self.crypto.into(), + } + } +} + +impl Crypto { + pub fn create(secret: &Secret, password: &str, iterations: u32) -> Self { + let salt: [u8; 32] = Random::random(); + let iv: [u8; 16] = Random::random(); + + // two parts of derived key + // DK = [ DK[0..15] DK[16..31] ] = [derived_left_bits, derived_right_bits] + let (derived_left_bits, derived_right_bits) = crypto::derive_key_iterations(password, &salt, iterations); + + let mut ciphertext = [0u8; 32]; + + // aes-128-ctr with initial vector of iv + crypto::aes::encrypt(&derived_left_bits, &iv, secret.deref(), &mut ciphertext); + + // KECCAK(DK[16..31] ++ ), where DK[16..31] - derived_right_bits + let mac = crypto::derive_mac(&derived_right_bits, &ciphertext).keccak256(); + + Crypto { + cipher: Cipher::Aes128Ctr(Aes128Ctr { + iv: iv, + }), + ciphertext: ciphertext, + kdf: Kdf::Pbkdf2(Pbkdf2 { + dklen: crypto::KEY_LENGTH as u32, + salt: salt, + c: iterations, + prf: Prf::HmacSha256, + }), + mac: mac, + } + } + + pub fn secret(&self, password: &str) -> Result { + let (derived_left_bits, derived_right_bits) = match self.kdf { + Kdf::Pbkdf2(ref params) => crypto::derive_key_iterations(password, ¶ms.salt, params.c), + Kdf::Scrypt(ref params) => crypto::derive_key_scrypt(password, ¶ms.salt, params.n, params.p, params.r), + }; + + let mac = crypto::derive_mac(&derived_right_bits, &self.ciphertext).keccak256(); + + if mac != self.mac { + return Err(Error::InvalidPassword); + } + + let mut secret = Secret::default(); + + match self.cipher { + Cipher::Aes128Ctr(ref params) => { + crypto::aes::decrypt(&derived_left_bits, ¶ms.iv, &self.ciphertext, secret.deref_mut()) + }, + } + + Ok(secret) + } +} + +impl SafeAccount { + pub fn create(keypair: &KeyPair, id: [u8; 16], password: &str, iterations: u32) -> Self { + SafeAccount { + id: id, + version: Version::V3, + crypto: Crypto::create(keypair.secret(), password, iterations), + address: keypair.address(), + } + } + + pub fn sign(&self, password: &str, message: &Message) -> Result { + let secret = try!(self.crypto.secret(password)); + sign(&secret, message).map_err(From::from) + } + + pub fn change_password(&self, old_password: &str, new_password: &str, iterations: u32) -> Result { + let secret = try!(self.crypto.secret(old_password)); + let result = SafeAccount { + id: self.id.clone(), + version: self.version.clone(), + crypto: Crypto::create(&secret, new_password, iterations), + address: self.address.clone(), + }; + Ok(result) + } + + pub fn check_password(&self, password: &str) -> bool { + self.crypto.secret(password).is_ok() + } +} + +#[cfg(test)] +mod tests { + use ethkey::{Generator, Random, verify_public, Message}; + use super::{Crypto, SafeAccount}; + + #[test] + fn crypto_create() { + let keypair = Random.generate().unwrap(); + let crypto = Crypto::create(keypair.secret(), "this is sparta", 10240); + let secret = crypto.secret("this is sparta").unwrap(); + assert_eq!(keypair.secret(), &secret); + } + + #[test] + #[should_panic] + fn crypto_invalid_password() { + let keypair = Random.generate().unwrap(); + let crypto = Crypto::create(keypair.secret(), "this is sparta", 10240); + let _ = crypto.secret("this is sparta!").unwrap(); + } + + #[test] + fn sign_and_verify_public() { + let keypair = Random.generate().unwrap(); + let password = "hello world"; + let message = Message::default(); + let account = SafeAccount::create(&keypair, [0u8; 16], password, 10240); + let signature = account.sign(password, &message).unwrap(); + assert!(verify_public(keypair.public(), &signature, &message).unwrap()); + } + + #[test] + fn change_password() { + let keypair = Random.generate().unwrap(); + let first_password = "hello world"; + let sec_password = "this is sparta"; + let i = 10240; + let message = Message::default(); + let account = SafeAccount::create(&keypair, [0u8; 16], first_password, i); + let new_account = account.change_password(first_password, sec_password, i).unwrap(); + assert!(account.sign(first_password, &message).is_ok()); + assert!(account.sign(sec_password, &message).is_err()); + assert!(new_account.sign(first_password, &message).is_err()); + assert!(new_account.sign(sec_password, &message).is_ok()); + } +} diff --git a/ethstore/src/account/version.rs b/ethstore/src/account/version.rs new file mode 100644 index 000000000..465ce4e1b --- /dev/null +++ b/ethstore/src/account/version.rs @@ -0,0 +1,38 @@ +// 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 . + +use json; + +#[derive(Debug, PartialEq, Clone)] +pub enum Version { + V3, +} + +impl From for Version { + fn from(json: json::Version) -> Self { + match json { + json::Version::V3 => Version::V3, + } + } +} + +impl Into for Version { + fn into(self) -> json::Version { + match self { + Version::V3 => json::Version::V3, + } + } +} diff --git a/ethstore/src/bin/ethstore.rs b/ethstore/src/bin/ethstore.rs new file mode 100644 index 000000000..5683a8116 --- /dev/null +++ b/ethstore/src/bin/ethstore.rs @@ -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 . + +extern crate rustc_serialize; +extern crate docopt; +extern crate ethstore; + +use std::{env, process, fs}; +use std::io::Read; +use std::ops::Deref; +use std::str::FromStr; +use docopt::Docopt; +use ethstore::ethkey::{Secret, Address, Message}; +use ethstore::dir::{KeyDirectory, ParityDirectory, DiskDirectory, GethDirectory, DirectoryType}; +use ethstore::{EthStore, SecretStore, import_accounts, Error, PresaleWallet}; + +pub const USAGE: &'static str = r#" +Ethereum key management. + Copyright 2016 Ethcore (UK) Limited + +Usage: + ethstore insert [--dir DIR] + ethstore change-pwd
[--dir DIR] + ethstore list [--dir DIR] + ethstore import [--src DIR] [--dir DIR] + ethstore import-wallet [--dir DIR] + ethstore remove
[--dir DIR] + ethstore sign
[--dir DIR] + ethstore [-h | --help] + +Options: + -h, --help Display this message and exit. + --dir DIR Specify the secret store directory. It may be either + parity, parity-test, geth, geth-test + or a path [default: parity]. + --src DIR Specify import source. It may be either + parity, parity-test, get, geth-test + or a path [default: geth]. + +Commands: + insert Save account with password. + change-pwd Change password. + list List accounts. + import Import accounts from src. + import-wallet Import presale wallet. + remove Remove account. + sign Sign message. +"#; + +#[derive(Debug, RustcDecodable)] +struct Args { + cmd_insert: bool, + cmd_change_pwd: bool, + cmd_list: bool, + cmd_import: bool, + cmd_import_wallet: bool, + cmd_remove: bool, + cmd_sign: bool, + arg_secret: String, + arg_password: String, + arg_old_pwd: String, + arg_new_pwd: String, + arg_address: String, + arg_message: String, + arg_path: String, + flag_src: String, + flag_dir: String, +} + +fn main() { + match execute(env::args()) { + Ok(result) => println!("{}", result), + Err(err) => { + println!("{}", err); + process::exit(1); + } + } +} + +fn key_dir(location: &str) -> Result, Error> { + let dir: Box = match location { + "parity" => Box::new(try!(ParityDirectory::create(DirectoryType::Main))), + "parity-test" => Box::new(try!(ParityDirectory::create(DirectoryType::Testnet))), + "geth" => Box::new(try!(GethDirectory::create(DirectoryType::Main))), + "geth-test" => Box::new(try!(GethDirectory::create(DirectoryType::Testnet))), + path => Box::new(try!(DiskDirectory::create(path))), + }; + + Ok(dir) +} + +fn format_accounts(accounts: &[Address]) -> String { + accounts.iter() + .enumerate() + .map(|(i, a)| format!("{:2}: {}", i, a)) + .collect::>() + .join("\n") +} + +fn load_password(path: &str) -> Result { + let mut file = try!(fs::File::open(path)); + let mut password = String::new(); + try!(file.read_to_string(&mut password)); + // drop EOF + let _ = password.pop(); + Ok(password) +} + +fn execute(command: I) -> Result where I: IntoIterator, S: AsRef { + let args: Args = Docopt::new(USAGE) + .and_then(|d| d.argv(command).decode()) + .unwrap_or_else(|e| e.exit()); + + let store = try!(EthStore::open(try!(key_dir(&args.flag_dir)))); + + return if args.cmd_insert { + let secret = try!(Secret::from_str(&args.arg_secret)); + let password = try!(load_password(&args.arg_password)); + let address = try!(store.insert_account(secret, &password)); + Ok(format!("{}", address)) + } else if args.cmd_change_pwd { + let address = try!(Address::from_str(&args.arg_address)); + let old_pwd = try!(load_password(&args.arg_old_pwd)); + let new_pwd = try!(load_password(&args.arg_new_pwd)); + let ok = store.change_password(&address, &old_pwd, &new_pwd).is_ok(); + Ok(format!("{}", ok)) + } else if args.cmd_list { + let accounts = store.accounts(); + Ok(format_accounts(&accounts)) + } else if args.cmd_import { + let src = try!(key_dir(&args.flag_src)); + let dst = try!(key_dir(&args.flag_dir)); + let accounts = try!(import_accounts(src.deref(), dst.deref())); + Ok(format_accounts(&accounts)) + } else if args.cmd_import_wallet { + let wallet = try!(PresaleWallet::open(&args.arg_path)); + let password = try!(load_password(&args.arg_password)); + let kp = try!(wallet.decrypt(&password)); + let address = try!(store.insert_account(kp.secret().clone(), &password)); + Ok(format!("{}", address)) + } else if args.cmd_remove { + let address = try!(Address::from_str(&args.arg_address)); + let password = try!(load_password(&args.arg_password)); + let ok = store.remove_account(&address, &password).is_ok(); + Ok(format!("{}", ok)) + } else if args.cmd_sign { + let address = try!(Address::from_str(&args.arg_address)); + let message = try!(Message::from_str(&args.arg_message)); + let password = try!(load_password(&args.arg_password)); + let signature = try!(store.sign(&address, &password, &message)); + Ok(format!("{}", signature)) + } else { + unreachable!(); + } +} + diff --git a/ethstore/src/bin/main.rs b/ethstore/src/bin/main.rs new file mode 100644 index 000000000..eee1fa39c --- /dev/null +++ b/ethstore/src/bin/main.rs @@ -0,0 +1,21 @@ +// 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 . + +#[cfg(feature = "cli")] +include!("ethstore.rs"); + +#[cfg(not(feature = "cli"))] +fn main() {} diff --git a/ethstore/src/crypto.rs b/ethstore/src/crypto.rs new file mode 100644 index 000000000..d8169c9c3 --- /dev/null +++ b/ethstore/src/crypto.rs @@ -0,0 +1,93 @@ +// 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 . + +use tiny_keccak::Keccak; +use rcrypto::pbkdf2::pbkdf2; +use rcrypto::scrypt::{scrypt, ScryptParams}; +use rcrypto::sha2::Sha256; +use rcrypto::hmac::Hmac; + +pub const KEY_LENGTH: usize = 32; +pub const KEY_ITERATIONS: usize = 10240; +pub const KEY_LENGTH_AES: usize = KEY_LENGTH / 2; + +pub fn derive_key_iterations(password: &str, salt: &[u8; 32], c: u32) -> (Vec, Vec) { + let mut h_mac = Hmac::new(Sha256::new(), password.as_bytes()); + let mut derived_key = vec![0u8; KEY_LENGTH]; + pbkdf2(&mut h_mac, salt, c, &mut derived_key); + let derived_right_bits = &derived_key[0..KEY_LENGTH_AES]; + let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH]; + (derived_right_bits.to_vec(), derived_left_bits.to_vec()) +} + +pub fn derive_key_scrypt(password: &str, salt: &[u8; 32], n: u32, p: u32, r: u32) -> (Vec, Vec) { + let mut derived_key = vec![0u8; KEY_LENGTH]; + let scrypt_params = ScryptParams::new(n.trailing_zeros() as u8, r, p); + scrypt(password.as_bytes(), salt, &scrypt_params, &mut derived_key); + let derived_right_bits = &derived_key[0..KEY_LENGTH_AES]; + let derived_left_bits = &derived_key[KEY_LENGTH_AES..KEY_LENGTH]; + (derived_right_bits.to_vec(), derived_left_bits.to_vec()) +} + +pub fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Vec { + let mut mac = vec![0u8; KEY_LENGTH_AES + cipher_text.len()]; + mac[0..KEY_LENGTH_AES].copy_from_slice(derived_left_bits); + mac[KEY_LENGTH_AES..cipher_text.len() + KEY_LENGTH_AES].copy_from_slice(cipher_text); + mac +} + +pub trait Keccak256 { + fn keccak256(&self) -> T where T: Sized; +} + +impl Keccak256<[u8; 32]> for [u8] { + fn keccak256(&self) -> [u8; 32] { + let mut keccak = Keccak::new_keccak256(); + let mut result = [0u8; 32]; + keccak.update(self); + keccak.finalize(&mut result); + result + } +} + +/// AES encryption +pub mod aes { + use rcrypto::blockmodes::{CtrMode, CbcDecryptor, PkcsPadding}; + use rcrypto::aessafe::{AesSafe128Encryptor, AesSafe128Decryptor}; + use rcrypto::symmetriccipher::{Encryptor, Decryptor, SymmetricCipherError}; + use rcrypto::buffer::{RefReadBuffer, RefWriteBuffer}; + + /// Encrypt a message + pub fn encrypt(k: &[u8], iv: &[u8], plain: &[u8], dest: &mut [u8]) { + let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); + encryptor.encrypt(&mut RefReadBuffer::new(plain), &mut RefWriteBuffer::new(dest), true).expect("Invalid length or padding"); + } + + /// Decrypt a message + pub fn decrypt(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) { + let mut encryptor = CtrMode::new(AesSafe128Encryptor::new(k), iv.to_vec()); + encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut RefWriteBuffer::new(dest), true).expect("Invalid length or padding"); + } + + /// Decrypt a message using cbc mode + pub fn decrypt_cbc(k: &[u8], iv: &[u8], encrypted: &[u8], dest: &mut [u8]) -> Result<(), SymmetricCipherError> { + let mut encryptor = CbcDecryptor::new(AesSafe128Decryptor::new(k), PkcsPadding, iv.to_vec()); + try!(encryptor.decrypt(&mut RefReadBuffer::new(encrypted), &mut RefWriteBuffer::new(dest), true)); + Ok(()) + } + +} + diff --git a/ethstore/src/dir/disk.rs b/ethstore/src/dir/disk.rs new file mode 100644 index 000000000..f63577361 --- /dev/null +++ b/ethstore/src/dir/disk.rs @@ -0,0 +1,125 @@ +// 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 . + +use std::{fs, ffi, io}; +use std::path::{PathBuf, Path}; +use std::collections::HashMap; +use ethkey::Address; +use {libc, json, SafeAccount, Error}; +use super::KeyDirectory; + +#[cfg(not(windows))] +fn restrict_permissions_to_owner(file_path: &Path) -> Result<(), i32> { + let cstr = ffi::CString::new(file_path.to_str().unwrap()).unwrap(); + match unsafe { libc::chmod(cstr.as_ptr(), libc::S_IWUSR | libc::S_IRUSR) } { + 0 => Ok(()), + x => Err(x), + } +} + +#[cfg(windows)] +fn restrict_permissions_to_owner(file_path: &Path) -> Result<(), i32> { + Ok(()) +} + +pub struct DiskDirectory { + path: PathBuf, +} + +impl DiskDirectory { + pub fn create

(path: P) -> Result where P: AsRef { + try!(fs::create_dir_all(&path)); + Ok(Self::at(path)) + } + + pub fn at

(path: P) -> Self where P: AsRef { + DiskDirectory { + path: path.as_ref().to_path_buf(), + } + } + + /// all accounts found in keys directory + fn files(&self) -> Result, Error> { + // it's not done using one iterator cause + // there is an issue with rustc and it takes tooo much time to compile + let paths = try!(fs::read_dir(&self.path)) + .flat_map(Result::ok) + .filter(|entry| { + let metadata = entry.metadata(); + metadata.is_ok() && !metadata.unwrap().is_dir() + }) + .map(|entry| entry.path()) + .collect::>(); + + let files: Result, _> = paths.iter() + .map(fs::File::open) + .collect(); + + let files = try!(files); + + let accounts = files.into_iter() + .map(json::KeyFile::load) + .zip(paths.into_iter()) + .filter_map(|(file, path)| file.ok().map(|file| (path, SafeAccount::from(file)))) + .collect(); + + Ok(accounts) + } +} + +impl KeyDirectory for DiskDirectory { + fn load(&self) -> Result, Error> { + let accounts = try!(self.files()) + .into_iter() + .map(|(_, account)| account) + .collect(); + Ok(accounts) + } + + fn insert(&self, account: SafeAccount) -> Result<(), Error> { + // transform account into key file + let keyfile: json::KeyFile = account.into(); + + // build file path + let mut keyfile_path = self.path.clone(); + keyfile_path.push(format!("{}", keyfile.id)); + + // save the file + let mut file = try!(fs::File::create(&keyfile_path)); + try!(keyfile.write(&mut file).map_err(|e| Error::Custom(format!("{:?}", e)))); + + if let Err(_) = restrict_permissions_to_owner(&keyfile_path) { + fs::remove_file(&keyfile_path).expect("Expected to remove recently created file"); + return Err(Error::Io(io::Error::last_os_error())); + } + + Ok(()) + } + + fn remove(&self, address: &Address) -> Result<(), Error> { + // enumerate all entries in keystore + // and find entry with given address + let to_remove = try!(self.files()) + .into_iter() + .find(|&(_, ref account)| &account.address == address); + + // remove it + match to_remove { + None => Err(Error::InvalidAccount), + Some((path, _)) => fs::remove_file(path).map_err(From::from) + } + } +} diff --git a/ethstore/src/dir/geth.rs b/ethstore/src/dir/geth.rs new file mode 100644 index 000000000..29c9f2dc3 --- /dev/null +++ b/ethstore/src/dir/geth.rs @@ -0,0 +1,95 @@ +// 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 . + +use std::env; +use std::path::PathBuf; +use ethkey::Address; +use {SafeAccount, Error}; +use super::{KeyDirectory, DiskDirectory, DirectoryType}; + +#[cfg(target_os = "macos")] +fn geth_dir_path() -> PathBuf { + let mut home = env::home_dir().expect("Failed to get home dir"); + home.push("Library"); + home.push("Ethereum"); + home +} + +#[cfg(windows)] +/// Default path for ethereum installation on Windows +pub fn geth_dir_path() -> PathBuf { + let mut home = env::home_dir().expect("Failed to get home dir"); + home.push("AppData"); + home.push("Roaming"); + home.push("Ethereum"); + home +} + +#[cfg(not(any(target_os = "macos", windows)))] +/// Default path for ethereum installation on posix system which is not Mac OS +pub fn geth_dir_path() -> PathBuf { + let mut home = env::home_dir().expect("Failed to get home dir"); + home.push(".ethereum"); + home +} + +fn geth_keystore(t: DirectoryType) -> PathBuf { + let mut dir = geth_dir_path(); + match t { + DirectoryType::Testnet => { + dir.push("testnet"); + dir.push("keystore"); + }, + DirectoryType::Main => { + dir.push("keystore"); + } + } + dir +} + +pub struct GethDirectory { + dir: DiskDirectory, +} + +impl GethDirectory { + pub fn create(t: DirectoryType) -> Result { + let result = GethDirectory { + dir: try!(DiskDirectory::create(geth_keystore(t))), + }; + + Ok(result) + } + + pub fn open(t: DirectoryType) -> Self { + GethDirectory { + dir: DiskDirectory::at(geth_keystore(t)), + } + } +} + +impl KeyDirectory for GethDirectory { + fn load(&self) -> Result, Error> { + self.dir.load() + } + + fn insert(&self, account: SafeAccount) -> Result<(), Error> { + self.dir.insert(account) + } + + fn remove(&self, address: &Address) -> Result<(), Error> { + self.dir.remove(address) + } +} diff --git a/ethstore/src/dir/mod.rs b/ethstore/src/dir/mod.rs new file mode 100644 index 000000000..68280f596 --- /dev/null +++ b/ethstore/src/dir/mod.rs @@ -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 . + +use ethkey::Address; +use {SafeAccount, Error}; + +mod disk; +mod geth; +mod parity; + +pub enum DirectoryType { + Testnet, + Main, +} + +pub trait KeyDirectory: Send + Sync { + fn load(&self) -> Result, Error>; + fn insert(&self, account: SafeAccount) -> Result<(), Error>; + fn remove(&self, address: &Address) -> Result<(), Error>; +} + +pub use self::disk::DiskDirectory; +pub use self::geth::GethDirectory; +pub use self::parity::ParityDirectory; diff --git a/ethstore/src/dir/parity.rs b/ethstore/src/dir/parity.rs new file mode 100644 index 000000000..c1b812fe0 --- /dev/null +++ b/ethstore/src/dir/parity.rs @@ -0,0 +1,74 @@ +// 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 . + +use std::env; +use std::path::PathBuf; +use ethkey::Address; +use {SafeAccount, Error}; +use super::{KeyDirectory, DiskDirectory, DirectoryType}; + +fn parity_dir_path() -> PathBuf { + let mut home = env::home_dir().expect("Failed to get home dir"); + home.push(".parity"); + home +} + +fn parity_keystore(t: DirectoryType) -> PathBuf { + let mut dir = parity_dir_path(); + match t { + DirectoryType::Testnet => { + dir.push("testnet_keys"); + }, + DirectoryType::Main => { + dir.push("keys"); + } + } + dir +} + +pub struct ParityDirectory { + dir: DiskDirectory, +} + +impl ParityDirectory { + pub fn create(t: DirectoryType) -> Result { + let result = ParityDirectory { + dir: try!(DiskDirectory::create(parity_keystore(t))), + }; + + Ok(result) + } + + pub fn open(t: DirectoryType) -> Self { + ParityDirectory { + dir: DiskDirectory::at(parity_keystore(t)), + } + } +} + +impl KeyDirectory for ParityDirectory { + fn load(&self) -> Result, Error> { + self.dir.load() + } + + fn insert(&self, account: SafeAccount) -> Result<(), Error> { + self.dir.insert(account) + } + + fn remove(&self, address: &Address) -> Result<(), Error> { + self.dir.remove(address) + } +} diff --git a/ethstore/src/error.rs b/ethstore/src/error.rs new file mode 100644 index 000000000..8066fe10c --- /dev/null +++ b/ethstore/src/error.rs @@ -0,0 +1,58 @@ +// 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 . + +use std::fmt; +use std::io::Error as IoError; +use ethkey::Error as EthKeyError; + +#[derive(Debug)] +pub enum Error { + Io(IoError), + InvalidPassword, + InvalidSecret, + InvalidAccount, + CreationFailed, + EthKey(EthKeyError), + Custom(String), +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + let s = match *self { + Error::Io(ref err) => format!("{}", err), + Error::InvalidPassword => "Invalid password".into(), + Error::InvalidSecret => "Invalid secret".into(), + Error::InvalidAccount => "Invalid account".into(), + Error::CreationFailed => "Account creation failed".into(), + Error::EthKey(ref err) => format!("{}", err), + Error::Custom(ref s) => s.clone(), + }; + + write!(f, "{}", s) + } +} + +impl From for Error { + fn from(err: IoError) -> Self { + Error::Io(err) + } +} + +impl From for Error { + fn from(err: EthKeyError) -> Self { + Error::EthKey(err) + } +} diff --git a/ethstore/src/ethkey.rs b/ethstore/src/ethkey.rs new file mode 100644 index 000000000..9d8858b79 --- /dev/null +++ b/ethstore/src/ethkey.rs @@ -0,0 +1,41 @@ +// 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 . + +//! ethkey reexport to make documentation look pretty. +pub use _ethkey::*; +use json; + +impl Into for Address { + fn into(self) -> json::H160 { + let a: [u8; 20] = self.into(); + From::from(a) + } +} + +impl From for Address { + fn from(json: json::H160) -> Self { + let a: [u8; 20] = json.into(); + From::from(a) + } +} + +impl<'a> From<&'a json::H160> for Address { + fn from(json: &'a json::H160) -> Self { + let mut a = [0u8; 20]; + a.copy_from_slice(json); + From::from(a) + } +} diff --git a/ethstore/src/ethstore.rs b/ethstore/src/ethstore.rs new file mode 100644 index 000000000..9ef84ebc2 --- /dev/null +++ b/ethstore/src/ethstore.rs @@ -0,0 +1,108 @@ +// 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 . + +use std::collections::BTreeMap; +use std::sync::RwLock; +use ethkey::KeyPair; +use crypto::KEY_ITERATIONS; +use random::Random; +use ethkey::{Signature, Address, Message, Secret}; +use dir::KeyDirectory; +use account::SafeAccount; +use {Error, SecretStore}; + +pub struct EthStore { + dir: Box, + iterations: u32, + cache: RwLock>, +} + +impl EthStore { + pub fn open(directory: Box) -> Result { + Self::open_with_iterations(directory, KEY_ITERATIONS as u32) + } + + pub fn open_with_iterations(directory: Box, iterations: u32) -> Result { + let accounts = try!(directory.load()); + let cache = accounts.into_iter().map(|account| (account.address.clone(), account)).collect(); + let store = EthStore { + dir: directory, + iterations: iterations, + cache: RwLock::new(cache), + }; + Ok(store) + } + + fn save(&self, account: SafeAccount) -> Result<(), Error> { + // save to file + try!(self.dir.insert(account.clone())); + + // update cache + let mut cache = self.cache.write().unwrap(); + cache.insert(account.address.clone(), account); + Ok(()) + } +} + +impl SecretStore for EthStore { + fn insert_account(&self, secret: Secret, password: &str) -> Result { + let keypair = try!(KeyPair::from_secret(secret).map_err(|_| Error::CreationFailed)); + let id: [u8; 16] = Random::random(); + let account = SafeAccount::create(&keypair, id, password, self.iterations); + let address = account.address.clone(); + try!(self.save(account)); + Ok(address) + } + + fn accounts(&self) -> Vec

{ + self.cache.read().unwrap().keys().cloned().collect() + } + + fn change_password(&self, address: &Address, old_password: &str, new_password: &str) -> Result<(), Error> { + // change password + let account = { + let cache = self.cache.read().unwrap(); + let account = try!(cache.get(address).ok_or(Error::InvalidAccount)); + try!(account.change_password(old_password, new_password, self.iterations)) + }; + + // save to file + self.save(account) + } + + fn remove_account(&self, address: &Address, password: &str) -> Result<(), Error> { + let can_remove = { + let cache = self.cache.read().unwrap(); + let account = try!(cache.get(address).ok_or(Error::InvalidAccount)); + account.check_password(password) + }; + + if can_remove { + try!(self.dir.remove(address)); + let mut cache = self.cache.write().unwrap(); + cache.remove(address); + Ok(()) + } else { + Err(Error::InvalidPassword) + } + } + + fn sign(&self, account: &Address, password: &str, message: &Message) -> Result { + let cache = self.cache.read().unwrap(); + let account = try!(cache.get(account).ok_or(Error::InvalidAccount)); + account.sign(password, message) + } +} diff --git a/ethstore/src/import.rs b/ethstore/src/import.rs new file mode 100644 index 000000000..79785ae0f --- /dev/null +++ b/ethstore/src/import.rs @@ -0,0 +1,28 @@ +// 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 . + +use ethkey::Address; +use dir::KeyDirectory; +use Error; + +pub fn import_accounts(src: &KeyDirectory, dst: &KeyDirectory) -> Result, Error> { + let accounts = try!(src.load()); + accounts.into_iter().map(|a| { + let address = a.address.clone(); + try!(dst.insert(a)); + Ok(address) + }).collect() +} diff --git a/ethstore/src/json/cipher.rs b/ethstore/src/json/cipher.rs new file mode 100644 index 000000000..119024437 --- /dev/null +++ b/ethstore/src/json/cipher.rs @@ -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 . + +use serde::{Serialize, Serializer, Deserialize, Deserializer, Error as SerdeError}; +use serde::de::Visitor; +use super::{Error, H128}; + +#[derive(Debug, PartialEq)] +pub enum CipherSer { + Aes128Ctr, +} + +impl Serialize for CipherSer { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer { + match *self { + CipherSer::Aes128Ctr => serializer.serialize_str("aes-128-ctr"), + } + } +} + +impl Deserialize for CipherSer { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + deserializer.deserialize(CipherSerVisitor) + } +} + +struct CipherSerVisitor; + +impl Visitor for CipherSerVisitor { + type Value = CipherSer; + + fn visit_str(&mut self, value: &str) -> Result where E: SerdeError { + match value { + "aes-128-ctr" => Ok(CipherSer::Aes128Ctr), + _ => Err(SerdeError::custom(Error::UnsupportedCipher)) + } + } + + fn visit_string(&mut self, value: String) -> Result where E: SerdeError { + self.visit_str(value.as_ref()) + } +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct Aes128Ctr { + pub iv: H128, +} + +#[derive(Debug, PartialEq)] +pub enum CipherSerParams { + Aes128Ctr(Aes128Ctr), +} + +impl Serialize for CipherSerParams { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer { + match *self { + CipherSerParams::Aes128Ctr(ref params) => params.serialize(serializer), + } + } +} + +impl Deserialize for CipherSerParams { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + Aes128Ctr::deserialize(deserializer) + .map(CipherSerParams::Aes128Ctr) + .map_err(|_| Error::InvalidCipherParams) + .map_err(SerdeError::custom) + } +} + +#[derive(Debug, PartialEq)] +pub enum Cipher { + Aes128Ctr(Aes128Ctr), +} diff --git a/ethstore/src/json/crypto.rs b/ethstore/src/json/crypto.rs new file mode 100644 index 000000000..9ff8c1e44 --- /dev/null +++ b/ethstore/src/json/crypto.rs @@ -0,0 +1,200 @@ +// 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 . + +use serde::{Deserialize, Deserializer, Serialize, Serializer, Error}; +use serde::de::{Visitor, MapVisitor}; +use serde::ser; +use super::{Cipher, CipherSer, CipherSerParams, Kdf, KdfSer, KdfSerParams, H256}; + +#[derive(Debug, PartialEq)] +pub struct Crypto { + pub cipher: Cipher, + pub ciphertext: H256, + pub kdf: Kdf, + pub mac: H256, +} + +enum CryptoField { + Cipher, + CipherParams, + CipherText, + Kdf, + KdfParams, + Mac, +} + +impl Deserialize for CryptoField { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer + { + deserializer.deserialize(CryptoFieldVisitor) + } +} + +struct CryptoFieldVisitor; + +impl Visitor for CryptoFieldVisitor { + type Value = CryptoField; + + fn visit_str(&mut self, value: &str) -> Result + where E: Error + { + match value { + "cipher" => Ok(CryptoField::Cipher), + "cipherparams" => Ok(CryptoField::CipherParams), + "ciphertext" => Ok(CryptoField::CipherText), + "kdf" => Ok(CryptoField::Kdf), + "kdfparams" => Ok(CryptoField::KdfParams), + "mac" => Ok(CryptoField::Mac), + _ => Err(Error::custom(format!("Unknown field: '{}'", value))), + } + } +} + +impl Deserialize for Crypto { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer + { + static FIELDS: &'static [&'static str] = &["id", "version", "crypto", "Crypto", "address"]; + deserializer.deserialize_struct("Crypto", FIELDS, CryptoVisitor) + } +} + +struct CryptoVisitor; + +impl Visitor for CryptoVisitor { + type Value = Crypto; + + fn visit_map(&mut self, mut visitor: V) -> Result + where V: MapVisitor + { + let mut cipher = None; + let mut cipherparams = None; + let mut ciphertext = None; + let mut kdf = None; + let mut kdfparams = None; + let mut mac = None; + + loop { + match try!(visitor.visit_key()) { + Some(CryptoField::Cipher) => { cipher = Some(try!(visitor.visit_value())); } + Some(CryptoField::CipherParams) => { cipherparams = Some(try!(visitor.visit_value())); } + Some(CryptoField::CipherText) => { ciphertext = Some(try!(visitor.visit_value())); } + Some(CryptoField::Kdf) => { kdf = Some(try!(visitor.visit_value())); } + Some(CryptoField::KdfParams) => { kdfparams = Some(try!(visitor.visit_value())); } + Some(CryptoField::Mac) => { mac = Some(try!(visitor.visit_value())); } + None => { break; } + } + } + + let cipher = match (cipher, cipherparams) { + (Some(CipherSer::Aes128Ctr), Some(CipherSerParams::Aes128Ctr(params))) => Cipher::Aes128Ctr(params), + (None, _) => return Err(Error::missing_field("cipher")), + (Some(_), None) => return Err(Error::missing_field("cipherparams")), + }; + + let ciphertext = match ciphertext { + Some(ciphertext) => ciphertext, + None => try!(visitor.missing_field("ciphertext")), + }; + + let kdf = match (kdf, kdfparams) { + (Some(KdfSer::Pbkdf2), Some(KdfSerParams::Pbkdf2(params))) => Kdf::Pbkdf2(params), + (Some(KdfSer::Scrypt), Some(KdfSerParams::Scrypt(params))) => Kdf::Scrypt(params), + (Some(_), Some(_)) => return Err(Error::custom("Invalid cipherparams")), + (None, _) => return Err(Error::missing_field("kdf")), + (Some(_), None) => return Err(Error::missing_field("kdfparams")), + }; + + let mac = match mac { + Some(mac) => mac, + None => try!(visitor.missing_field("mac")), + }; + + try!(visitor.end()); + + let result = Crypto { + cipher: cipher, + ciphertext: ciphertext, + kdf: kdf, + mac: mac, + }; + + Ok(result) + } +} + +impl Serialize for Crypto { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer + { + serializer.serialize_struct("Crypto", CryptoMapVisitor { + value: self, + state: 0, + }) + } +} + +struct CryptoMapVisitor<'a> { + value: &'a Crypto, + state: u8, +} + +impl<'a> ser::MapVisitor for CryptoMapVisitor<'a> { + fn visit(&mut self, serializer: &mut S) -> Result, S::Error> + where S: Serializer + { + match self.state { + 0 => { + self.state += 1; + match self.value.cipher { + Cipher::Aes128Ctr(_) => Ok(Some(try!(serializer.serialize_struct_elt("cipher", &CipherSer::Aes128Ctr)))), + } + }, + 1 => { + self.state += 1; + match self.value.cipher { + Cipher::Aes128Ctr(ref params) => Ok(Some(try!(serializer.serialize_struct_elt("cipherparams", params)))), + } + }, + 2 => { + self.state += 1; + Ok(Some(try!(serializer.serialize_struct_elt("ciphertext", &self.value.ciphertext)))) + }, + 3 => { + self.state += 1; + match self.value.kdf { + Kdf::Pbkdf2(_) => Ok(Some(try!(serializer.serialize_struct_elt("kdf", &KdfSer::Pbkdf2)))), + Kdf::Scrypt(_) => Ok(Some(try!(serializer.serialize_struct_elt("kdf", &KdfSer::Scrypt)))), + } + }, + 4 => { + self.state += 1; + match self.value.kdf { + Kdf::Pbkdf2(ref params) => Ok(Some(try!(serializer.serialize_struct_elt("kdfparams", params)))), + Kdf::Scrypt(ref params) => Ok(Some(try!(serializer.serialize_struct_elt("kdfparams", params)))), + } + }, + 5 => { + self.state += 1; + Ok(Some(try!(serializer.serialize_struct_elt("mac", &self.value.mac)))) + }, + _ => { + Ok(None) + } + } + } +} diff --git a/ethstore/src/json/error.rs b/ethstore/src/json/error.rs new file mode 100644 index 000000000..5e077cfad --- /dev/null +++ b/ethstore/src/json/error.rs @@ -0,0 +1,50 @@ +// 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 . + +use std::fmt; + +#[derive(Debug, PartialEq)] +pub enum Error { + UnsupportedCipher, + InvalidCipherParams, + UnsupportedKdf, + InvalidUUID, + UnsupportedVersion, + InvalidCiphertext, + InvalidH256, + InvalidPrf, +} + +impl fmt::Display for Error { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + match *self { + Error::InvalidUUID => write!(f, "Invalid UUID"), + Error::UnsupportedVersion => write!(f, "Unsupported version"), + Error::UnsupportedKdf => write!(f, "Unsupported kdf"), + Error::InvalidCiphertext => write!(f, "Invalid ciphertext"), + Error::UnsupportedCipher => write!(f, "Unsupported cipher"), + Error::InvalidCipherParams => write!(f, "Invalid cipher params"), + Error::InvalidH256 => write!(f, "Invalid hash"), + Error::InvalidPrf => write!(f, "Invalid prf"), + } + } +} + +impl Into for Error { + fn into(self) -> String { + format!("{}", self) + } +} diff --git a/ethstore/src/json/hash.rs b/ethstore/src/json/hash.rs new file mode 100644 index 000000000..2edc7b80b --- /dev/null +++ b/ethstore/src/json/hash.rs @@ -0,0 +1,112 @@ +// 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 . + +use std::fmt; +use std::ops; +use std::str::FromStr; +use rustc_serialize::hex::{FromHex, ToHex}; +use serde::{Serialize, Serializer, Deserialize, Deserializer, Error as SerdeError}; +use serde::de::Visitor; +use super::Error; + +macro_rules! impl_hash { + ($name: ident, $size: expr) => { + pub struct $name([u8; $size]); + + impl fmt::Debug for $name { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + let self_ref: &[u8] = &self.0; + write!(f, "{:?}", self_ref) + } + } + + impl PartialEq for $name { + fn eq(&self, other: &Self) -> bool { + let self_ref: &[u8] = &self.0; + let other_ref: &[u8] = &other.0; + self_ref == other_ref + } + } + + impl ops::Deref for $name { + type Target = [u8]; + + fn deref(&self) -> &Self::Target { + &self.0 + } + } + + impl Serialize for $name { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer { + serializer.serialize_str(&self.0.to_hex()) + } + } + + impl Deserialize for $name { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + struct HashVisitor; + + impl Visitor for HashVisitor { + type Value = $name; + + fn visit_str(&mut self, value: &str) -> Result where E: SerdeError { + FromStr::from_str(value).map_err(SerdeError::custom) + } + + fn visit_string(&mut self, value: String) -> Result where E: SerdeError { + self.visit_str(value.as_ref()) + } + } + + deserializer.deserialize(HashVisitor) + } + } + + impl FromStr for $name { + type Err = Error; + + fn from_str(value: &str) -> Result { + match value.from_hex() { + Ok(ref hex) if hex.len() == $size => { + let mut hash = [0u8; $size]; + hash.clone_from_slice(hex); + Ok($name(hash)) + } + _ => Err(Error::InvalidH256), + } + } + } + + impl From<[u8; $size]> for $name { + fn from(bytes: [u8; $size]) -> Self { + $name(bytes) + } + } + + impl Into<[u8; $size]> for $name { + fn into(self) -> [u8; $size] { + self.0 + } + } + } +} + +impl_hash!(H128, 16); +impl_hash!(H160, 20); +impl_hash!(H256, 32); +impl_hash!(H768, 96); diff --git a/ethstore/src/json/id.rs b/ethstore/src/json/id.rs new file mode 100644 index 000000000..2e896458c --- /dev/null +++ b/ethstore/src/json/id.rs @@ -0,0 +1,145 @@ +// 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 . + +//! Universaly unique identifier. +use std::str::FromStr; +use std::fmt; +use rustc_serialize::hex::{ToHex, FromHex}; +use serde::{Deserialize, Serialize, Deserializer, Serializer, Error as SerdeError}; +use serde::de::Visitor; +use super::Error; + +/// Universaly unique identifier. +#[derive(Debug, PartialEq)] +pub struct UUID([u8; 16]); + +impl From<[u8; 16]> for UUID { + fn from(uuid: [u8; 16]) -> Self { + UUID(uuid) + } +} + +impl<'a> Into for &'a UUID { + fn into(self) -> String { + let d1 = &self.0[0..4]; + let d2 = &self.0[4..6]; + let d3 = &self.0[6..8]; + let d4 = &self.0[8..10]; + let d5 = &self.0[10..16]; + [d1, d2, d3, d4, d5].into_iter().map(|d| d.to_hex()).collect::>().join("-") + } +} + +impl Into for UUID { + fn into(self) -> String { + Into::into(&self) + } +} + +impl Into<[u8; 16]> for UUID { + fn into(self) -> [u8; 16] { + self.0 + } +} + +impl fmt::Display for UUID { + fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { + let s: String = (self as &UUID).into(); + write!(f, "{}", s) + } +} + +fn copy_into(from: &str, into: &mut [u8]) -> Result<(), Error> { + let from = try!(from.from_hex().map_err(|_| Error::InvalidUUID)); + + if from.len() != into.len() { + return Err(Error::InvalidUUID); + } + + into.copy_from_slice(&from); + Ok(()) +} + +impl FromStr for UUID { + type Err = Error; + + fn from_str(s: &str) -> Result { + let parts: Vec<&str> = s.split("-").collect(); + + if parts.len() != 5 { + return Err(Error::InvalidUUID); + } + + let mut uuid = [0u8; 16]; + + try!(copy_into(parts[0], &mut uuid[0..4])); + try!(copy_into(parts[1], &mut uuid[4..6])); + try!(copy_into(parts[2], &mut uuid[6..8])); + try!(copy_into(parts[3], &mut uuid[8..10])); + try!(copy_into(parts[4], &mut uuid[10..16])); + + Ok(UUID(uuid)) + } +} + +impl Serialize for UUID { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer { + let s: String = self.into(); + serializer.serialize_str(&s) + } +} + +impl Deserialize for UUID { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + deserializer.deserialize(UUIDVisitor) + } +} + +struct UUIDVisitor; + +impl Visitor for UUIDVisitor { + type Value = UUID; + + fn visit_str(&mut self, value: &str) -> Result where E: SerdeError { + UUID::from_str(value).map_err(SerdeError::custom) + } + + fn visit_string(&mut self, value: String) -> Result where E: SerdeError { + self.visit_str(value.as_ref()) + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use super::UUID; + + #[test] + fn uuid_from_str() { + let uuid = UUID::from_str("3198bc9c-6672-5ab3-d995-4942343ae5b6").unwrap(); + assert_eq!(uuid, UUID::from([0x31, 0x98, 0xbc, 0x9c, 0x66, 0x72, 0x5a, 0xb3, 0xd9, 0x95, 0x49, 0x42, 0x34, 0x3a, 0xe5, 0xb6])); + } + + #[test] + fn uuid_from_and_to_str() { + let from = "3198bc9c-6672-5ab3-d995-4942343ae5b6"; + let uuid = UUID::from_str(from).unwrap(); + let to: String = uuid.into(); + assert_eq!(from, &to); + } +} diff --git a/ethstore/src/json/kdf.rs b/ethstore/src/json/kdf.rs new file mode 100644 index 000000000..676df1f95 --- /dev/null +++ b/ethstore/src/json/kdf.rs @@ -0,0 +1,149 @@ +// 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 . + +use serde::{Serialize, Serializer, Deserialize, Deserializer, Error as SerdeError}; +use serde::de::Visitor; +use serde_json::{Value, value}; +use super::{Error, H256}; + +#[derive(Debug, PartialEq)] +pub enum KdfSer { + Pbkdf2, + Scrypt, +} + +impl Serialize for KdfSer { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer { + match *self { + KdfSer::Pbkdf2 => serializer.serialize_str("pbkdf2"), + KdfSer::Scrypt => serializer.serialize_str("scrypt"), + } + } +} + +impl Deserialize for KdfSer { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + deserializer.deserialize(KdfSerVisitor) + } +} + +struct KdfSerVisitor; + +impl Visitor for KdfSerVisitor { + type Value = KdfSer; + + fn visit_str(&mut self, value: &str) -> Result where E: SerdeError { + match value { + "pbkdf2" => Ok(KdfSer::Pbkdf2), + "scrypt" => Ok(KdfSer::Scrypt), + _ => Err(SerdeError::custom(Error::UnsupportedKdf)) + } + } + + fn visit_string(&mut self, value: String) -> Result where E: SerdeError { + self.visit_str(value.as_ref()) + } +} + +#[derive(Debug, PartialEq)] +pub enum Prf { + HmacSha256, +} + +impl Serialize for Prf { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer { + match *self { + Prf::HmacSha256 => serializer.serialize_str("hmac-sha256"), + } + } +} + +impl Deserialize for Prf { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + deserializer.deserialize(PrfVisitor) + } +} + +struct PrfVisitor; + +impl Visitor for PrfVisitor { + type Value = Prf; + + fn visit_str(&mut self, value: &str) -> Result where E: SerdeError { + match value { + "hmac-sha256" => Ok(Prf::HmacSha256), + _ => Err(SerdeError::custom(Error::InvalidPrf)), + } + } + + fn visit_string(&mut self, value: String) -> Result where E: SerdeError { + self.visit_str(value.as_ref()) + } +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct Pbkdf2 { + pub c: u32, + pub dklen: u32, + pub prf: Prf, + pub salt: H256, +} + +#[derive(Debug, PartialEq, Serialize, Deserialize)] +pub struct Scrypt { + pub dklen: u32, + pub p: u32, + pub n: u32, + pub r: u32, + pub salt: H256, +} + +#[derive(Debug, PartialEq)] +pub enum KdfSerParams { + Pbkdf2(Pbkdf2), + Scrypt(Scrypt), +} + +impl Serialize for KdfSerParams { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer { + match *self { + KdfSerParams::Pbkdf2(ref params) => params.serialize(serializer), + KdfSerParams::Scrypt(ref params) => params.serialize(serializer), + } + } +} + +impl Deserialize for KdfSerParams { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + let v = try!(Value::deserialize(deserializer)); + + Deserialize::deserialize(&mut value::Deserializer::new(v.clone())).map(KdfSerParams::Pbkdf2) + .or_else(|_| Deserialize::deserialize(&mut value::Deserializer::new(v)).map(KdfSerParams::Scrypt)) + .map_err(|e| D::Error::custom(format!("{}", e))) + } +} + +#[derive(Debug, PartialEq)] +pub enum Kdf { + Pbkdf2(Pbkdf2), + Scrypt(Scrypt), +} diff --git a/ethstore/src/json/key_file.rs b/ethstore/src/json/key_file.rs new file mode 100644 index 000000000..5d87745ef --- /dev/null +++ b/ethstore/src/json/key_file.rs @@ -0,0 +1,271 @@ +// 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 . + +use std::io::{Read, Write}; +use serde::{Deserialize, Deserializer, Error}; +use serde::de::{Visitor, MapVisitor}; +use serde_json; +use super::{UUID, Version, Crypto, H160}; + +#[derive(Debug, PartialEq, Serialize)] +pub struct KeyFile { + pub id: UUID, + pub version: Version, + pub crypto: Crypto, + pub address: H160, +} + +enum KeyFileField { + ID, + Version, + Crypto, + Address, +} + +impl Deserialize for KeyFileField { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer + { + deserializer.deserialize(KeyFileFieldVisitor) + } +} + +struct KeyFileFieldVisitor; + +impl Visitor for KeyFileFieldVisitor { + type Value = KeyFileField; + + fn visit_str(&mut self, value: &str) -> Result + where E: Error + { + match value { + "id" => Ok(KeyFileField::ID), + "version" => Ok(KeyFileField::Version), + "crypto" => Ok(KeyFileField::Crypto), + "Crypto" => Ok(KeyFileField::Crypto), + "address" => Ok(KeyFileField::Address), + _ => Err(Error::custom(format!("Unknown field: '{}'", value))), + } + } +} + +impl Deserialize for KeyFile { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer + { + static FIELDS: &'static [&'static str] = &["id", "version", "crypto", "Crypto", "address"]; + deserializer.deserialize_struct("KeyFile", FIELDS, KeyFileVisitor) + } +} + +struct KeyFileVisitor; + +impl Visitor for KeyFileVisitor { + type Value = KeyFile; + + fn visit_map(&mut self, mut visitor: V) -> Result + where V: MapVisitor + { + let mut id = None; + let mut version = None; + let mut crypto = None; + let mut address = None; + + loop { + match try!(visitor.visit_key()) { + Some(KeyFileField::ID) => { id = Some(try!(visitor.visit_value())); } + Some(KeyFileField::Version) => { version = Some(try!(visitor.visit_value())); } + Some(KeyFileField::Crypto) => { crypto = Some(try!(visitor.visit_value())); } + Some(KeyFileField::Address) => { address = Some(try!(visitor.visit_value())); } + None => { break; } + } + } + + let id = match id { + Some(id) => id, + None => try!(visitor.missing_field("id")), + }; + + let version = match version { + Some(version) => version, + None => try!(visitor.missing_field("version")), + }; + + let crypto = match crypto { + Some(crypto) => crypto, + None => try!(visitor.missing_field("crypto")), + }; + + let address = match address { + Some(address) => address, + None => try!(visitor.missing_field("address")), + }; + + try!(visitor.end()); + + let result = KeyFile { + id: id, + version: version, + crypto: crypto, + address: address, + }; + + Ok(result) + } +} + +impl KeyFile { + pub fn load(reader: R) -> Result where R: Read { + serde_json::from_reader(reader) + } + + pub fn write(&self, writer: &mut W) -> Result<(), serde_json::Error> where W: Write { + serde_json::to_writer(writer, self) + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use serde_json; + use json::{KeyFile, UUID, Version, Crypto, Cipher, Aes128Ctr, Kdf, Scrypt, H128, H160, H256}; + + #[test] + fn basic_keyfile() { + let json = r#" + { + "address": "6edddfc6349aff20bc6467ccf276c5b52487f7a8", + "crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc", + "cipherparams": { + "iv": "b5a7ec855ec9e2c405371356855fec83" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209" + }, + "mac": "46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f" + }, + "id": "8777d9f6-7860-4b9b-88b7-0b57ee6b3a73", + "version": 3 + }"#; + + let expected = KeyFile { + id: UUID::from_str("8777d9f6-7860-4b9b-88b7-0b57ee6b3a73").unwrap(), + version: Version::V3, + address: H160::from_str("6edddfc6349aff20bc6467ccf276c5b52487f7a8").unwrap(), + crypto: Crypto { + cipher: Cipher::Aes128Ctr(Aes128Ctr { + iv: H128::from_str("b5a7ec855ec9e2c405371356855fec83").unwrap(), + }), + ciphertext: H256::from_str("7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc").unwrap(), + kdf: Kdf::Scrypt(Scrypt { + n: 262144, + dklen: 32, + p: 1, + r: 8, + salt: H256::from_str("1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209").unwrap(), + }), + mac: H256::from_str("46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f").unwrap(), + }, + }; + + let keyfile: KeyFile = serde_json::from_str(json).unwrap(); + assert_eq!(keyfile, expected); + } + + #[test] + fn capital_crypto_keyfile() { + let json = r#" + { + "address": "6edddfc6349aff20bc6467ccf276c5b52487f7a8", + "Crypto": { + "cipher": "aes-128-ctr", + "ciphertext": "7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc", + "cipherparams": { + "iv": "b5a7ec855ec9e2c405371356855fec83" + }, + "kdf": "scrypt", + "kdfparams": { + "dklen": 32, + "n": 262144, + "p": 1, + "r": 8, + "salt": "1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209" + }, + "mac": "46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f" + }, + "id": "8777d9f6-7860-4b9b-88b7-0b57ee6b3a73", + "version": 3 + }"#; + + let expected = KeyFile { + id: UUID::from_str("8777d9f6-7860-4b9b-88b7-0b57ee6b3a73").unwrap(), + version: Version::V3, + address: H160::from_str("6edddfc6349aff20bc6467ccf276c5b52487f7a8").unwrap(), + crypto: Crypto { + cipher: Cipher::Aes128Ctr(Aes128Ctr { + iv: H128::from_str("b5a7ec855ec9e2c405371356855fec83").unwrap(), + }), + ciphertext: H256::from_str("7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc").unwrap(), + kdf: Kdf::Scrypt(Scrypt { + n: 262144, + dklen: 32, + p: 1, + r: 8, + salt: H256::from_str("1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209").unwrap(), + }), + mac: H256::from_str("46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f").unwrap(), + }, + }; + + let keyfile: KeyFile = serde_json::from_str(json).unwrap(); + assert_eq!(keyfile, expected); + } + + #[test] + fn to_and_from_json() { + let file = KeyFile { + id: UUID::from_str("8777d9f6-7860-4b9b-88b7-0b57ee6b3a73").unwrap(), + version: Version::V3, + address: H160::from_str("6edddfc6349aff20bc6467ccf276c5b52487f7a8").unwrap(), + crypto: Crypto { + cipher: Cipher::Aes128Ctr(Aes128Ctr { + iv: H128::from_str("b5a7ec855ec9e2c405371356855fec83").unwrap(), + }), + ciphertext: H256::from_str("7203da0676d141b138cd7f8e1a4365f59cc1aa6978dc5443f364ca943d7cb4bc").unwrap(), + kdf: Kdf::Scrypt(Scrypt { + n: 262144, + dklen: 32, + p: 1, + r: 8, + salt: H256::from_str("1e8642fdf1f87172492c1412fc62f8db75d796cdfa9c53c3f2b11e44a2a1b209").unwrap(), + }), + mac: H256::from_str("46325c5d4e8c991ad2683d525c7854da387138b6ca45068985aa4959fa2b8c8f").unwrap(), + }, + }; + + let serialized = serde_json::to_string(&file).unwrap(); + let deserialized = serde_json::from_str(&serialized).unwrap(); + + assert_eq!(file, deserialized); + } +} diff --git a/ethstore/src/json/mod.rs b/ethstore/src/json/mod.rs new file mode 100644 index 000000000..208d474df --- /dev/null +++ b/ethstore/src/json/mod.rs @@ -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 . + +//! Contract interface specification. + +#[cfg(feature = "serde_macros")] +include!("mod.rs.in"); + +#[cfg(not(feature = "serde_macros"))] +include!(concat!(env!("OUT_DIR"), "/mod.rs")); + diff --git a/ethstore/src/json/mod.rs.in b/ethstore/src/json/mod.rs.in new file mode 100644 index 000000000..7272d7e2e --- /dev/null +++ b/ethstore/src/json/mod.rs.in @@ -0,0 +1,20 @@ +mod cipher; +mod crypto; +mod error; +mod hash; +mod id; +mod kdf; +mod key_file; +mod presale; +mod version; + +pub use self::cipher::{Cipher, CipherSer, CipherSerParams, Aes128Ctr}; +pub use self::crypto::Crypto; +pub use self::error::Error; +pub use self::hash::{H128, H160, H256, H768}; +pub use self::id::UUID; +pub use self::kdf::{Kdf, KdfSer, Prf, Pbkdf2, Scrypt, KdfSerParams}; +pub use self::key_file::KeyFile; +pub use self::presale::PresaleWallet; +pub use self::version::Version; + diff --git a/ethstore/src/json/presale.rs b/ethstore/src/json/presale.rs new file mode 100644 index 000000000..cba50695f --- /dev/null +++ b/ethstore/src/json/presale.rs @@ -0,0 +1,42 @@ +use std::io::Read; +use serde_json; +use super::{H160, H768}; + +#[derive(Debug, PartialEq, Deserialize)] +pub struct PresaleWallet { + pub encseed: H768, + #[serde(rename = "ethaddr")] + pub address: H160, +} + +impl PresaleWallet { + pub fn load(reader: R) -> Result where R: Read { + serde_json::from_reader(reader) + } +} + +#[cfg(test)] +mod tests { + use std::str::FromStr; + use serde_json; + use json::{PresaleWallet, H160, H768}; + + #[test] + fn presale_wallet() { + let json = r#" + { + "encseed": "137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066", + "ethaddr": "ede84640d1a1d3e06902048e67aa7db8d52c2ce1", + "email": "123@gmail.com", + "btcaddr": "1JvqEc6WLhg6GnyrLBe2ztPAU28KRfuseH" + } "#; + + let expected = PresaleWallet { + encseed: H768::from_str("137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066").unwrap(), + address: H160::from_str("ede84640d1a1d3e06902048e67aa7db8d52c2ce1").unwrap(), + }; + + let wallet: PresaleWallet = serde_json::from_str(json).unwrap(); + assert_eq!(expected, wallet); + } +} diff --git a/ethstore/src/json/version.rs b/ethstore/src/json/version.rs new file mode 100644 index 000000000..f394f61c2 --- /dev/null +++ b/ethstore/src/json/version.rs @@ -0,0 +1,54 @@ +// 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 . + +use serde::{Serialize, Serializer, Deserialize, Deserializer, Error as SerdeError}; +use serde::de::Visitor; +use super::Error; + +#[derive(Debug, PartialEq)] +pub enum Version { + V3, +} + +impl Serialize for Version { + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer { + match *self { + Version::V3 => serializer.serialize_u64(3) + } + } +} + +impl Deserialize for Version { + fn deserialize(deserializer: &mut D) -> Result + where D: Deserializer { + deserializer.deserialize(VersionVisitor) + } +} + +struct VersionVisitor; + +impl Visitor for VersionVisitor { + type Value = Version; + + fn visit_u64(&mut self, value: u64) -> Result where E: SerdeError { + match value { + 3 => Ok(Version::V3), + _ => Err(SerdeError::custom(Error::UnsupportedVersion)) + } + } +} + diff --git a/ethstore/src/lib.rs b/ethstore/src/lib.rs new file mode 100644 index 000000000..96d860db4 --- /dev/null +++ b/ethstore/src/lib.rs @@ -0,0 +1,50 @@ +// 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 . + +#![cfg_attr(feature="nightly", feature(custom_derive, plugin))] +#![cfg_attr(feature="nightly", plugin(serde_macros))] + +extern crate libc; +extern crate rand; +extern crate serde; +extern crate serde_json; +extern crate rustc_serialize; +extern crate crypto as rcrypto; +extern crate tiny_keccak; +// reexport it nicely +extern crate ethkey as _ethkey; + +pub mod dir; +pub mod ethkey; + +mod account; +mod json; +mod crypto; + +mod error; +mod ethstore; +mod import; +mod presale; +mod random; +mod secret_store; + +pub use self::account::SafeAccount; +pub use self::error::Error; +pub use self::ethstore::EthStore; +pub use self::import::import_accounts; +pub use self::presale::PresaleWallet; +pub use self::secret_store::SecretStore; + diff --git a/ethstore/src/presale.rs b/ethstore/src/presale.rs new file mode 100644 index 000000000..09c86abea --- /dev/null +++ b/ethstore/src/presale.rs @@ -0,0 +1,79 @@ +use std::fs; +use std::path::Path; +use rcrypto::pbkdf2::pbkdf2; +use rcrypto::sha2::Sha256; +use rcrypto::hmac::Hmac; +use json; +use ethkey::{Address, Secret, KeyPair}; +use crypto::Keccak256; +use {crypto, Error}; + +pub struct PresaleWallet { + iv: [u8; 16], + ciphertext: [u8; 80], + address: Address, +} + +impl From for PresaleWallet { + fn from(wallet: json::PresaleWallet) -> Self { + let mut iv = [0u8; 16]; + iv.copy_from_slice(&wallet.encseed[..16]); + + let mut ciphertext = [0u8; 80]; + ciphertext.copy_from_slice(&wallet.encseed[16..]); + + PresaleWallet { + iv: iv, + ciphertext: ciphertext, + address: Address::from(wallet.address), + } + } +} + +impl PresaleWallet { + pub fn open

(path: P) -> Result where P: AsRef { + let file = try!(fs::File::open(path)); + let presale = json::PresaleWallet::load(file).unwrap(); + Ok(PresaleWallet::from(presale)) + } + + pub fn decrypt(&self, password: &str) -> Result { + let mut h_mac = Hmac::new(Sha256::new(), password.as_bytes()); + let mut derived_key = vec![0u8; 16]; + pbkdf2(&mut h_mac, password.as_bytes(), 2000, &mut derived_key); + + let mut key = [0u8; 64]; + try!(crypto::aes::decrypt_cbc(&derived_key, &self.iv, &self.ciphertext, &mut key).map_err(|_| Error::InvalidPassword)); + + let secret = Secret::from(key.keccak256()); + if let Ok(kp) = KeyPair::from_secret(secret) { + if kp.address() == self.address { + return Ok(kp) + } + } + + Err(Error::InvalidPassword) + } +} + +#[cfg(test)] +mod tests { + use super::PresaleWallet; + use json; + + #[test] + fn test() { + let json = r#" + { + "encseed": "137103c28caeebbcea5d7f95edb97a289ded151b72159137cb7b2671f394f54cff8c121589dcb373e267225547b3c71cbdb54f6e48ec85cd549f96cf0dedb3bc0a9ac6c79b9c426c5878ca2c9d06ff42a23cb648312fc32ba83649de0928e066", + "ethaddr": "ede84640d1a1d3e06902048e67aa7db8d52c2ce1", + "email": "123@gmail.com", + "btcaddr": "1JvqEc6WLhg6GnyrLBe2ztPAU28KRfuseH" + } "#; + + let wallet = json::PresaleWallet::load(json.as_bytes()).unwrap(); + let wallet = PresaleWallet::from(wallet); + assert!(wallet.decrypt("123").is_ok()); + assert!(wallet.decrypt("124").is_err()); + } +} diff --git a/ethstore/src/random.rs b/ethstore/src/random.rs new file mode 100644 index 000000000..e0a7f52c7 --- /dev/null +++ b/ethstore/src/random.rs @@ -0,0 +1,39 @@ +// 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 . + +use rand::{Rng, OsRng}; + +pub trait Random { + fn random() -> Self where Self: Sized; +} + +impl Random for [u8; 16] { + fn random() -> Self { + let mut result = [0u8; 16]; + let mut rng = OsRng::new().unwrap(); + rng.fill_bytes(&mut result); + result + } +} + +impl Random for [u8; 32] { + fn random() -> Self { + let mut result = [0u8; 32]; + let mut rng = OsRng::new().unwrap(); + rng.fill_bytes(&mut result); + result + } +} diff --git a/ethstore/src/secret_store.rs b/ethstore/src/secret_store.rs new file mode 100644 index 000000000..5dab50ba7 --- /dev/null +++ b/ethstore/src/secret_store.rs @@ -0,0 +1,31 @@ +// 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 . + +use ethkey::{Address, Message, Signature, Secret}; +use Error; + +pub trait SecretStore: Send + Sync { + fn insert_account(&self, secret: Secret, password: &str) -> Result; + + fn accounts(&self) -> Vec

; + + fn change_password(&self, account: &Address, old_password: &str, new_password: &str) -> Result<(), Error>; + + fn remove_account(&self, account: &Address, password: &str) -> Result<(), Error>; + + fn sign(&self, account: &Address, password: &str, message: &Message) -> Result; +} + diff --git a/ethstore/tests/api.rs b/ethstore/tests/api.rs new file mode 100644 index 000000000..3b6a9f784 --- /dev/null +++ b/ethstore/tests/api.rs @@ -0,0 +1,127 @@ +// 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 . + +extern crate rand; +extern crate ethstore; + +mod util; + +use std::str::FromStr; +use ethstore::{SecretStore, EthStore}; +use ethstore::ethkey::{Random, Generator, Secret, Address}; +use ethstore::dir::DiskDirectory; +use util::TransientDir; + +#[test] +fn secret_store_create() { + let dir = TransientDir::create().unwrap(); + let _ = EthStore::open(Box::new(dir)).unwrap(); +} + +#[test] +#[should_panic] +fn secret_store_open_not_existing() { + let dir = TransientDir::open(); + let _ = EthStore::open(Box::new(dir)).unwrap(); +} + +fn random_secret() -> Secret { + Random.generate().unwrap().secret().clone() +} + +#[test] +fn secret_store_create_account() { + let dir = TransientDir::create().unwrap(); + let store = EthStore::open(Box::new(dir)).unwrap(); + assert_eq!(store.accounts().len(), 0); + assert!(store.insert_account(random_secret(), "").is_ok()); + assert_eq!(store.accounts().len(), 1); + assert!(store.insert_account(random_secret(), "").is_ok()); + assert_eq!(store.accounts().len(), 2); +} + +#[test] +fn secret_store_sign() { + let dir = TransientDir::create().unwrap(); + let store = EthStore::open(Box::new(dir)).unwrap(); + assert!(store.insert_account(random_secret(), "").is_ok()); + let accounts = store.accounts(); + assert_eq!(accounts.len(), 1); + assert!(store.sign(&accounts[0], "", &Default::default()).is_ok()); + assert!(store.sign(&accounts[0], "1", &Default::default()).is_err()); +} + +#[test] +fn secret_store_change_password() { + let dir = TransientDir::create().unwrap(); + let store = EthStore::open(Box::new(dir)).unwrap(); + assert!(store.insert_account(random_secret(), "").is_ok()); + let accounts = store.accounts(); + assert_eq!(accounts.len(), 1); + assert!(store.sign(&accounts[0], "", &Default::default()).is_ok()); + assert!(store.change_password(&accounts[0], "", "1").is_ok()); + assert!(store.sign(&accounts[0], "", &Default::default()).is_err()); + assert!(store.sign(&accounts[0], "1", &Default::default()).is_ok()); +} + +#[test] +fn secret_store_remove_account() { + let dir = TransientDir::create().unwrap(); + let store = EthStore::open(Box::new(dir)).unwrap(); + assert!(store.insert_account(random_secret(), "").is_ok()); + let accounts = store.accounts(); + assert_eq!(accounts.len(), 1); + assert!(store.remove_account(&accounts[0], "").is_ok()); + assert_eq!(store.accounts().len(), 0); + assert!(store.remove_account(&accounts[0], "").is_err()); +} + +fn test_path() -> &'static str { + match ::std::fs::metadata("ethstore") { + Ok(_) => "ethstore/tests/res/geth_keystore", + Err(_) => "tests/res/geth_keystore", + } +} + +fn pat_path() -> &'static str { + match ::std::fs::metadata("ethstore") { + Ok(_) => "ethstore/tests/res/pat", + Err(_) => "tests/res/pat", + } +} + +#[test] +fn secret_store_laod_geth_files() { + let dir = DiskDirectory::at(test_path()); + let store = EthStore::open(Box::new(dir)).unwrap(); + assert_eq!(store.accounts(), vec![ + Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap(), + Address::from_str("5ba4dcf897e97c2bdf8315b9ef26c13c085988cf").unwrap(), + Address::from_str("63121b431a52f8043c16fcf0d1df9cb7b5f66649").unwrap(), + ]); +} + +#[test] +fn secret_store_load_pat_files() { + let dir = DiskDirectory::at(pat_path()); + let store = EthStore::open(Box::new(dir)).unwrap(); + assert_eq!(store.accounts(), vec![ + Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap(), + Address::from_str("5ba4dcf897e97c2bdf8315b9ef26c13c085988cf").unwrap(), + ]); +} + + diff --git a/ethstore/tests/cli.rs b/ethstore/tests/cli.rs new file mode 100644 index 000000000..d4ebdc448 --- /dev/null +++ b/ethstore/tests/cli.rs @@ -0,0 +1,16 @@ +// 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 . + diff --git a/util/res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9 b/ethstore/tests/res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9 similarity index 100% rename from util/res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9 rename to ethstore/tests/res/geth_keystore/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9 diff --git a/util/res/geth_keystore/UTC--2016-02-20T09-33-03.984382741Z--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf b/ethstore/tests/res/geth_keystore/UTC--2016-02-20T09-33-03.984382741Z--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf similarity index 100% rename from util/res/geth_keystore/UTC--2016-02-20T09-33-03.984382741Z--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf rename to ethstore/tests/res/geth_keystore/UTC--2016-02-20T09-33-03.984382741Z--5ba4dcf897e97c2bdf8315b9ef26c13c085988cf diff --git a/util/res/geth_keystore/UTC--2016-04-03T08-58-49.834202900Z--63121b431a52f8043c16fcf0d1df9cb7b5f66649 b/ethstore/tests/res/geth_keystore/UTC--2016-04-03T08-58-49.834202900Z--63121b431a52f8043c16fcf0d1df9cb7b5f66649 similarity index 91% rename from util/res/geth_keystore/UTC--2016-04-03T08-58-49.834202900Z--63121b431a52f8043c16fcf0d1df9cb7b5f66649 rename to ethstore/tests/res/geth_keystore/UTC--2016-04-03T08-58-49.834202900Z--63121b431a52f8043c16fcf0d1df9cb7b5f66649 index 08272d43b..a3253e29a 100644 --- a/util/res/geth_keystore/UTC--2016-04-03T08-58-49.834202900Z--63121b431a52f8043c16fcf0d1df9cb7b5f66649 +++ b/ethstore/tests/res/geth_keystore/UTC--2016-04-03T08-58-49.834202900Z--63121b431a52f8043c16fcf0d1df9cb7b5f66649 @@ -1 +1 @@ -{"address":"63121b431a52f8043c16fcf0d1df9cb7b5f66649","crypto":{"cipher":"aes-128-ctr","ciphertext":"1dd21926c644b9983916d646f3a4f2c7f9362f7e1c9fb1abcb42494dae06fa01","cipherparams":{"iv":"c52c6ee66d89a7aa8c6839f4b6ed29c8"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"96f17c17bbf48db2dc4da00b3e7decce8e21f44a5d7963dadeeff70e1d38ad75"},"mac":"f279f3444585c2817701225e2196c1176386ad549ebaec2bcc4f94f309727fe6"},"id":"15e49cd2-51fb-4316-ba46-c3cf8db4ae44","version":3} \ No newline at end of file +{"address":"63121b431a52f8043c16fcf0d1df9cb7b5f66649","crypto":{"cipher":"aes-128-ctr","ciphertext":"1dd21926c644b9983916d646f3a4f2c7f9362f7e1c9fb1abcb42494dae06fa01","cipherparams":{"iv":"c52c6ee66d89a7aa8c6839f4b6ed29c8"},"kdf":"scrypt","kdfparams":{"dklen":32,"n":262144,"p":1,"r":8,"salt":"96f17c17bbf48db2dc4da00b3e7decce8e21f44a5d7963dadeeff70e1d38ad75"},"mac":"f279f3444585c2817701225e2196c1176386ad549ebaec2bcc4f94f309727fe6"},"id":"15e49cd2-51fb-4316-ba46-c3cf8db4ae44","version":3} diff --git a/util/res/pat/p1.json b/ethstore/tests/res/pat/p1.json similarity index 100% rename from util/res/pat/p1.json rename to ethstore/tests/res/pat/p1.json diff --git a/util/res/pat/p2.json b/ethstore/tests/res/pat/p2.json similarity index 100% rename from util/res/pat/p2.json rename to ethstore/tests/res/pat/p2.json diff --git a/ethstore/tests/util/mod.rs b/ethstore/tests/util/mod.rs new file mode 100644 index 000000000..73c47ee61 --- /dev/null +++ b/ethstore/tests/util/mod.rs @@ -0,0 +1,19 @@ +// 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 . + +mod transient_dir; + +pub use self::transient_dir::TransientDir; diff --git a/ethstore/tests/util/transient_dir.rs b/ethstore/tests/util/transient_dir.rs new file mode 100644 index 000000000..f4998e124 --- /dev/null +++ b/ethstore/tests/util/transient_dir.rs @@ -0,0 +1,74 @@ +// 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 . + +use std::path::PathBuf; +use std::{env, fs}; +use rand::{Rng, OsRng}; +use ethstore::dir::{KeyDirectory, DiskDirectory}; +use ethstore::ethkey::Address; +use ethstore::{Error, SafeAccount}; + +pub fn random_dir() -> PathBuf { + let mut rng = OsRng::new().unwrap(); + let mut dir = env::temp_dir(); + dir.push(format!("{:x}-{:x}", rng.next_u64(), rng.next_u64())); + dir +} + +pub struct TransientDir { + dir: DiskDirectory, + path: PathBuf, +} + +impl TransientDir { + pub fn create() -> Result { + let path = random_dir(); + let result = TransientDir { + dir: try!(DiskDirectory::create(&path)), + path: path, + }; + + Ok(result) + } + + pub fn open() -> Self { + let path = random_dir(); + TransientDir { + dir: DiskDirectory::at(&path), + path: path, + } + } +} + +impl Drop for TransientDir { + fn drop(&mut self) { + fs::remove_dir_all(&self.path).expect("Expected to remove temp dir"); + } +} + +impl KeyDirectory for TransientDir { + fn load(&self) -> Result, Error> { + self.dir.load() + } + + fn insert(&self, account: SafeAccount) -> Result<(), Error> { + self.dir.insert(account) + } + + fn remove(&self, address: &Address) -> Result<(), Error> { + self.dir.remove(address) + } +} diff --git a/evmjit/Cargo.toml b/evmjit/Cargo.toml index 39725a0de..001656f1b 100644 --- a/evmjit/Cargo.toml +++ b/evmjit/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "evmjit" -version = "1.2.0" +version = "1.3.0" authors = ["debris "] [lib] diff --git a/hook.sh b/hook.sh index adb763f9d..9ce825f80 100755 --- a/hook.sh +++ b/hook.sh @@ -7,6 +7,6 @@ echo "set -e" >> $FILE echo "cargo build --features dev" >> $FILE # Build tests echo "cargo test --no-run --features dev \\" >> $FILE -echo " -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethcore-dapps -p ethcore-signer" >> $FILE +echo " -p ethkey -p ethstore -p ethash -p ethcore-util -p ethcore -p ethsync -p ethcore-rpc -p parity -p ethcore-dapps -p ethcore-signer" >> $FILE echo "" >> $FILE chmod +x $FILE diff --git a/install-parity.sh b/install-parity.sh index 7f165f450..eadf698db 100755 --- a/install-parity.sh +++ b/install-parity.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -PARITY_DEB_URL=https://github.com/ethcore/parity/releases/download/v1.1.0/parity_linux_1.1.0-0_amd64.deb +PARITY_DEB_URL=https://github.com/ethcore/parity/releases/download/v1.2.0/parity_linux_1.2.0-0_amd64.deb function run_installer() diff --git a/ipc/codegen/Cargo.toml b/ipc/codegen/Cargo.toml index b7111c4af..4d83b65e1 100644 --- a/ipc/codegen/Cargo.toml +++ b/ipc/codegen/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethcore-ipc-codegen" -version = "1.2.0" +version = "1.3.0" authors = ["Nikolay Volf"] license = "GPL-3.0" description = "Macros to auto-generate implementations for ipc call" diff --git a/ipc/nano/Cargo.toml b/ipc/nano/Cargo.toml index fc229d393..4096ed443 100644 --- a/ipc/nano/Cargo.toml +++ b/ipc/nano/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethcore-ipc-nano" -version = "1.2.0" +version = "1.3.0" authors = ["Nikolay Volf "] license = "GPL-3.0" diff --git a/ipc/rpc/Cargo.toml b/ipc/rpc/Cargo.toml index 0bc9b05ef..ab00523de 100644 --- a/ipc/rpc/Cargo.toml +++ b/ipc/rpc/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ethcore-ipc" -version = "1.2.0" +version = "1.3.0" authors = ["Nikolay Volf "] license = "GPL-3.0" diff --git a/json/Cargo.toml b/json/Cargo.toml index a2a560c43..e93f493e1 100644 --- a/json/Cargo.toml +++ b/json/Cargo.toml @@ -10,7 +10,7 @@ rustc-serialize = "0.3" serde = "0.7.0" serde_json = "0.7.0" serde_macros = { version = "0.7.0", optional = true } -clippy = { version = "0.0.76", optional = true} +clippy = { version = "0.0.77", optional = true} [build-dependencies] serde_codegen = { version = "0.7.0", optional = true } diff --git a/json/src/spec/engine.rs b/json/src/spec/engine.rs index e877e37a8..9659d8af7 100644 --- a/json/src/spec/engine.rs +++ b/json/src/spec/engine.rs @@ -53,7 +53,8 @@ mod tests { "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", - "frontierCompatibilityModeLimit" : "0x" + "frontierCompatibilityModeLimit" : "0x", + "daoRescueSoftFork": true } } }"#; diff --git a/json/src/spec/ethash.rs b/json/src/spec/ethash.rs index 254ffff9b..5cb7475f2 100644 --- a/json/src/spec/ethash.rs +++ b/json/src/spec/ethash.rs @@ -42,6 +42,9 @@ pub struct EthashParams { /// Homestead transition block number. #[serde(rename="frontierCompatibilityModeLimit")] pub frontier_compatibility_mode_limit: Uint, + /// DAO rescue soft-fork? + #[serde(rename="daoRescueSoftFork")] + pub dao_rescue_soft_fork: bool, } /// Ethash engine deserialization. @@ -65,8 +68,9 @@ mod tests { "difficultyBoundDivisor": "0x0800", "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", - "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", - "frontierCompatibilityModeLimit" : "0x42" + "registrar": "0xc6d9d2cd449a754c494264e1809c50e34d64562b", + "frontierCompatibilityModeLimit": "0x42", + "daoRescueSoftFork": true } }"#; diff --git a/json/src/spec/spec.rs b/json/src/spec/spec.rs index fbb206c40..08724ca56 100644 --- a/json/src/spec/spec.rs +++ b/json/src/spec/spec.rs @@ -63,7 +63,8 @@ mod tests { "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", - "frontierCompatibilityModeLimit" : "0x" + "frontierCompatibilityModeLimit" : "0x", + "daoRescueSoftFork": false } } }, diff --git a/nsis/installer.nsi b/nsis/installer.nsi new file mode 100644 index 000000000..c93234850 --- /dev/null +++ b/nsis/installer.nsi @@ -0,0 +1,135 @@ + +!define APPNAME "Parity" +!define COMPANYNAME "Ethcore" +!define DESCRIPTION "Fast, light, robust Ethereum implementation" +!define VERSIONMAJOR 1 +!define VERSIONMINOR 3 +!define VERSIONBUILD 0 + +!addplugindir .\ + +!define HELPURL "https://github.com/ethcore/parity/wiki" # "Support Information" link +!define UPDATEURL "https://github.com/ethcore/parity/releases" # "Product Updates" link +!define ABOUTURL "https://github.com/ethcore/parity" # "Publisher" link +!define INSTALLSIZE 26120 + +RequestExecutionLevel admin ;Require admin rights on NT6+ (When UAC is turned on) + +InstallDir "$PROGRAMFILES64\${COMPANYNAME}\${APPNAME}" + +LicenseData "..\LICENSE" +Name "${COMPANYNAME} ${APPNAME}" +Icon "logo.ico" +outFile "installer.exe" + +!include LogicLib.nsh + +page license +page directory +Page instfiles + +!macro VerifyUserIsAdmin +UserInfo::GetAccountType +pop $0 +${If} $0 != "admin" ;Require admin rights on NT4+ + messageBox mb_iconstop "Administrator rights required!" + setErrorLevel 740 ;ERROR_ELEVATION_REQUIRED + quit +${EndIf} +!macroend + +function .onInit + setShellVarContext all + !insertmacro VerifyUserIsAdmin +functionEnd + +section "install" + # Files for the install directory - to build the installer, these should be in the same directory as the install script (this file) + setOutPath $INSTDIR + # Files added here should be removed by the uninstaller (see section "uninstall") + file /oname=parity.exe ..\target\release\parity.exe + file "logo.ico" + file vc_redist.x64.exe + + ExecWait '"$INSTDIR\vc_redist.x64.exe" /passive /norestart' + # Add any other files for the install directory (license files, app data, etc) here + + # Uninstaller - See function un.onInit and section "uninstall" for configuration + writeUninstaller "$INSTDIR\uninstall.exe" + + # Start Menu + createDirectory "$SMPROGRAMS\${COMPANYNAME}" + createShortCut "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}.lnk" "$INSTDIR\parity.exe" "ui" "$INSTDIR\logo.ico" + + # Firewall remove rules if exists + SimpleFC::AdvRemoveRule "Parity incoming peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Parity outgoing peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Parity web queries (TCP:80)" + SimpleFC::AdvRemoveRule "Parity UDP discovery (UDP:30303)" + + # Firewall exception rules + SimpleFC::AdvAddRule "Parity incoming peers (TCP:30303)" "" 6 1 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" 30303 "" "" "" + SimpleFC::AdvAddRule "Parity outgoing peers (TCP:30303)" "" 6 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 30303 "" "" + SimpleFC::AdvAddRule "Parity web queries (TCP:80)" "" 6 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 80 "" "" + SimpleFC::AdvAddRule "Parity UDP discovery (UDP:30303)" "" 17 2 1 2147483647 1 "$INSTDIR\parity.exe" "" "" "Parity" "" 30303 "" "" + + # Registry information for add/remove programs + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayName" "${COMPANYNAME} - ${APPNAME} - ${DESCRIPTION}" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "UninstallString" "$\"$INSTDIR\uninstall.exe$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "QuietUninstallString" "$\"$INSTDIR\uninstall.exe$\" /S" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "InstallLocation" "$\"$INSTDIR$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayIcon" "$\"$INSTDIR\logo.ico$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "Publisher" "$\"${COMPANYNAME}$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "HelpLink" "$\"${HELPURL}$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLUpdateInfo" "$\"${UPDATEURL}$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "URLInfoAbout" "$\"${ABOUTURL}$\"" + WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "DisplayVersion" "$\"${VERSIONMAJOR}.${VERSIONMINOR}.${VERSIONBUILD}$\"" + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMajor" ${VERSIONMAJOR} + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "VersionMinor" ${VERSIONMINOR} + # There is no option for modifying or repairing the install + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoModify" 1 + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "NoRepair" 1 + # Set the INSTALLSIZE constant (!defined at the top of this script) so Add/Remove Programs can accurately report the size + WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" "EstimatedSize" ${INSTALLSIZE} +sectionEnd + +# Uninstaller + +function un.onInit + SetShellVarContext all + + #Verify the uninstaller - last chance to back out + MessageBox MB_OKCANCEL "Permanantly remove ${APPNAME}?" IDOK next + Abort + + next: + !insertmacro VerifyUserIsAdmin +functionEnd + +section "uninstall" + + # Remove Start Menu launcher + delete "$SMPROGRAMS\${COMPANYNAME}\${APPNAME}.lnk" + # Try to remove the Start Menu folder - this will only happen if it is empty + rmDir "$SMPROGRAMS\${COMPANYNAME}" + + # Remove files + delete $INSTDIR\parity.exe + delete $INSTDIR\logo.ico + + # Always delete uninstaller as the last action + delete $INSTDIR\uninstall.exe + + # Try to remove the install directory - this will only happen if it is empty + rmDir $INSTDIR + + # Firewall exception rules + SimpleFC::AdvRemoveRule "Parity incoming peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Parity outgoing peers (TCP:30303)" + SimpleFC::AdvRemoveRule "Parity web queries (TCP:80)" + SimpleFC::AdvRemoveRule "Parity UDP discovery (UDP:30303)" + + # Remove uninstaller information from the registry + DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${COMPANYNAME} ${APPNAME}" + +sectionEnd diff --git a/nsis/logo.ico b/nsis/logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..4fbaa4d39cff498e1cba9deda57b3fd031e98ae4 GIT binary patch literal 99678 zcmeI5cd%APmcZXs?N;qyTl>#e?aaC(h@glfiWooyK|rE_WJwYQC1)^@Gm>-8Dme!O z8MC0`2*w#BVxAc%&-9+(dGu$$`)>H|_acu=)#HA*Z|6RJ`sB{a`bE~iXZ_cIWy!x% zSr7eNR#q#1mCAm9O447Dv`UpOzL(9)>ha%MSv6~Bzh7G`E9*b2Wo3;XeewN2evx(S zV_8|($}3ftlD}W*|58Tk@&5bu|NPPvx4&!4Ty2^*Y-IZOe%K7?)7La>)Y#l`ZTYnN zdCQHJOsi(i%}v)|Z(84fziE7LeRIbxRrFc2+MSVgw7$QE=4soqmAU4sGUmFg%bK<= zTWT8hUir&k1=ewI?R(7i*Ia9O-hBNHrd+Ag=IUQxsdY4O(!^YK#s8V+P44q8Pd>(3 zwMuqh%gY?tb>Vl7s?|)r+OdJkSGJsK-nfZ=qc82-v`u}pZIt=HUuzzo z*Ob0W=01BK`Oa_ZWj^ZFsvWqNe5)wyOg`4TVcmKYURi z^#DiSe8u5CE6bR?{DEgm$zM(Rvv_8-;xb8a{uPI@CVeP=xISu4z}-Uz3^e0Lk5=4K z`hTw|(0v4c2hTq7=%Z%*n6bL=S1es-rcRn9c%hFO^Z4Ut!q~BTwt$bK`XA>zV_PtH zuIb&QhpBX31wCs9_a9(t3hpl}IA!{jsoEar5;%U*{P}ve#c3lf@8AIg3LJ3+%<~Nh7KH*!l#^P(JmpQ0X=_WH`$dFWBWv?t{W=@}>@0@qHSH4Am z4;wt#RF`wij)Qa6?>w^K(|t~vI7!bPoBy$qBTbb`l?-cgQ-$kw%$$#m`N?V1bI<|6 z2K}{V<33w8zu&ZJkxgSzwyB&KT|0Hw`YPX0G1XS(iZ^N+Ys9+Pc7T<~M~zCo+w^pv zoXhmz=4Fh`1@D}>_Uz=n)Wx~r_rpDV>OQgM*c*4svfsY&~IoQ;EC^ybNuKrsd)$HsMD`3YeG8D zb!*n7`VXzprDG@GGTwT!`#;s(dFyTF@sXp<=*J$DdT!SJ#Q0cKZyEbuPUx!&<;p2O zs#mL)>EEZ1nK*Ww(kkFA=rx-+=-KIk2h5gDo3svhjoY+nVY*#}y`ZwBv)1epn}@k- z-=>Y=uX$$nlQUE4_Ph7lR^Yv7*RDEF=u`V0m}B3U5xBHze$UAQCsl;jcfUb<-&3Qe z;%+xR=r{NjTCGxr3g#BsTa1Ax^}74ZTON9@W4i~;4bonA`RkQ#1P4qSH(vLRw~XKW z%>qB8h7C`Rfwn7LT)RR2`kQJ38{Trv%e2XpHNCX-mpt}N1YdV(+b&lbZyoMC=S#JV zIG=R-#CiaOGp1&rH*S8;Vw>Ncf6agKd~)+g{id9IhOjT-;V9Rnego6#f%d8K+^T29 zP<;mvfV*t{?%8G2(tS2-EbHma8~cm3rM$bIQzuPU7@=L42Llg`8vgS-rrWNY54?A6 znKG&Iu>XO_N^vnWF1u-!pl_uZ|i%BGo>1*!3Or*yCpP ziWTNcfeZTM;ziCb%X4MYu3Kh+;4$zDFaiI>xS8{wUAvjq($3@w6O<-nt>C9v2fG*C zdNTbD+^<@`!o2X@bGpARAIiQ4E;*0bYw*Y5&b@o~2#s)4jycP;ZMPhA0REXEIGuBq zbA>eUC1=#wC!R2k>(|$P>Xs{r-{6B@-Fv9apoa8;c_@f>k~%Lv-Ym|VIii3f`H7qY z5o%}oOUWrjmg@Z%XG}@nk`1%T`X=jJl3<|rT{T3`&_Z~t{FPf3)Eq$v!Y8g=zTE8D zwcC90`RC@N4?i@|9Xx2ZZ{2DJ_3J16$_>Se9)T}G7qjWDdWbnQ zXPP=S?>5hDd`fx5E*(3n{NTX8{bu60afbCNsJTq1UgTPPckj{uyE24|<;$DrpM5q( z_m6q}3Dc)n?^Iu*3DLEzS+z>@U01g7bsY`r)K%J@aiT+lFNS7@k7F%rRlh6MU-B@{ z>bKva@>BBOdecqHcffNlU$P`e-gM?JuX%uJ%lo@^AqSW;aiYp);roz{(QkNygZmHo z@&NEK=n36=3i9``L4#EW{_3l9$bwl5#$&&C zY}d}roi#i4ZqwNVt5>efm2SW1-Ars0mM>YFN@p#QuY2>^cjVr#{05l{XPEtNpPc8etlOq% z`h0rB#$2`p$g^H}?)e-#DEb~XZ^&YSMcbEIGiI0vJ9J3B+w^^V_Nwg8zGwQxF2a@X zgGbPLy!_HjIq(hoLU3zTJCt|zdC1z{J9kd?8Lo`=?mMfS4eQoL))&^^RYFfP$F#xU zh#^DG;TK*oBZm!B{DR!i&UcNfx%X^P-N;Vu+0A*@t9y5qS3;w*udPmX-t0L-C;8j| z1l8@PPY~S>@<8UFvk4uc?JxNr?)i|yDY{a|=a!B7jeQaOYR|4+Im*?nR?Vzgxyo$Y zvQ>Ep+I8VAs$Tn@Ir#d*1@rXAjVjx<>E7p_ox2Qc?M;t*XS~cew2@z4U}@HjC(XOR zc~@k}V|?@Ym9uHkE=LX>5_<8LKzvAEbTChC*buvZ__8Gn7o})y+pc|PpLw^co*`3R z1A0bi0`wKE_l+JMBXb1pJa^VCgZ@lh0rFp3Pt~>5f-p%f@Wx^LU ztXD7N{!>46`;vtVbJW3^iS3(fBi32;Ug$f5=EA14uh2!mv27TPPe!ZUS1=(M3-PjGm zUqGjf7JG+%Lgyl+XLYf#lPfP*z}K!+Ar$9k!*BYHRF*?oHTGT1JB{Lx3|#~*$$$3#|y zuO4<6`K6mFE^~xT82LW7j_4_l9zJZAEnZ?qKl+&Hkbk2#d56Sy09`EdoRi0oi;vVw zvAyV+l8qOav83A%>}{JgXdp7pIp*}KQ|8!_qoRYHs5(nxvY-5FZRmFzL{J5y|_KuyJy~h+tk0Oj>=V$ zZDX^BjMeJY+DHtS69VI|T^r-T_ZWQ;V`h%fVIwEBdU|7ss z(((Pn|B*Gu9+CavXS>6?qRYTG2U{%ivrk-|5_T46-g;Z-)V5h%p4bY!{@QD)b@uDm z%4N$`4v%gd7~zR-@SYkqR5!wy!HKSp!CMbDbXzxXPVF7<_o8^mUIn`q*WS_F5AYi} z!A-{|5}mHa1AN2p`uNdfIczxGGVG&+V#Cl`@Qj;Yl)ted0AHh9^y>%k3~bbPZ0CV@ z_5->-@PsV~yko11Kdw73_B+o;5{v7_6DJDPrr2#S>^HiiH(q}|P|wIXw{6~%D^?bG z&FXCKzVpr;wqWSYPaZ#^@t*wJ20s$BB|m+Z{n|+<4ZB4Ah=cMD=-b!q6up{zZh_aZ z<+5eiKi)l0tSrt%dv4gg_6aWh%{%Ypu(Pq>3hRko1#2JFN6x;p@4l-x1GZ1VG&*AM zUa`7Jn~x{!i;Yy!KIr~n7oi#V)S()!xW#!vWr&$`mz;s_ zcVOl9S6|CvU+#Wq&R%)>L|6FPTjd%t?2Q#qS#j18Lyd}ZyoZJOVcF>)?4F8dw) z0&R@VwoP-N*zUak>Z`(M*7p7G=FRJGVsya6+Ox}B-@dvxh4{B`Cw!EXCOzv(~z3B(HX%Y(hiiziR!nw#5&&czWtzv&w`_XUXyA008mtXsV%SKH9?$aB8>>Z@FScdh(2)p?)Mv9=XGl?6$-D!I-c&xBCI!8QRg7 z!Ow)aO5oeoLMP!fq4-z!AU1V2UtXWYI74OuJ@%@cwb;4>^DeDo+hD!GkKhQ_-lk{z z#5NNiW7m$IzJ7Mp3vS_T!0!lp2;VL2+>t$G+O92!90oW$CvZ)CDCpEE*h0qh%1bZ% z+LYRQ(|ytw{3W<8Y9E1Xh#iNV><@qVL*RLtZrkL;hk*T!pE_~%{Adtweb9OMQa~em zzr}rrZh&`A2cDU$>#w;+=!_}~ukZ(P+w;p$ylQ+h;o~`%z(0Ox5M}8D_#QeISzumm zDd!4p2R!31<&_!QzOoOA-$37xp<}Zq<8*zm?0mor#no$JlT2IQKEYdYu6WxaAF(OUynQBzEXi9w zukXk(!Lfezur9!;J3pM^i{>v-|0Xxxue?oT|G>|9=|AW?Z<;MbEE@bbh>v2^3gU^( zhw~r^7a`m5+RVexz{B62#=QZ+68b^n^SS+JZxf?6Xby>iL7W)3OhNpnf6$)9(GIE~ z+2%D@<>XNY_U$L<^3K3Awl4e{*)RBg+cciwT9+1fzrib>QWRIg`Ob zes!`|;3oK9`<;11ZjY~@P4hk}2W)xcVA7uTP4$)m9`Gl{*Tnm+Am4$v?OV46w#hl< z%6RDuYX}V=gbRsbyK&w69Cbp|f$xIg9=Zsg8@i_;$Lp;dTz5q1{4jh2|K{>5)Pe6f zf8P3_EuojZ{i!Q=mUCmZ+(UF4&4E75ERz~++Sb(R_Leg54sKL6PK1@ZP%|^ zn=4i_XDYbUmi0d2d7$%xV8ffgAl``=Gjn>*IPPvc$TGo)ZW=Oi{KBj(^Z_}ukR!P3 z41Mj5HRaa983{dxkDi-e*uUXVUxVHZkv$>f=*}L#4rv!+kj{0!1e{1D7vd3#Qy7{ZrxLJ2fp;~7h8rW^&FP56UW(2FY4dG zEAnYSTnK)Gb|JYgvSHa4;^S0ac9AsVZ5m<5eyN+M>J9~oP>;d=; zxJ{?%lTh7*FIHx_TpHnL+7Ms&0KQ= zeuK`0CZ<00snE!N?G~prU>`p92|1rQ*H521t?|UTg8;sfwO4-TqW*&4&i zG4r6U@LztQb!%U|Qk=#d)EDLgy-Z(;O+YL@>|2p*U>8EHPh|MWDTx`%Tv=F$9te^# z2DNo5q!aTI-~OeG7OUMeHZJhR;B|P$AiRGmj4f^-xu=3N0y$>fvPu5pqr!3jPW_}>wCdc=?+8uy92B8jKN6WJetKfl5-SEj%`d+A!u(10Hg_z~pF3CMoDsu`_yYKEau4imxpNv{ z%&Bs}{f|HXsD8`%Hxl=WxM&L`<|jVc-^;zP=fC_?>)jeOv|RtQt?$-?@qFx ziNX5D>u)H{;FhBv=t1I9;>*gNH{6x}mp}hm&WS&2Ki)fcPUBnAKlfgEx1Qv8e4c`} zfd(U%1oYY8{`NP;$G?;Pw_nzvSN9$g7dL0DLce*2-y^>DpM}mNex)0ehWz*^6L$rE zfIAS#|ZM{LxYj+O@%^mv=dW^M#$A|ADHY;~GaK|8c zJ!uryv*vD{{00|&`st?{KaI1(`#pKj2@}jQ@dE$;_rIH= z0|#b2Ukm2WQ`%vJ(2wkA;;V5Uz`qmEyt&-T%N-oVuR~_QJL!BUP96E#zw6{2fNxkJ zGDLf}$5}J#LH__>xO~adv~XFR`b$z?)}H%PKNG%*Sc%;K6nA{A5qKY&J~E=9@~jK% z&b_AfMc&K1UtW7p1@dIzF_V~H;4t_?WXQzD%mj}7`c~4?xbJ8G-hJk~Z@}}*T#H<7l1knbpRoj*=l^@_&es>d*1K?n zV*Q7eFX`W)@g|HNr*agj0b(vA4R^1oI0p)QT3F>@2p3Qi*gt4J3wb2cbw3B!v+mD zUkaYyyL(S)EM4G)`-$zHXWYMmZntts%yIZjWV+`?jxa>d0k8Zxo&G}qalgX5a+h1P zMvaqm;37YOUWa{)jCYLO_mIil!mpwCCEhf2T+m)--ytV}*0<*{dC>uK2aR8xYt|Op z1briI5Wg0kL|lG=GiTfrqs_N+zHOF!w7hpHqys}GEe~@~e0Ao8yFl-B?#xbitlXur zNq7e62F0zOJ6ha&ID3H=?>ZyLVg2>aL0N0JjQtH zIwx{L_-b%IG8*nWjlHMDmJ@u8-i|vn!tRaW3})@Q^UK=~@5CwRd(a(7tTFN*&KJ&c z?hQ?M-Q9f11+hOuXKZnh`~7nIJ!RrVmGcoFKZphon-B0d`yQQ5GvVQb@-oldQw6PG zMqtJ-pQQz{6Ad~)D2IK}`|rJHelIpeHnzQAeL-m|SCIQ=|19aG^tn49dbdjrZhi_PU&TZrZLHC+@%idMBszC-E zg^#cqXAdu4urMQ<6&pj!a~Fo+y@%d@m85s>zkpBYZu3ld;r4CXs&18g1~>zP=7w_} z8@^_Z8>jAD3Ce5Jfh}x^t$m*d3yy;$BRfUecfF zPFXk3&rEP1djFHhPw4u0Zr>qv-q=^l+lSn@<~QHS2)Ms2iWhyTTQ`w8e5pEKbUl7` zg{8rBu>Qyv8CO`|lJJfB#FmG(pF3+-?D1Y#wyfG&qLZ07XHH~!^nK84nao|?TDA1t z2rCQjLe>cX!Tt1M_nZ0ELwS5t&{J~9Z*jT%%&)Kck%ry;dxA5Oqgb1sIQ8P!fi4Ey zkf`$5g>-1!E~E2>K5_nckaH&Nu150J5PdR!0>~c2Y*m8BiEbLX;JLGBL+{-TDu1b@ zV>^YM5Bo~&cEflqzcC@N$EFIqO715OBGq-Jc6lBx(t~U3Z{SDvPrDI2x zVc=urcQ=^L>-U7-7(8Hr;zaIa#~0Nv-=&_`xA()!t06msAB!^{_$B_}L7um?Abl*o-Y+xG=Wv8aU$~u^%tmyT#obamQ8I`O)cc zKQ4B-?58;Gvj)S2zsE-t+kECKtUNM0d~&b{3(J@8H~4#C>E;`52(1s8h9~@o*skDb z#J*0q4f5f8jIH|_(J#372*;_TIOavqF|o>02{gmbZQE2ogl;hG%x9d~b3rF~^*ec;1Ng`$A`_}6cEC|*3OYXQzR~l< z)$w76fS)1fKnsyq=C$8NT^@gF^m@?7_)tf!pSQo`MvoEwz)xZm__W&fdcV8x*yVE0 zz!$`A$F0ZjH*0>!Ew_lxki-KJSn$hZ)1XzhY}%}JE--7;(|vMwe04s1zvTBg((OZj z<%6z;H-@%hFUP4DxeYdR==7s}>6oXQA_oNTN6BsD^uf(by;hDKMV}$pIw$-bdcJmo z|J-__exrZf{LC{7Kgda=@)y_d70Q(}_-R7(K|{ysC-gh_Bct16KSY&9k4ziL?V|GL zFl+5|apfLFmCuY~bUxRZw}CFI}qsFUYr|_KWQULflnyoje=EV9G`vqnZ~B+(6()8TW-5W{TqInxI4gZ zQ?YaO>koVs`MOBFgq_>Bn}7V{A1eQ1-%lJjUTtjg1^BDf0S*X~zriCxCq(J${Q8iW zG+++>P!L{Ye9s=p)^9)Y=%ecYH&)_CoRatw=sp!ff zd{^NonOE=k!WwJ3?O@}KEfzjJRxi)|zz4%SVKaB+&|!_00dC(RFw$3iVz9yXYok^3 z=6a5tIDR};pUnrIjBEkFE}K@E&$0r`(Dq)w247+H6!?$gSLW9z&cr^wdz;;2Q_eiF zUydF=BJ(p+d01C&0E`o#4BQx0pI;k=orc_XrNl}D?#GQDt*{DD-cfXL#N2vaY^9KE z5I1R&$nuGm69v!Ucl4s*OzeHI8)970UeMtd#tM6^wmoc$SQ9%AWQEA?h%bg8i_I7G zytYgk(H(UX-SI;85&iLpAB9$YUCUbCC30+H4gpWg7B4oHDpZK9H>kaWN@tJvc(9B4 zKwx=`*tR2w>(Ql)`q7^gJ{WshY&MYpwrJWkQh($26P^Ir|BWO6)p-}1FX;Sr%NOKt z&O2_g5m>=~iskzWuK3EBmFY0kWQwQ8mIueW^IJ9}&Bz(E?fle)3HDhysftWWkE za9>$yLHJMjf%R+Gsy#FGN)SzF%lbWm1J)W^2!A8!#E)bi@rm9bb>n+LtUAsZzw$+q zcD1a}@WDfr&q25U-M8PVo|gV&4{@8=)w?uMCVeEP1Mm+W1b;w$hbaCjlXfyG!&$_7 z&@XI}k#*)(hY#$)KVl=gYsXHNp%Pz=`Gv0{ra@lkG?TIVl|dH5z9&`!{OwXXqgpm= zrnc5mG7`V~{LrWlbBlrMX7~LXtAUs2q{3*ZMkE#bej2-L`f}i&6+GXx**ig@B&P4R4nVf^( zHfaOB8vNF)FTbMvV_cnrx6b@{r(dlkP8s@5Y z99Cz3d_(WFQ(}{5`ydTbxg|R2bYhYQwa+}EXF`XFJcYHdCj1n7FwPg~i{gU&-7yd+ z1KSsPH7m2nW{UO4CI=lZbW&Wq7U&#kV*WS}@!Q|NWvk-bbaaDmAM^V+aYB(zYm*hc#pL!eZ>{AXaME~+Xd!HZJ1=d#JQ%=)c4}alj<`X*M2U)#~f52vYt62`@pY< z_)B(gGAGb5_&4D1!2UqLn~u*DXFjw)`@og+Q4hKm;H{|qCct^{xHi6=ofqJfcysCU z0MJX!hh2BZ!x>^}NaUQzl;C~vHE?Bvw$0-5#7+*`CwFXcUb+1O4p?*M4W0qHeFK5@ zFn?=k2hI?DhTOWC8)7%X55aT0-wNwDF(Q%E%$q$s7mWj+YbkQBu)bg)(MZlTod@9` zh%w0gxU>V~y#KyzJD6ifjw%ietFx%T(RcjuvG?O14Zr>{CS>R6|Inc@zQz()iL=z3 zpL2xoel#R!EcOxTR?#DR%NFE2_Qjm}$g=(DaA-4dfISD@zJSv?)6rQs6MXhV_ka=yW@`Z?AC8x--6X`5?{$_7FG@nlh@b;`V*~n6YZVK@9ge zG7)eBu{!#RzmOkp^^Oz$(EIPbpRFGioa+6apYPBj;C$i&r{lv!|9f`rrt-=-@>=+u zm2y`V@uQ*n@^cJ@RTs1X^f~8ql%KX=pO`z&geX1%T4Kb|p(-OM#wxV4UwwH^<1Ajg zYL&)=<*vY}^@RVS|LMSqw{PG;Y+qj$`!)JoGv4MI{VxzG4(IuqQzv7w) z+4vgSGsJhBFm`OLbAT~%R>J#7>C&MU(UY@2#MH=d{V4iv;YlJUvc`4Q)=T7r*D);zm9E0l>H<48Cz-OaT7%k zl`fqX)gS11;{GAmTDoXanCJ)mcyGV@qtdWjLGF$XzgMQ^EeqX79`J=L z$MNR#dxsBRv2>Zz{7;N}G?KpXtE0H4ai4Rw3&fRtLODBY{E7^M~d2ek1-RcST?uToPl1ca?jPuw&&u zC*tpV#~<~M+>CP|O7{i60oL#z>MpTmqv{R&j;)=QFGcYc&~3={{N$KnZSW2GKQteF zC4L1_`7g!qoTE$R{KT(kWQO)j=tkIIQL!EHJAqb1H1(6p9t^zq0~XVxv)8B zY{)Q)H5Zo8?;A8C=Oc1HVq+DS9Mi8a1)T;h&-u*#de}9@Z4dklKM0&Ri*Uc~D>J6ZZ+Q{&DGjmp(>s9u~tksQpVRoi&4&hQGl^IFr6Z zKO!HA(ywACd`@hr(b2|@r2w3w!#sWJbSN*$`k|l32Ow_jH^#2?h4=%~)_93^5G7N} zWWI`98EiuEXTx3&`B*0XLoa|lJ!-!pvq6SVY;bE!5!D{@Hf)#aA3hCX`Jpw~vzf{p zuor``oT*~QIzln|r zIe#W&;f!xDxP-kFR34wfiQ~qZzlp67{%1kFIWUQx6?ep|udTpWP@SC9$bmD#UDQb& zDP&6AOB_YV1ofdLq!SYo9I!)dXt9TiJ0{KnWC_UJ!uSE~(hfcUg6fCxx%bNEpyRqf z_@MHO*sq1jCn$>#BRqTD{*s@)j=c(dzki=T8P$f9$QLrvF;Z`Ke6RBwBg5_A<@lTV zz=n$TKQ3{SGCc?2DZl|?vL5V^h_8!&2w1bc7Bu`Qxq||kG563^u2?Z}Pr^fB*Ox9Y z;ayYw)`(q=zZ|km@Au2`9UOoSEi!iey6nAtapnTt&%SI>r%tGU0rrCUs-cgx`XOMB z7<14e*mVZAt2zjw_tEW!oi#z_ky#>(BGxAhl=XrOSc66L=c_zws`%aq(UH_wOX`Jx2%;ZtKZ2gbDgpM0X``}F zIZJ}_UT*2&V(#zce8$%uoqr~CV0A=cHmB&1h_%8#oH2E(^7_z*VKN+S(U1vdO7CL> z2A_u=%%J}LQ)f>mV=Sp6NFh+%s;Y;Kru_Nt$( z2RdUF?E5f;V&|QNBRj}!aZ@^_l7-W5S)dL>2mr;{0L+M zvqdhL>0D6`TYJs}c>hTfOA{Rb&DY;(oD%d;oW=NXq2uA5IF0CG&`nI9FhTb_@+Hb= z+7Eb(@nZLgpW0lZaWk#wa$0}RXW~aCGlsuXNa|BU9k-%7B4Xx z(C1sbYG^+A0_=N^ieC@;$p4evF~yw~*pw6R6CXtC527vo)(G22_!|6$GL;wk)mzfj z2KMcz^w|N?!G!tJvlhs5(8KhTxC7W1LffHJ!-n#V#Nk4>_V~zA5<8-m`XPtS9lR*8 zK>m}$k8tM%^*}2ipWu$KeiE;c_GmW@7N8qwn^*YNaoLbl z0b8_3yVz>0ErQVZUV0Nc|L>whR^L6*DSO*U-gB%(3I9etGjp3M&qKn8*C*rp*{fS&B#qldIJS^ZnF z4P$-j$Ik6LRCk0<2w5_;2l6E1ST`-A__Vg~m-2I__`X345;qzBEpj{jqL^Fs$Abq9 z(6b(yoV(`knDN~~CIk)7I=bJyztPRGUep)F>(LH6XJ`U!1=g-!qcA{hKKe&Lq4%Nr zkS}=KNZ!Nuy*oeH`Jj(?|Go9*TXMHTPn8jcoxg59oW?3;nfsQB)?le=r{h` z$f|k?ULfxAzvMo1`|p(Ct#oltQ2m#CI{Xs!Jif%x;^2Gs75WqKE-`kYvD29+&UAD{ zL3Vn`8?fI_SN4dknfR=nPxOaa_1KId-^G^iwupP`(&=-O=Vx5OUauqeImAZAz8_i- zT8#7IQxCC+u=nZNwX2>x*p*`& zjO^%(&%ey&6@k%K1<)rQ0DtcmSFYUj^%N^6~O?ZP%a(5iDdGV_uA9%j8Lkl7YVx7^^@SQs*vHv2z$8V)P zI0o4*`pIRBmze&K^ie!v;U}FwCV2`6M!?HmFZB4 [options] parity account (new | list ) [options] parity account import ... [options] + parity wallet import --password FILE [options] parity import [ ] [options] parity export [ ] [options] parity signer new-token [options] parity [options] + parity ui [options] Protocol Options: --chain CHAIN Specify the blockchain type. CHAIN may be either a @@ -40,6 +42,12 @@ Protocol Options: --keys-path PATH Specify the path for JSON key files to be found [default: $HOME/.parity/keys]. --identity NAME Specify your node's name. + --fork POLICY Specifies the client's fork policy. POLICY must be + one of: + dogmatic - sticks rigidly to the standard chain. + dao-soft - votes for the DAO-rescue soft-fork. + normal - goes with whatever fork is decided but + votes for none. [default: normal]. Account Options: --unlock ACCOUNTS Unlock ACCOUNTS for the duration of the execution. @@ -52,6 +60,7 @@ Account Options: --no-import-keys Do not import keys from legacy clients. Networking Options: + --no-network Disable p2p networking. --port PORT Override the port on which the node should listen [default: 30303]. --peers NUM Try to maintain that many peers [default: 25]. @@ -65,9 +74,13 @@ Networking Options: --no-discovery Disable new peer discovery. --node-key KEY Specify node secret key, either as 64-character hex string or input to SHA3 operation. + --reserved-peers FILE Provide a file containing enodes, one per line. + These nodes will always have a reserved slot on top + of the normal maximum peers. + --reserved-only Connect only to reserved nodes. API and Console Options: - --jsonrpc-off Disable the JSON-RPC API server. + --no-jsonrpc Disable the JSON-RPC API server. --jsonrpc-port PORT Specify the port portion of the JSONRPC API server [default: 8545]. --jsonrpc-interface IP Specify the hostname portion of the JSONRPC API @@ -80,13 +93,13 @@ API and Console Options: ethcore, ethcore_set, traces. [default: web3,eth,net,ethcore,personal,traces]. - --ipc-off Disable JSON-RPC over IPC service. + --no-ipc Disable JSON-RPC over IPC service. --ipc-path PATH Specify custom path for JSON-RPC over IPC service [default: $HOME/.parity/jsonrpc.ipc]. --ipc-apis APIS Specify custom API set available via JSON-RPC over - IPC [default: web3,eth,net,ethcore,personal,traces]. + IPC [default: web3,eth,net,ethcore,personal,traces,rpc]. - --dapps-off Disable the Dapps server (e.g. status page). + --no-dapps Disable the Dapps server (e.g. status page). --dapps-port PORT Specify the port portion of the Dapps server [default: 8080]. --dapps-interface IP Specify the hostname portion of the Dapps @@ -102,15 +115,38 @@ API and Console Options: [default: $HOME/.parity/dapps] --signer Enable Trusted Signer WebSocket endpoint used by - Signer UIs. + Signer UIs. Default if run with ui command. + --no-signer Disable Trusted Signer WebSocket endpoint used by + Signer UIs. Default if no command is specified. --signer-port PORT Specify the port of Trusted Signer server [default: 8180]. --signer-path PATH Specify directory where Signer UIs tokens should be stored. [default: $HOME/.parity/signer] + --no-token By default a new system UI security token will be + output on start up. This will prevent it. Sealing/Mining Options: + --author ADDRESS Specify the block author (aka "coinbase") address + for sending block rewards from sealed blocks. + NOTE: MINING WILL NOT WORK WITHOUT THIS OPTION. --force-sealing Force the node to author new blocks as if it were always sealing/mining. + --reseal-on-txs SET Specify which transactions should force the node + to reseal a block. SET is one of: + none - never reseal on new transactions; + own - reseal only on a new local transaction; + ext - reseal only on a new external transaction; + all - reseal on all new transactions [default: all]. + --tx-gas-limit GAS Apply a limit of GAS as the maximum amount of gas + a single transaction may have for it to be mined. + --relay-set SET Set of transactions to relay. SET may be: + cheap - Relay any transaction in the queue (this + may include invalid transactions); + strict - Relay only executed transactions (this + guarantees we don't relay invalid transactions, but + means we relay nothing if not mining); + lenient - Same as strict when mining, and cheap + when not [default: cheap]. --usd-per-tx USD Amount of USD to be paid for a basic transaction [default: 0.005]. The minimum gas price is set accordingly. @@ -119,14 +155,13 @@ Sealing/Mining Options: web service in turn and fallback on the last known good value [default: auto]. --gas-floor-target GAS Amount of gas per block to target when sealing a new - block [default: 4712388]. - --author ADDRESS Specify the block author (aka "coinbase") address - for sending block rewards from sealed blocks - [default: 0037a6b811ffeb6e072da21179d11b1406371c63]. + block [default: 4700000]. + --gas-cap GAS A cap on how large we will raise the gas limit per + block due to transaction volume [default: 6283184]. --extra-data STRING Specify a custom extra-data for authored blocks, no more than 32 characters. - --tx-limit LIMIT Limit of transactions kept in the queue (waiting to - be included in next block) [default: 1024]. + --tx-queue-size LIMIT Maximum amount of transactions in the queue (waiting + to be included in next block) [default: 1024]. Footprint Options: --tracing BOOL Indicates if full transaction tracing should be @@ -135,15 +170,11 @@ Footprint Options: off. auto uses last used value of this option (off if it does not exist) [default: auto]. --pruning METHOD Configure pruning of the state/storage trie. METHOD - may be one of auto, archive, fast, basic, light: + may be one of auto, archive, fast: archive - keep all state trie data. No pruning. fast - maintain journal overlay. Fast but 50MB used. - basic - reference count in disk DB. Slow, light, and - experimental! - light - early merges with partial tracking. Fast, - light, and experimental! auto - use the method most recently synced or - default to archive if none synced [default: auto]. + default to fast if none synced [default: auto]. --cache-pref-size BYTES Specify the prefered size of the blockchain cache in bytes [default: 16384]. --cache-max-size BYTES Specify the maximum size of the blockchain cache in @@ -154,6 +185,12 @@ Footprint Options: the entire system, overrides other cache and queue options. +Database Options: + --db-cache-size MB Override RocksDB database cache size. + --db-compaction TYPE Database compaction type. TYPE may be one of: + ssd - suitable for SSDs and fast HDDs; + hdd - suitable for slow HDDs [default: ssd]. + Import/Export Options: --from BLOCK Export from block BLOCK, which may be an index or hash [default: 1]. @@ -166,9 +203,10 @@ Virtual Machine Options: --jitvm Enable the JIT VM. Legacy Options: - --geth Run in Geth-compatibility mode. Currently just sets - the IPC path to be the same as Geth's. Overrides - the --ipc-path/--ipcpath options. + --geth Run in Geth-compatibility mode. Sets the IPC path + to be the same as Geth's. Overrides the --ipc-path + and --ipcpath options. Alters RPCs to reflect Geth + bugs. --testnet Geth-compatible testnet mode. Equivalent to --chain testnet --keys-path $HOME/parity/testnet-keys. Overrides the --keys-path option. @@ -178,13 +216,16 @@ Legacy Options: --nodekey KEY Equivalent to --node-key KEY. --nodiscover Equivalent to --no-discovery. -j --jsonrpc Does nothing; JSON-RPC is on by default now. + --jsonrpc-off Equivalent to --no-jsonrpc. -w --webapp Does nothing; dapps server is on by default now. + --dapps-off Equivalent to --no-dapps. --rpc Does nothing; JSON-RPC is on by default now. --rpcaddr IP Equivalent to --jsonrpc-interface IP. --rpcport PORT Equivalent to --jsonrpc-port PORT. --rpcapi APIS Equivalent to --jsonrpc-apis APIS. --rpccorsdomain URL Equivalent to --jsonrpc-cors URL. - --ipcdisable Equivalent to --ipc-off. + --ipcdisable Equivalent to --no-ipc. + --ipc-off Equivalent to --no-ipc. --ipcapi APIS Equivalent to --ipc-apis APIS. --ipcpath PATH Equivalent to --ipc-path PATH. --gasprice WEI Minimum amount of Wei per GAS to be paid for a @@ -205,18 +246,21 @@ Miscellaneous Options: pub struct Args { pub cmd_daemon: bool, pub cmd_account: bool, + pub cmd_wallet: bool, pub cmd_new: bool, pub cmd_list: bool, pub cmd_export: bool, pub cmd_import: bool, pub cmd_signer: bool, pub cmd_new_token: bool, + pub cmd_ui: bool, pub arg_pid_file: String, pub arg_file: Option, pub arg_path: Vec, pub flag_chain: String, pub flag_db_path: String, pub flag_identity: String, + pub flag_fork: String, pub flag_unlock: Option, pub flag_password: Vec, pub flag_cache: Option, @@ -232,33 +276,41 @@ pub struct Args { pub flag_no_discovery: bool, pub flag_nat: String, pub flag_node_key: Option, + pub flag_reserved_peers: Option, + pub flag_reserved_only: bool, pub flag_cache_pref_size: usize, pub flag_cache_max_size: usize, pub flag_queue_max_size: usize, - pub flag_jsonrpc_off: bool, + pub flag_no_jsonrpc: bool, pub flag_jsonrpc_interface: String, pub flag_jsonrpc_port: u16, pub flag_jsonrpc_cors: Option, pub flag_jsonrpc_apis: String, - pub flag_ipc_off: bool, + pub flag_no_ipc: bool, pub flag_ipc_path: String, pub flag_ipc_apis: String, - pub flag_dapps_off: bool, + pub flag_no_dapps: bool, pub flag_dapps_port: u16, pub flag_dapps_interface: String, pub flag_dapps_user: Option, pub flag_dapps_pass: Option, pub flag_dapps_path: String, pub flag_signer: bool, + pub flag_no_signer: bool, pub flag_signer_port: u16, pub flag_signer_path: String, + pub flag_no_token: bool, pub flag_force_sealing: bool, - pub flag_author: String, + pub flag_reseal_on_txs: String, + pub flag_tx_gas_limit: Option, + pub flag_relay_set: String, + pub flag_author: Option, pub flag_usd_per_tx: String, pub flag_usd_per_eth: String, pub flag_gas_floor_target: String, + pub flag_gas_cap: String, pub flag_extra_data: Option, - pub flag_tx_limit: usize, + pub flag_tx_queue_size: usize, pub flag_logging: Option, pub flag_version: bool, pub flag_from: String, @@ -266,6 +318,7 @@ pub struct Args { pub flag_format: Option, pub flag_jitvm: bool, pub flag_no_color: bool, + pub flag_no_network: bool, // legacy... pub flag_geth: bool, pub flag_nodekey: Option, @@ -285,8 +338,13 @@ pub struct Args { pub flag_testnet: bool, pub flag_networkid: Option, pub flag_ipcdisable: bool, + pub flag_ipc_off: bool, + pub flag_jsonrpc_off: bool, + pub flag_dapps_off: bool, pub flag_ipcpath: Option, pub flag_ipcapi: Option, + pub flag_db_cache_size: Option, + pub flag_db_compaction: String, } pub fn print_version() { diff --git a/parity/configuration.rs b/parity/configuration.rs index 3076e4e68..121d40e6e 100644 --- a/parity/configuration.rs +++ b/parity/configuration.rs @@ -24,9 +24,10 @@ use docopt::Docopt; use die::*; use util::*; -use util::keys::store::{ImportKeySet, AccountService}; +use ethcore::account_provider::AccountProvider; use util::network_settings::NetworkSettings; -use ethcore::client::{append_path, get_db_path, ClientConfig, Switch, VMType}; +use ethcore::client::{append_path, get_db_path, ClientConfig, DatabaseCompactionProfile, Switch, VMType}; +use ethcore::miner::{MinerOptions, PendingSet}; use ethcore::ethereum; use ethcore::spec::Spec; use ethsync::SyncConfig; @@ -44,6 +45,13 @@ pub struct Directories { pub signer: String, } +#[derive(Eq, PartialEq, Debug)] +pub enum Policy { + DaoSoft, + Normal, + Dogmatic, +} + impl Configuration { pub fn parse() -> Self { Configuration { @@ -67,18 +75,74 @@ impl Configuration { self.args.flag_maxpeers.unwrap_or(self.args.flag_peers) as u32 } - pub fn author(&self) -> Address { - let d = self.args.flag_etherbase.as_ref().unwrap_or(&self.args.flag_author); - Address::from_str(clean_0x(d)).unwrap_or_else(|_| { - die!("{}: Invalid address for --author. Must be 40 hex characters, with or without the 0x at the beginning.", d) - }) + fn decode_u256(d: &str, argument: &str) -> U256 { + U256::from_dec_str(d).unwrap_or_else(|_| + U256::from_str(clean_0x(d)).unwrap_or_else(|_| + die!("{}: Invalid numeric value for {}. Must be either a decimal or a hex number.", d, argument) + ) + ) + } + + pub fn miner_options(&self) -> MinerOptions { + let (own, ext) = match self.args.flag_reseal_on_txs.as_str() { + "none" => (false, false), + "own" => (true, false), + "ext" => (false, true), + "all" => (true, true), + x => die!("{}: Invalid value for --reseal option. Use --help for more information.", x) + }; + MinerOptions { + force_sealing: self.args.flag_force_sealing, + reseal_on_external_tx: ext, + reseal_on_own_tx: own, + tx_gas_limit: self.args.flag_tx_gas_limit.as_ref().map_or(!U256::zero(), |d| Self::decode_u256(d, "--tx-gas-limit")), + tx_queue_size: self.args.flag_tx_queue_size, + pending_set: match self.args.flag_relay_set.as_str() { + "cheap" => PendingSet::AlwaysQueue, + "strict" => PendingSet::AlwaysSealing, + "lenient" => PendingSet::SealingOrElseQueue, + x => die!("{}: Invalid value for --relay-set option. Use --help for more information.", x) + }, + } + } + + pub fn author(&self) -> Option
{ + self.args.flag_etherbase.as_ref() + .or(self.args.flag_author.as_ref()) + .map(|d| Address::from_str(clean_0x(d)).unwrap_or_else(|_| { + die!("{}: Invalid address for --author. Must be 40 hex characters, with or without the 0x at the beginning.", d) + })) + } + + pub fn policy(&self) -> Policy { + match self.args.flag_fork.as_str() { + "dao-soft" => Policy::DaoSoft, + "normal" => Policy::Normal, + "dogmatic" => Policy::Dogmatic, + x => die!("{}: Invalid value given for --policy option. Use --help for more info.", x) + } } pub fn gas_floor_target(&self) -> U256 { - let d = &self.args.flag_gas_floor_target; - U256::from_dec_str(d).unwrap_or_else(|_| { - die!("{}: Invalid target gas floor given. Must be a decimal unsigned 256-bit number.", d) - }) + if self.policy() == Policy::DaoSoft { + 3_141_592.into() + } else { + let d = &self.args.flag_gas_floor_target; + U256::from_dec_str(d).unwrap_or_else(|_| { + die!("{}: Invalid target gas floor given. Must be a decimal unsigned 256-bit number.", d) + }) + } + } + + pub fn gas_ceil_target(&self) -> U256 { + if self.policy() == Policy::DaoSoft { + 3_141_592.into() + } else { + let d = &self.args.flag_gas_cap; + U256::from_dec_str(d).unwrap_or_else(|_| { + die!("{}: Invalid target gas ceiling given. Must be a decimal unsigned 256-bit number.", d) + }) + } } pub fn gas_price(&self) -> U256 { @@ -124,7 +188,7 @@ impl Configuration { pub fn spec(&self) -> Spec { match self.chain().as_str() { - "frontier" | "homestead" | "mainnet" => ethereum::new_frontier(), + "frontier" | "homestead" | "mainnet" => ethereum::new_frontier(self.policy() != Policy::Dogmatic), "morden" | "testnet" => ethereum::new_morden(), "olympic" => ethereum::new_olympic(), f => Spec::load(contents(f).unwrap_or_else(|_| { @@ -153,6 +217,25 @@ impl Configuration { } } + pub fn init_reserved_nodes(&self) -> Vec { + use std::fs::File; + + if let Some(ref path) = self.args.flag_reserved_peers { + let mut buffer = String::new(); + let mut node_file = File::open(path).unwrap_or_else(|e| { + die!("Error opening reserved nodes file: {}", e); + }); + node_file.read_to_string(&mut buffer).expect("Error reading reserved node file"); + buffer.lines().map(|s| { + Self::normalize_enode(s).unwrap_or_else(|| { + die!("{}: Invalid node address format given for a reserved node.", s); + }) + }).collect() + } else { + Vec::new() + } + } + pub fn net_addresses(&self) -> (Option, Option) { let port = self.net_port(); let listen_address = Some(SocketAddr::new(IpAddr::from_str("0.0.0.0").unwrap(), port)); @@ -179,6 +262,11 @@ impl Configuration { let mut net_path = PathBuf::from(&self.path()); net_path.push("network"); ret.config_path = Some(net_path.to_str().unwrap().to_owned()); + ret.reserved_nodes = self.init_reserved_nodes(); + + if self.args.flag_reserved_only { + ret.non_reserved_mode = ::util::network::NonReservedPeerMode::Deny; + } ret } @@ -187,7 +275,7 @@ impl Configuration { let mut latest_era = None; let jdb_types = [journaldb::Algorithm::Archive, journaldb::Algorithm::EarlyMerge, journaldb::Algorithm::OverlayRecent, journaldb::Algorithm::RefCounted]; for i in jdb_types.into_iter() { - let db = journaldb::new(&append_path(&get_db_path(Path::new(&self.path()), *i, spec.genesis_header().hash()), "state"), *i); + let db = journaldb::new(&append_path(&get_db_path(Path::new(&self.path()), *i, spec.genesis_header().hash()), "state"), *i, kvdb::DatabaseConfig::default()); trace!(target: "parity", "Looking for best DB: {} at {:?}", i, db.latest_era()); match (latest_era, db.latest_era()) { (Some(best), Some(this)) if best >= this => {} @@ -214,6 +302,8 @@ impl Configuration { client_config.blockchain.max_cache_size = self.args.flag_cache_max_size; } } + // forced blockchain (blocks + extras) db cache size if provided + client_config.blockchain.db_cache_size = self.args.flag_db_cache_size.and_then(|cs| Some(cs / 2)); client_config.tracing.enabled = match self.args.flag_tracing.as_str() { "auto" => Switch::Auto, @@ -221,16 +311,28 @@ impl Configuration { "off" => Switch::Off, _ => { die!("Invalid tracing method given!") } }; + // forced trace db cache size if provided + client_config.tracing.db_cache_size = self.args.flag_db_cache_size.and_then(|cs| Some(cs / 4)); client_config.pruning = match self.args.flag_pruning.as_str() { "archive" => journaldb::Algorithm::Archive, "light" => journaldb::Algorithm::EarlyMerge, "fast" => journaldb::Algorithm::OverlayRecent, "basic" => journaldb::Algorithm::RefCounted, - "auto" => self.find_best_db(spec).unwrap_or(journaldb::Algorithm::Archive), + "auto" => self.find_best_db(spec).unwrap_or(journaldb::Algorithm::OverlayRecent), _ => { die!("Invalid pruning method given."); } }; + // forced state db cache size if provided + client_config.db_cache_size = self.args.flag_db_cache_size.and_then(|cs| Some(cs / 4)); + + // compaction profile + client_config.db_compaction = match self.args.flag_db_compaction.as_str() { + "ssd" => DatabaseCompactionProfile::Default, + "hdd" => DatabaseCompactionProfile::HDD, + _ => { die!("Invalid compaction profile given (--db-compaction argument), expected hdd/default."); } + }; + if self.args.flag_jitvm { client_config.vm_type = VMType::jit().unwrap_or_else(|| die!("Parity built without jit vm.")) } @@ -249,7 +351,10 @@ impl Configuration { sync_config } - pub fn account_service(&self) -> AccountService { + pub fn account_service(&self) -> AccountProvider { + use ethcore::ethstore::{import_accounts, EthStore}; + use ethcore::ethstore::dir::{GethDirectory, DirectoryType, DiskDirectory}; + // Secret Store let passwords = self.args.flag_password.iter().flat_map(|filename| { BufReader::new(&File::open(filename).unwrap_or_else(|_| die!("{} Unable to read password file. Ensure it exists and permissions are correct.", filename))) @@ -258,18 +363,30 @@ impl Configuration { .collect::>() .into_iter() }).collect::>(); - let import_keys = match (self.args.flag_no_import_keys, self.args.flag_testnet) { - (true, _) => ImportKeySet::None, - (false, false) => ImportKeySet::Legacy, - (false, true) => ImportKeySet::LegacyTestnet, - }; - let account_service = AccountService::with_security(Path::new(&self.keys_path()), self.keys_iterations(), import_keys); + + if !self.args.flag_no_import_keys { + let dir_type = if self.args.flag_testnet { + DirectoryType::Testnet + } else { + DirectoryType::Main + }; + + let from = GethDirectory::open(dir_type); + let to = DiskDirectory::create(self.keys_path()).unwrap(); + // ignore error, cause geth may not exist + let _ = import_accounts(&from, &to); + } + + let dir = Box::new(DiskDirectory::create(self.keys_path()).unwrap()); + let iterations = self.keys_iterations(); + let account_service = AccountProvider::new(Box::new(EthStore::open_with_iterations(dir, iterations).unwrap())); + if let Some(ref unlocks) = self.args.flag_unlock { for d in unlocks.split(',') { let a = Address::from_str(clean_0x(d)).unwrap_or_else(|_| { die!("{}: Invalid address for --unlock. Must be 40 hex characters, without the 0x at the beginning.", d) }); - if passwords.iter().find(|p| account_service.unlock_account_no_expire(&a, p).is_ok()).is_none() { + if passwords.iter().find(|p| account_service.unlock_account_permanently(a, (*p).clone()).is_ok()).is_none() { die!("No password given to unlock account {}. Pass the password using `--password`.", a); } } @@ -287,9 +404,14 @@ impl Configuration { } fn geth_ipc_path(&self) -> String { - if self.args.flag_testnet { path::ethereum::with_testnet("geth.ipc") } - else { path::ethereum::with_default("geth.ipc") } - .to_str().unwrap().to_owned() + if cfg!(windows) { + r"\\.\pipe\geth.ipc".to_owned() + } + else { + if self.args.flag_testnet { path::ethereum::with_testnet("geth.ipc") } + else { path::ethereum::with_default("geth.ipc") } + .to_str().unwrap().to_owned() + } } pub fn keys_iterations(&self) -> u32 { @@ -298,7 +420,7 @@ impl Configuration { pub fn ipc_settings(&self) -> IpcConfiguration { IpcConfiguration { - enabled: !(self.args.flag_ipcdisable || self.args.flag_ipc_off), + enabled: !(self.args.flag_ipcdisable || self.args.flag_ipc_off || self.args.flag_no_ipc), socket_addr: self.ipc_path(), apis: self.args.flag_ipcapi.clone().unwrap_or(self.args.flag_ipc_apis.clone()), } @@ -311,7 +433,7 @@ impl Configuration { chain: self.chain(), max_peers: self.max_peers(), network_port: self.net_port(), - rpc_enabled: !self.args.flag_jsonrpc_off, + rpc_enabled: !self.args.flag_jsonrpc_off && !self.args.flag_no_jsonrpc, rpc_interface: self.args.flag_rpcaddr.clone().unwrap_or(self.args.flag_jsonrpc_interface.clone()), rpc_port: self.args.flag_rpcport.unwrap_or(self.args.flag_jsonrpc_port), } @@ -357,17 +479,51 @@ impl Configuration { } fn ipc_path(&self) -> String { - if self.args.flag_geth { self.geth_ipc_path() } - else { Configuration::replace_home(&self.args.flag_ipcpath.clone().unwrap_or(self.args.flag_ipc_path.clone())) } + if self.args.flag_geth { + self.geth_ipc_path() + } else if cfg!(windows) { + r"\\.\pipe\parity.jsonrpc".to_owned() + } else { + Configuration::replace_home(&self.args.flag_ipcpath.clone().unwrap_or(self.args.flag_ipc_path.clone())) + } + } + + pub fn have_color(&self) -> bool { + !self.args.flag_no_color && !cfg!(windows) } pub fn signer_port(&self) -> Option { - if self.args.flag_signer { - Some(self.args.flag_signer_port) - } else { + if !self.signer_enabled() { None + } else { + Some(self.args.flag_signer_port) } } + + pub fn rpc_interface(&self) -> String { + match self.network_settings().rpc_interface.as_str() { + "all" => "0.0.0.0", + "local" => "127.0.0.1", + x => x, + }.into() + } + + pub fn dapps_interface(&self) -> String { + match self.args.flag_dapps_interface.as_str() { + "all" => "0.0.0.0", + "local" => "127.0.0.1", + x => x, + }.into() + } + + pub fn dapps_enabled(&self) -> bool { + !self.args.flag_dapps_off && !self.args.flag_no_dapps + } + + pub fn signer_enabled(&self) -> bool { + (self.args.cmd_ui && !self.args.flag_no_signer) || + (!self.args.cmd_ui && self.args.flag_signer) + } } #[cfg(test)] diff --git a/parity/dapps.rs b/parity/dapps.rs index 59a9ee552..917c59fc6 100644 --- a/parity/dapps.rs +++ b/parity/dapps.rs @@ -45,12 +45,7 @@ pub fn new(configuration: Configuration, deps: Dependencies) -> Option "0.0.0.0", - "local" => "127.0.0.1", - x => x, - }; - let url = format!("{}:{}", interface, configuration.port); + let url = format!("{}:{}", configuration.interface, configuration.port); let addr = SocketAddr::from_str(&url).unwrap_or_else(|_| die!("{}: Invalid Webapps listen host/port given.", url)); let auth = configuration.user.as_ref().map(|username| { diff --git a/parity/io_handler.rs b/parity/io_handler.rs index d130d584c..3f0c04fbd 100644 --- a/parity/io_handler.rs +++ b/parity/io_handler.rs @@ -14,38 +14,52 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::sync::Arc; +use std::sync::{Arc, Weak}; use ethcore::client::Client; -use ethcore::service::NetSyncMessage; +use ethcore::service::{NetSyncMessage, SyncMessage}; use ethsync::EthSync; -use util::keys::store::AccountService; -use util::{TimerToken, IoHandler, IoContext}; +use ethcore::account_provider::AccountProvider; +use util::{TimerToken, IoHandler, IoContext, NetworkService, NetworkIoMessage}; use informant::Informant; const INFO_TIMER: TimerToken = 0; -const ACCOUNT_TICK_TIMER: TimerToken = 10; -const ACCOUNT_TICK_MS: u64 = 60000; - pub struct ClientIoHandler { pub client: Arc, pub sync: Arc, - pub accounts: Arc, + pub accounts: Arc, pub info: Informant, + pub network: Weak>, } impl IoHandler for ClientIoHandler { fn initialize(&self, io: &IoContext) { io.register_timer(INFO_TIMER, 5000).expect("Error registering timer"); - io.register_timer(ACCOUNT_TICK_TIMER, ACCOUNT_TICK_MS).expect("Error registering account timer"); } fn timeout(&self, _io: &IoContext, timer: TimerToken) { - match timer { - INFO_TIMER => { self.info.tick(&self.client, Some(&self.sync)); } - ACCOUNT_TICK_TIMER => { self.accounts.tick(); }, - _ => {} + if let INFO_TIMER = timer { + self.info.tick(&self.client, Some(&self.sync)); + } + } + + fn message(&self, _io: &IoContext, message: &NetSyncMessage) { + match *message { + NetworkIoMessage::User(SyncMessage::StartNetwork) => { + info!("Starting network"); + if let Some(network) = self.network.upgrade() { + network.start().unwrap_or_else(|e| warn!("Error starting network: {:?}", e)); + EthSync::register(&*network, self.sync.clone()).unwrap_or_else(|e| warn!("Error registering eth protocol handler: {}", e)); + } + }, + NetworkIoMessage::User(SyncMessage::StopNetwork) => { + info!("Stopping network"); + if let Some(network) = self.network.upgrade() { + network.stop().unwrap_or_else(|e| warn!("Error stopping network: {:?}", e)); + } + }, + _ => {/* Ignore other messages */}, } } } diff --git a/parity/main.rs b/parity/main.rs index 0d536e28a..047338bc8 100644 --- a/parity/main.rs +++ b/parity/main.rs @@ -32,6 +32,7 @@ extern crate log as rlog; extern crate env_logger; extern crate ctrlc; extern crate fdlimit; +#[cfg(not(windows))] extern crate daemonize; extern crate time; extern crate number_prefix; @@ -67,6 +68,7 @@ mod configuration; mod migration; mod signer; mod rpc_apis; +mod url; use std::io::{Write, Read, BufReader, BufRead}; use std::ops::Deref; @@ -78,7 +80,7 @@ use std::thread::sleep; use std::time::Duration; use rustc_serialize::hex::FromHex; use ctrlc::CtrlC; -use util::{H256, ToPretty, NetworkConfiguration, PayloadInfo, Bytes}; +use util::{H256, ToPretty, NetworkConfiguration, PayloadInfo, Bytes, UtilError}; use util::panics::{MayPanic, ForwardPanic, PanicHandler}; use ethcore::client::{BlockID, BlockChainClient, ClientConfig, get_db_path}; use ethcore::error::{Error, ImportError}; @@ -86,7 +88,6 @@ use ethcore::service::ClientService; use ethcore::spec::Spec; use ethsync::EthSync; use ethcore::miner::{Miner, MinerService, ExternalMiner}; -use daemonize::Daemonize; use migration::migrate; use informant::Informant; @@ -109,17 +110,18 @@ fn execute(conf: Configuration) { return; } + if conf.args.cmd_signer { + execute_signer(conf); + return; + } + let spec = conf.spec(); let client_config = conf.client_config(&spec); execute_upgrades(&conf, &spec, &client_config); if conf.args.cmd_daemon { - Daemonize::new() - .pid_file(conf.args.arg_pid_file.clone()) - .chown_pid_file(true) - .start() - .unwrap_or_else(|e| die!("Couldn't daemonize; {}", e)); + daemonize(&conf); } if conf.args.cmd_account { @@ -127,6 +129,11 @@ fn execute(conf: Configuration) { return; } + if conf.args.cmd_wallet { + execute_wallet_cli(conf); + return; + } + if conf.args.cmd_export { execute_export(conf); return; @@ -137,14 +144,23 @@ fn execute(conf: Configuration) { return; } - if conf.args.cmd_signer { - execute_signer(conf); - return; - } - execute_client(conf, spec, client_config); } +#[cfg(not(windows))] +fn daemonize(conf: &Configuration) { + use daemonize::Daemonize; + Daemonize::new() + .pid_file(conf.args.arg_pid_file.clone()) + .chown_pid_file(true) + .start() + .unwrap_or_else(|e| die!("Couldn't daemonize; {}", e)); +} + +#[cfg(windows)] +fn daemonize(_conf: &Configuration) { +} + fn execute_upgrades(conf: &Configuration, spec: &Spec, client_config: &ClientConfig) { match ::upgrade::upgrade(Some(&conf.path())) { Ok(upgrades_applied) if upgrades_applied > 0 => { @@ -175,20 +191,34 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) let net_settings = conf.net_settings(&spec); let sync_config = conf.sync_config(&spec); + // Create and display a new token for UIs. + if conf.signer_enabled() && !conf.args.flag_no_token { + new_token(conf.directories().signer).unwrap_or_else(|e| { + die!("Error generating token: {:?}", e) + }); + } + + // Display warning about using unlock with signer + if conf.signer_enabled() && conf.args.flag_unlock.is_some() { + warn!("Using Trusted Signer and --unlock is not recommended!"); + warn!("NOTE that Signer will not ask you to confirm transactions from unlocked account."); + } + // Secret Store let account_service = Arc::new(conf.account_service()); // Miner - let miner = Miner::with_accounts(conf.args.flag_force_sealing, conf.spec(), account_service.clone()); - miner.set_author(conf.author()); + let miner = Miner::new(conf.miner_options(), conf.spec(), Some(account_service.clone())); + miner.set_author(conf.author().unwrap_or_default()); miner.set_gas_floor_target(conf.gas_floor_target()); + miner.set_gas_ceil_target(conf.gas_ceil_target()); miner.set_extra_data(conf.extra_data()); miner.set_minimal_gas_price(conf.gas_price()); - miner.set_transactions_limit(conf.args.flag_tx_limit); + miner.set_transactions_limit(conf.args.flag_tx_queue_size); // Build client let mut service = ClientService::start( - client_config, spec, net_settings, Path::new(&conf.path()), miner.clone() + client_config, spec, net_settings, Path::new(&conf.path()), miner.clone(), !conf.args.flag_no_network ).unwrap_or_else(|e| die_with_error("Client", e)); panic_handler.forward_from(&service); @@ -198,7 +228,8 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) let network_settings = Arc::new(conf.network_settings()); // Sync - let sync = EthSync::register(service.network(), sync_config, client.clone()); + let sync = EthSync::new(sync_config, client.clone()); + EthSync::register(&*service.network(), sync.clone()).unwrap_or_else(|e| die_with_error("Error registering eth protocol handler", UtilError::from(e).into())); let deps_for_rpc_apis = Arc::new(rpc_apis::Dependencies { signer_port: conf.signer_port(), @@ -210,6 +241,8 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) external_miner: external_miner.clone(), logger: logger.clone(), settings: network_settings.clone(), + allow_pending_receipt_query: !conf.args.flag_geth, + net_service: service.network(), }); let dependencies = rpc::Dependencies { @@ -220,7 +253,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) // Setup http rpc let rpc_server = rpc::new_http(rpc::HttpConfiguration { enabled: network_settings.rpc_enabled, - interface: network_settings.rpc_interface.clone(), + interface: conf.rpc_interface(), port: network_settings.rpc_port, apis: conf.rpc_apis(), cors: conf.rpc_cors(), @@ -228,11 +261,12 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) // setup ipc rpc let _ipc_server = rpc::new_ipc(conf.ipc_settings(), &dependencies); + debug!("IPC: {}", conf.ipc_settings()); if conf.args.flag_webapp { println!("WARNING: Flag -w/--webapp is deprecated. Dapps server is now on by default. Ignoring."); } let dapps_server = dapps::new(dapps::Configuration { - enabled: !conf.args.flag_dapps_off, - interface: conf.args.flag_dapps_interface.clone(), + enabled: conf.dapps_enabled(), + interface: conf.dapps_interface(), port: conf.args.flag_dapps_port, user: conf.args.flag_dapps_user.clone(), pass: conf.args.flag_dapps_pass.clone(), @@ -244,7 +278,7 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) // Set up a signer let signer_server = signer::start(signer::Configuration { - enabled: deps_for_rpc_apis.signer_port.is_some(), + enabled: conf.signer_enabled(), port: conf.args.flag_signer_port, signer_path: conf.directories().signer, }, signer::Dependencies { @@ -255,11 +289,19 @@ fn execute_client(conf: Configuration, spec: Spec, client_config: ClientConfig) // Register IO handler let io_handler = Arc::new(ClientIoHandler { client: service.client(), - info: Informant::new(!conf.args.flag_no_color), + info: Informant::new(conf.have_color()), sync: sync.clone(), accounts: account_service.clone(), + network: Arc::downgrade(&service.network()), }); - service.io().register_handler(io_handler).expect("Error registering IO handler"); + service.register_io_handler(io_handler).expect("Error registering IO handler"); + + if conf.args.cmd_ui { + if !conf.dapps_enabled() { + die_with_message("Cannot use UI command with Dapps turned off."); + } + url::open(&format!("http://{}:{}/", conf.dapps_interface(), conf.args.flag_dapps_port)); + } // Handle exit wait_for_exit(panic_handler, rpc_server, dapps_server, signer_server); @@ -289,16 +331,17 @@ fn execute_export(conf: Configuration) { udp_port: None, nat_enabled: false, discovery_enabled: false, - pin: true, boot_nodes: Vec::new(), use_secret: None, ideal_peers: 0, + reserved_nodes: Vec::new(), + non_reserved_mode: ::util::network::NonReservedPeerMode::Accept, }; let client_config = conf.client_config(&spec); // Build client let service = ClientService::start( - client_config, spec, net_settings, Path::new(&conf.path()), Arc::new(Miner::default()), + client_config, spec, net_settings, Path::new(&conf.path()), Arc::new(Miner::with_spec(conf.spec())), false ).unwrap_or_else(|e| die_with_error("Client", e)); panic_handler.forward_from(&service); @@ -360,33 +403,36 @@ fn execute_import(conf: Configuration) { udp_port: None, nat_enabled: false, discovery_enabled: false, - pin: true, boot_nodes: Vec::new(), use_secret: None, ideal_peers: 0, + reserved_nodes: Vec::new(), + non_reserved_mode: ::util::network::NonReservedPeerMode::Accept, }; let client_config = conf.client_config(&spec); // Build client let service = ClientService::start( - client_config, spec, net_settings, Path::new(&conf.path()), Arc::new(Miner::default()), + client_config, spec, net_settings, Path::new(&conf.path()), Arc::new(Miner::with_spec(conf.spec())), false ).unwrap_or_else(|e| die_with_error("Client", e)); panic_handler.forward_from(&service); let client = service.client(); - let mut instream: Box = if let Some(f) = conf.args.arg_file { - let f = File::open(&f).unwrap_or_else(|_| die!("Cannot open the file given: {}", f)); + let mut instream: Box = if let Some(ref f) = conf.args.arg_file { + let f = File::open(f).unwrap_or_else(|_| die!("Cannot open the file given: {}", f)); Box::new(f) } else { Box::new(::std::io::stdin()) }; - let mut first_bytes: Bytes = vec![0; 3]; + const READAHEAD_BYTES: usize = 8; + + let mut first_bytes: Bytes = vec![0; READAHEAD_BYTES]; let mut first_read = 0; let format = match conf.args.flag_format { - Some(x) => match x.deref() { + Some(ref x) => match x.deref() { "binary" | "bin" => DataFormat::Binary, "hex" => DataFormat::Hex, x => die!("Invalid --format parameter given: {:?}", x), @@ -407,7 +453,7 @@ fn execute_import(conf: Configuration) { } }; - let informant = Informant::new(!conf.args.flag_no_color); + let informant = Informant::new(conf.have_color()); let do_import = |bytes| { while client.queue_info().is_full() { sleep(Duration::from_secs(1)); } @@ -422,13 +468,13 @@ fn execute_import(conf: Configuration) { match format { DataFormat::Binary => { loop { - let mut bytes: Bytes = if first_read > 0 {first_bytes.clone()} else {vec![0; 3]}; + let mut bytes: Bytes = if first_read > 0 {first_bytes.clone()} else {vec![0; READAHEAD_BYTES]}; let n = if first_read > 0 {first_read} else {instream.read(&mut(bytes[..])).unwrap_or_else(|_| die!("Error reading from the file/stream."))}; if n == 0 { break; } first_read = 0; let s = PayloadInfo::from(&(bytes[..])).unwrap_or_else(|e| die!("Invalid RLP in the file/stream: {:?}", e)).total(); bytes.resize(s, 0); - instream.read_exact(&mut(bytes[3..])).unwrap_or_else(|_| die!("Error reading from the file/stream.")); + instream.read_exact(&mut(bytes[READAHEAD_BYTES..])).unwrap_or_else(|_| die!("Error reading from the file/stream.")); do_import(bytes); } } @@ -457,9 +503,15 @@ fn execute_signer(conf: Configuration) { } fn execute_account_cli(conf: Configuration) { - use util::keys::store::SecretStore; + use ethcore::ethstore::{EthStore, import_accounts}; + use ethcore::ethstore::dir::DiskDirectory; + use ethcore::account_provider::AccountProvider; use rpassword::read_password; - let mut secret_store = SecretStore::with_security(Path::new(&conf.keys_path()), conf.keys_iterations()); + + let dir = Box::new(DiskDirectory::create(conf.keys_path()).unwrap()); + let iterations = conf.keys_iterations(); + let secret_store = AccountProvider::new(Box::new(EthStore::open_with_iterations(dir, iterations).unwrap())); + if conf.args.cmd_new { println!("Please note that password is NOT RECOVERABLE."); print!("Type password: "); @@ -477,19 +529,50 @@ fn execute_account_cli(conf: Configuration) { println!("{:?}", new_address); return; } + if conf.args.cmd_list { println!("Known addresses:"); - for &(addr, _) in &secret_store.accounts().unwrap() { + for addr in &secret_store.accounts() { println!("{:?}", addr); } return; } + if conf.args.cmd_import { - let imported = util::keys::import_keys_paths(&mut secret_store, &conf.args.arg_path).unwrap(); + let to = DiskDirectory::create(conf.keys_path()).unwrap(); + let mut imported = 0; + for path in &conf.args.arg_path { + let from = DiskDirectory::at(path); + imported += import_accounts(&from, &to).unwrap_or_else(|e| die!("Could not import accounts {}", e)).len(); + } println!("Imported {} keys", imported); } } +fn execute_wallet_cli(conf: Configuration) { + use ethcore::ethstore::{PresaleWallet, EthStore}; + use ethcore::ethstore::dir::DiskDirectory; + use ethcore::account_provider::AccountProvider; + + let wallet_path = conf.args.arg_path.first().unwrap(); + let filename = conf.args.flag_password.first().unwrap(); + let mut file = File::open(filename).unwrap_or_else(|_| die!("{} Unable to read password file.", filename)); + let mut file_content = String::new(); + file.read_to_string(&mut file_content).unwrap_or_else(|_| die!("{} Unable to read password file.", filename)); + + let dir = Box::new(DiskDirectory::create(conf.keys_path()).unwrap()); + let iterations = conf.keys_iterations(); + let store = AccountProvider::new(Box::new(EthStore::open_with_iterations(dir, iterations).unwrap())); + + // remove eof + let pass = &file_content[..file_content.len() - 1]; + let wallet = PresaleWallet::open(wallet_path).unwrap_or_else(|_| die!("Unable to open presale wallet.")); + let kp = wallet.decrypt(pass).unwrap_or_else(|_| die!("Invalid password")); + let address = store.insert_account(kp.secret().clone(), pass).unwrap(); + + println!("Imported account: {}", address); +} + fn wait_for_exit( panic_handler: Arc, _rpc_server: Option, diff --git a/parity/migration.rs b/parity/migration.rs index acfd32ffd..df2c2116f 100644 --- a/parity/migration.rs +++ b/parity/migration.rs @@ -20,7 +20,7 @@ use std::io::{Read, Write, Error as IoError, ErrorKind}; use std::path::PathBuf; use std::fmt::{Display, Formatter, Error as FmtError}; use util::migration::{Manager as MigrationManager, Config as MigrationConfig, MigrationIterator}; -use util::kvdb::{Database, DatabaseConfig}; +use util::kvdb::{Database, DatabaseConfig, CompactionProfile}; use ethcore::migrations; /// Database is assumed to be at default version, when no version file is found. @@ -89,6 +89,7 @@ fn current_version(path: &PathBuf) -> Result { /// Writes current database version to the file. /// Creates a new file if the version file does not exist yet. fn update_version(path: &PathBuf) -> Result<(), Error> { + try!(fs::create_dir_all(path)); let mut file = try!(File::create(version_file_path(path))); try!(file.write_all(format!("{}", CURRENT_VERSION).as_bytes())); Ok(()) @@ -151,8 +152,6 @@ fn migrate_database(version: u32, path: PathBuf, migrations: MigrationManager) - return Ok(()) } - println!("Migrating database {} from version {} to {}", path.to_string_lossy(), version, CURRENT_VERSION); - let temp_path = temp_database_path(&path); let backup_path = backup_database_path(&path); // remote the dir if it exists @@ -163,6 +162,8 @@ fn migrate_database(version: u32, path: PathBuf, migrations: MigrationManager) - let db_config = DatabaseConfig { prefix_size: None, max_open_files: 64, + cache_size: None, + compaction: CompactionProfile::default(), }; // open old database @@ -187,20 +188,26 @@ fn migrate_database(version: u32, path: PathBuf, migrations: MigrationManager) - // remove backup try!(fs::remove_dir_all(&backup_path)); - println!("Migration finished"); Ok(()) } +fn exists(path: &PathBuf) -> bool { + fs::metadata(path).is_ok() +} + /// Migrates the database. pub fn migrate(path: &PathBuf) -> Result<(), Error> { // read version file. let version = try!(current_version(path)); // migrate the databases. - if version != CURRENT_VERSION { + // main db directory may already exists, so let's check if we have blocks dir + if version != CURRENT_VERSION && exists(&blocks_database_path(path)) { + println!("Migrating database from version {} to {}", version, CURRENT_VERSION); try!(migrate_database(version, blocks_database_path(path), try!(blocks_database_migrations()))); try!(migrate_database(version, extras_database_path(path), try!(extras_database_migrations()))); + println!("Migration finished"); } // update version file. diff --git a/parity/rpc.rs b/parity/rpc.rs index 66f504408..df1e14524 100644 --- a/parity/rpc.rs +++ b/parity/rpc.rs @@ -22,6 +22,7 @@ use util::panics::PanicHandler; use die::*; use jsonipc; use rpc_apis; +use std::fmt; #[cfg(feature = "rpc")] pub use ethcore_rpc::Server as RpcServer; @@ -44,6 +45,17 @@ pub struct IpcConfiguration { pub apis: String, } +impl fmt::Display for IpcConfiguration { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + if self.enabled { + write!(f, "endpoint address [{}], api list [{}]", self.socket_addr, self.apis) + } + else { + write!(f, "disabled") + } + } +} + pub struct Dependencies { pub panic_handler: Arc, pub apis: Arc, @@ -54,24 +66,13 @@ pub fn new_http(conf: HttpConfiguration, deps: &Dependencies) -> Option "0.0.0.0", - "local" => "127.0.0.1", - x => x, - }; let apis = conf.apis.split(',').collect(); - let url = format!("{}:{}", interface, conf.port); + let url = format!("{}:{}", conf.interface, conf.port); let addr = SocketAddr::from_str(&url).unwrap_or_else(|_| die!("{}: Invalid JSONRPC listen host/port given.", url)); Some(setup_http_rpc_server(deps, &addr, conf.cors, apis)) } -pub fn new_ipc(conf: IpcConfiguration, deps: &Dependencies) -> Option { - if !conf.enabled { return None; } - let apis = conf.apis.split(',').collect(); - Some(setup_ipc_rpc_server(deps, &conf.socket_addr, apis)) -} - fn setup_rpc_server(apis: Vec<&str>, deps: &Dependencies) -> Server { let apis = rpc_apis::from_str(apis); let server = Server::new(); @@ -109,10 +110,18 @@ pub fn setup_http_rpc_server( }, } } + #[cfg(not(feature = "rpc"))] pub fn setup_ipc_rpc_server(_dependencies: &Dependencies, _addr: &str, _apis: Vec<&str>) -> ! { die!("Your Parity version has been compiled without JSON-RPC support.") } + +pub fn new_ipc(conf: IpcConfiguration, deps: &Dependencies) -> Option { + if !conf.enabled { return None; } + let apis = conf.apis.split(',').collect(); + Some(setup_ipc_rpc_server(deps, &conf.socket_addr, apis)) +} + #[cfg(feature = "rpc")] pub fn setup_ipc_rpc_server(dependencies: &Dependencies, addr: &str, apis: Vec<&str>) -> jsonipc::Server { let server = setup_rpc_server(apis, dependencies); diff --git a/parity/rpc_apis.rs b/parity/rpc_apis.rs index d9085fc31..c0daaa926 100644 --- a/parity/rpc_apis.rs +++ b/parity/rpc_apis.rs @@ -23,8 +23,9 @@ use ethsync::EthSync; use ethcore::miner::{Miner, ExternalMiner}; use ethcore::client::Client; use util::RotatingLogger; -use util::keys::store::AccountService; +use ethcore::account_provider::AccountProvider; use util::network_settings::NetworkSettings; +use util::network::NetworkService; #[cfg(feature="rpc")] pub use ethcore_rpc::ConfirmationsQueue; @@ -83,11 +84,13 @@ pub struct Dependencies { pub signer_queue: Arc, pub client: Arc, pub sync: Arc, - pub secret_store: Arc, + pub secret_store: Arc, pub miner: Arc, pub external_miner: Arc, pub logger: Arc, pub settings: Arc, + pub allow_pending_receipt_query: bool, + pub net_service: Arc>, } fn to_modules(apis: &[Api]) -> BTreeMap { @@ -122,10 +125,10 @@ fn list_apis(apis: ApiSet) -> Vec { match apis { ApiSet::List(apis) => apis, ApiSet::UnsafeContext => { - vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Ethcore, Api::EthcoreSet, Api::Traces, Api::Rpc] + vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Ethcore, Api::Traces, Api::Rpc] }, _ => { - vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Signer, Api::Ethcore, Api::EthcoreSet, Api::Traces, Api::Rpc] + vec![Api::Web3, Api::Net, Api::Eth, Api::Personal, Api::Signer, Api::Ethcore, Api::Traces, Api::Rpc] }, } } @@ -143,11 +146,11 @@ pub fn setup_rpc(server: T, deps: Arc, apis: ApiSet server.add_delegate(NetClient::new(&deps.sync).to_delegate()); }, Api::Eth => { - server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner).to_delegate()); + server.add_delegate(EthClient::new(&deps.client, &deps.sync, &deps.secret_store, &deps.miner, &deps.external_miner, deps.allow_pending_receipt_query).to_delegate()); server.add_delegate(EthFilterClient::new(&deps.client, &deps.miner).to_delegate()); if deps.signer_port.is_some() { - server.add_delegate(EthSigningQueueClient::new(&deps.signer_queue).to_delegate()); + server.add_delegate(EthSigningQueueClient::new(&deps.signer_queue, &deps.client, &deps.miner, &deps.secret_store).to_delegate()); } else { server.add_delegate(EthSigningUnsafeClient::new(&deps.client, &deps.secret_store, &deps.miner).to_delegate()); } @@ -159,10 +162,11 @@ pub fn setup_rpc(server: T, deps: Arc, apis: ApiSet server.add_delegate(SignerClient::new(&deps.secret_store, &deps.client, &deps.miner, &deps.signer_queue).to_delegate()); }, Api::Ethcore => { - server.add_delegate(EthcoreClient::new(&deps.miner, deps.logger.clone(), deps.settings.clone()).to_delegate()) + let queue = deps.signer_port.map(|_| deps.signer_queue.clone()); + server.add_delegate(EthcoreClient::new(&deps.client, &deps.miner, deps.logger.clone(), deps.settings.clone(), queue).to_delegate()) }, Api::EthcoreSet => { - server.add_delegate(EthcoreSetClient::new(&deps.miner).to_delegate()) + server.add_delegate(EthcoreSetClient::new(&deps.miner, &deps.net_service).to_delegate()) }, Api::Traces => { server.add_delegate(TracesClient::new(&deps.client, &deps.miner).to_delegate()) diff --git a/parity/signer.rs b/parity/signer.rs index f8ff699df..f15d8c97b 100644 --- a/parity/signer.rs +++ b/parity/signer.rs @@ -14,11 +14,13 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +extern crate ansi_term; +use self::ansi_term::Colour::White; use std::io; use std::path::PathBuf; use std::sync::Arc; use util::panics::{PanicHandler, ForwardPanic}; -use util::keys::directory::restrict_permissions_owner; +use util::path::restrict_permissions_owner; use die::*; use rpc_apis; @@ -65,8 +67,7 @@ pub fn new_token(path: String) -> io::Result<()> { let mut codes = try!(signer::AuthCodes::from_file(&path)); let code = try!(codes.generate_new()); try!(codes.to_file(&path)); - println!("New token has been generated. Copy the code below to your Signer UI:"); - println!("{}", code); + println!("This key code will authorise your System Signer UI: {}", White.bold().paint(code)); Ok(()) } diff --git a/parity/url.rs b/parity/url.rs new file mode 100644 index 000000000..129812387 --- /dev/null +++ b/parity/url.rs @@ -0,0 +1,59 @@ +// 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 . + +//! Cross-platform open url in default browser + +#[cfg(windows)] +mod shell { + extern crate winapi; + + use self::winapi::*; + extern "system" { + pub fn ShellExecuteA( + hwnd: HWND, lpOperation: LPCSTR, lpFile: LPCSTR, lpParameters: LPCSTR, lpDirectory: LPCSTR, + nShowCmd: c_int + ) -> HINSTANCE; + } + + pub use self::winapi::SW_SHOWNORMAL as Normal; +} + +#[cfg(windows)] +pub fn open(url: &str) { + use std::ffi::CString; + use std::ptr; + + unsafe { + shell::ShellExecuteA(ptr::null_mut(), + CString::new("open").unwrap().as_ptr(), + CString::new(url.to_owned().replace("\n", "%0A")).unwrap().as_ptr(), + ptr::null(), + ptr::null(), + shell::Normal); + } +} + +#[cfg(target_os="macos")] +pub fn open(url: &str) { + use std; + let _ = std::process::Command::new("open").arg(url).spawn(); +} + +#[cfg(target_os="linux")] +pub fn open(url: &str) { + use std; + let _ = std::process::Command::new("xdg-open").arg(url).spawn(); +} diff --git a/rpc/Cargo.toml b/rpc/Cargo.toml index b1369c88d..21a59ad50 100644 --- a/rpc/Cargo.toml +++ b/rpc/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Ethcore jsonrpc" name = "ethcore-rpc" -version = "1.2.0" +version = "1.3.0" license = "GPL-3.0" authors = ["Ethcore "] diff --git a/rpc/rpctest/src/main.rs b/rpc/rpctest/src/main.rs index 6cc747959..139514cb1 100644 --- a/rpc/rpctest/src/main.rs +++ b/rpc/rpctest/src/main.rs @@ -123,7 +123,7 @@ impl Configuration { accs.insert(Address::from(1), TestAccount::new("test")); let accounts = Arc::new(TestAccountProvider::new(accs)); let server = rpc::RpcServer::new(); - server.add_delegate(EthClient::new(&client, &sync, &accounts, &miner).to_delegate()); + server.add_delegate(EthClient::new(&client, &sync, &accounts, &miner, true).to_delegate()); server.add_delegate(EthFilterClient::new(&client, &miner).to_delegate()); let url = format!("{}:{}", self.args.flag_jsonrpc_addr, self.args.flag_jsonrpc_port); diff --git a/rpc/src/v1/helpers/signing_queue.rs b/rpc/src/v1/helpers/signing_queue.rs index 0ded8998c..3d7f9e35b 100644 --- a/rpc/src/v1/helpers/signing_queue.rs +++ b/rpc/src/v1/helpers/signing_queue.rs @@ -19,8 +19,11 @@ use std::time::{Instant, Duration}; use std::sync::{mpsc, Mutex, RwLock, Arc}; use std::collections::HashMap; use v1::types::{TransactionRequest, TransactionConfirmation}; -use util::{U256, H256}; +use util::U256; +use jsonrpc_core; +/// Result that can be returned from JSON RPC. +pub type RpcResult = Result; /// Possible events happening in the queue that can be listened to. #[derive(Debug, PartialEq)] @@ -59,13 +62,19 @@ pub trait SigningQueue: Send + Sync { /// Removes a request from the queue. /// Notifies possible token holders that transaction was confirmed and given hash was assigned. - fn request_confirmed(&self, id: U256, hash: H256) -> Option; + fn request_confirmed(&self, id: U256, result: RpcResult) -> Option; /// Returns a request if it is contained in the queue. fn peek(&self, id: &U256) -> Option; /// Return copy of all the requests in the queue. fn requests(&self) -> Vec; + + /// Returns number of transactions awaiting confirmation. + fn len(&self) -> usize; + + /// Returns true if there are no transactions awaiting confirmation. + fn is_empty(&self) -> bool; } #[derive(Debug, PartialEq)] @@ -75,7 +84,7 @@ enum ConfirmationResult { /// The transaction has been rejected. Rejected, /// The transaction has been confirmed. - Confirmed(H256), + Confirmed(RpcResult), } /// Time you need to confirm the transaction in UI. @@ -100,7 +109,7 @@ pub struct ConfirmationPromise { impl ConfirmationToken { /// Submit solution to all listeners - fn resolve(&self, result: Option) { + fn resolve(&self, result: Option) { let mut res = self.result.lock().unwrap(); *res = result.map_or(ConfirmationResult::Rejected, |h| ConfirmationResult::Confirmed(h)); // Notify listener @@ -119,8 +128,8 @@ impl ConfirmationPromise { /// Blocks current thread and awaits for /// resolution of the transaction (rejected / confirmed) /// Returns `None` if transaction was rejected or timeout reached. - /// Returns `Some(hash)` if transaction was confirmed. - pub fn wait_with_timeout(&self) -> Option { + /// Returns `Some(result)` if transaction was confirmed. + pub fn wait_with_timeout(&self) -> Option { let timeout = Duration::from_secs(QUEUE_TIMEOUT_DURATION_SEC); let deadline = Instant::now() + timeout; @@ -137,7 +146,7 @@ impl ConfirmationPromise { // Check the result match *res { ConfirmationResult::Rejected => return None, - ConfirmationResult::Confirmed(h) => return Some(h), + ConfirmationResult::Confirmed(ref h) => return Some(h.clone()), ConfirmationResult::Waiting => continue, } } @@ -204,12 +213,12 @@ impl ConfirmationsQueue { /// Removes transaction from this queue and notifies `ConfirmationPromise` holders about the result. /// Notifies also a receiver about that event. - fn remove(&self, id: U256, result: Option) -> Option { + fn remove(&self, id: U256, result: Option) -> Option { let token = self.queue.write().unwrap().remove(&id); if let Some(token) = token { // notify receiver about the event - self.notify(result.map_or_else( + self.notify(result.clone().map_or_else( || QueueEvent::RequestRejected(id), |_| QueueEvent::RequestConfirmed(id) )); @@ -265,15 +274,25 @@ impl SigningQueue for ConfirmationsQueue { self.remove(id, None) } - fn request_confirmed(&self, id: U256, hash: H256) -> Option { + fn request_confirmed(&self, id: U256, result: RpcResult) -> Option { debug!(target: "own_tx", "Signer: Transaction confirmed ({:?}).", id); - self.remove(id, Some(hash)) + self.remove(id, Some(result)) } fn requests(&self) -> Vec { let queue = self.queue.read().unwrap(); queue.values().map(|token| token.request.clone()).collect() } + + fn len(&self) -> usize { + let queue = self.queue.read().unwrap(); + queue.len() + } + + fn is_empty(&self) -> bool { + let queue = self.queue.read().unwrap(); + queue.is_empty() + } } @@ -286,6 +305,7 @@ mod test { use util::numbers::{U256, H256}; use v1::types::TransactionRequest; use super::*; + use jsonrpc_core::to_value; fn request() -> TransactionRequest { TransactionRequest { @@ -317,10 +337,10 @@ mod test { // Just wait for the other thread to start thread::sleep(Duration::from_millis(100)); } - queue.request_confirmed(id, H256::from(1)); + queue.request_confirmed(id, to_value(&H256::from(1))); // then - assert_eq!(handle.join().expect("Thread should finish nicely"), H256::from(1)); + assert_eq!(handle.join().expect("Thread should finish nicely"), to_value(&H256::from(1))); } #[test] diff --git a/rpc/src/v1/impls/eth.rs b/rpc/src/v1/impls/eth.rs index b0d6abcf0..05dc89564 100644 --- a/rpc/src/v1/impls/eth.rs +++ b/rpc/src/v1/impls/eth.rs @@ -18,6 +18,8 @@ extern crate ethash; +use std::thread; +use std::time::{Instant, Duration}; use std::sync::{Arc, Weak, Mutex}; use std::ops::Deref; use ethsync::{SyncProvider, SyncState}; @@ -26,7 +28,7 @@ use jsonrpc_core::*; use util::numbers::*; use util::sha3::*; use util::rlp::{encode, decode, UntrustedRlp, View}; -use util::keys::store::AccountProvider; +use ethcore::account_provider::AccountProvider; use ethcore::client::{MiningBlockChainClient, BlockID, TransactionID, UncleID}; use ethcore::block::IsBlock; use ethcore::views::*; @@ -37,35 +39,34 @@ use ethcore::filter::Filter as EthcoreFilter; use self::ethash::SeedHashCompute; use v1::traits::Eth; use v1::types::{Block, BlockTransactions, BlockNumber, Bytes, SyncStatus, SyncInfo, Transaction, CallRequest, OptionalValue, Index, Filter, Log, Receipt}; -use v1::impls::dispatch_transaction; +use v1::impls::{default_gas_price, dispatch_transaction, error_codes}; use serde; /// Eth rpc implementation. -pub struct EthClient where +pub struct EthClient where C: MiningBlockChainClient, S: SyncProvider, - A: AccountProvider, M: MinerService, EM: ExternalMinerService { client: Weak, sync: Weak, - accounts: Weak, + accounts: Weak, miner: Weak, external_miner: Arc, seed_compute: Mutex, + allow_pending_receipt_query: bool, } -impl EthClient where +impl EthClient where C: MiningBlockChainClient, S: SyncProvider, - A: AccountProvider, M: MinerService, EM: ExternalMinerService { /// Creates new EthClient. - pub fn new(client: &Arc, sync: &Arc, accounts: &Arc, miner: &Arc, em: &Arc) - -> EthClient { + pub fn new(client: &Arc, sync: &Arc, accounts: &Arc, miner: &Arc, em: &Arc, allow_pending_receipt_query: bool) + -> EthClient { EthClient { client: Arc::downgrade(client), sync: Arc::downgrade(sync), @@ -73,6 +74,7 @@ impl EthClient where accounts: Arc::downgrade(accounts), external_miner: em.clone(), seed_compute: Mutex::new(SeedHashCompute::new()), + allow_pending_receipt_query: allow_pending_receipt_query, } } @@ -154,14 +156,13 @@ impl EthClient where } fn sign_call(&self, request: CallRequest) -> Result { - let client = take_weak!(self.client); - let miner = take_weak!(self.miner); + let (client, miner) = (take_weak!(self.client), take_weak!(self.miner)); let from = request.from.unwrap_or(Address::zero()); Ok(EthTransaction { nonce: request.nonce.unwrap_or_else(|| client.latest_nonce(&from)), action: request.to.map_or(Action::Create, Action::Call), gas: request.gas.unwrap_or(U256::from(50_000_000)), - gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()), + gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(&*client, &*miner)), value: request.value.unwrap_or_else(U256::zero), data: request.data.map_or_else(Vec::new, |d| d.to_vec()) }.fake_sign(from)) @@ -210,21 +211,33 @@ fn from_params_default_third(params: Params) -> Result<(F1, F2, BlockNum } } -// must be in range [-32099, -32000] -const UNSUPPORTED_REQUEST_CODE: i64 = -32000; - fn make_unsupported_err() -> Error { Error { - code: ErrorCode::ServerError(UNSUPPORTED_REQUEST_CODE), + code: ErrorCode::ServerError(error_codes::UNSUPPORTED_REQUEST_CODE), message: "Unsupported request.".into(), data: None } } -impl Eth for EthClient where +fn no_work_err() -> Error { + Error { + code: ErrorCode::ServerError(error_codes::NO_WORK_CODE), + message: "Still syncing.".into(), + data: None + } +} + +fn no_author_err() -> Error { + Error { + code: ErrorCode::ServerError(error_codes::NO_AUTHOR_CODE), + message: "Author not configured. Run parity with --author to configure.".into(), + data: None + } +} + +impl Eth for EthClient where C: MiningBlockChainClient + 'static, S: SyncProvider + 'static, - A: AccountProvider + 'static, M: MinerService + 'static, EM: ExternalMinerService + 'static { @@ -284,17 +297,17 @@ impl Eth for EthClient where fn gas_price(&self, params: Params) -> Result { match params { - Params::None => to_value(&take_weak!(self.miner).sensible_gas_price()), + Params::None => { + let (client, miner) = (take_weak!(self.client), take_weak!(self.miner)); + to_value(&default_gas_price(&*client, &*miner)) + } _ => Err(Error::invalid_params()) } } fn accounts(&self, _: Params) -> Result { let store = take_weak!(self.accounts); - match store.accounts() { - Ok(account_list) => to_value(&account_list), - Err(_) => Err(Error::internal_error()) - } + to_value(&store.accounts()) } fn block_number(&self, params: Params) -> Result { @@ -408,9 +421,15 @@ impl Eth for EthClient where fn transaction_receipt(&self, params: Params) -> Result { from_params::<(H256,)>(params) .and_then(|(hash,)| { - let client = take_weak!(self.client); - let receipt = client.transaction_receipt(TransactionID::Hash(hash)); - to_value(&receipt.map(Receipt::from)) + let miner = take_weak!(self.miner); + match miner.pending_receipts().get(&hash) { + Some(receipt) if self.allow_pending_receipt_query => to_value(&Receipt::from(receipt.clone())), + _ => { + let client = take_weak!(self.client); + let receipt = client.transaction_receipt(TransactionID::Hash(hash)); + to_value(&receipt.map(Receipt::from)) + } + } }) } @@ -460,11 +479,21 @@ impl Eth for EthClient where //let sync = take_weak!(self.sync); if /*sync.status().state != SyncState::Idle ||*/ client.queue_info().total_queue_size() > MAX_QUEUE_SIZE_TO_MINE_ON { trace!(target: "miner", "Syncing. Cannot give any work."); - return to_value(&(String::new(), String::new(), String::new())); + return Err(no_work_err()); + } + + // Otherwise spin until our submitted block has been included. + let timeout = Instant::now() + Duration::from_millis(1000); + while Instant::now() < timeout && client.queue_info().total_queue_size() > 0 { + thread::sleep(Duration::from_millis(1)); } } let miner = take_weak!(self.miner); + if miner.author().is_zero() { + warn!(target: "miner", "Cannot give work package - no author is configured. Use --author to configure!"); + return Err(no_author_err()) + } miner.map_sealing_work(client.deref(), |b| { let pow_hash = b.hash(); let target = Ethash::difficulty_to_boundary(b.block().header().difficulty()); @@ -499,7 +528,7 @@ impl Eth for EthClient where .and_then(|(raw_transaction, )| { let raw_transaction = raw_transaction.to_vec(); match UntrustedRlp::new(&raw_transaction).as_val() { - Ok(signed_transaction) => to_value(&dispatch_transaction(&*take_weak!(self.client), &*take_weak!(self.miner), signed_transaction)), + Ok(signed_transaction) => dispatch_transaction(&*take_weak!(self.client), &*take_weak!(self.miner), signed_transaction), Err(_) => to_value(&H256::zero()), } }) diff --git a/rpc/src/v1/impls/eth_signing.rs b/rpc/src/v1/impls/eth_signing.rs index f8c3c343d..fa4330f46 100644 --- a/rpc/src/v1/impls/eth_signing.rs +++ b/rpc/src/v1/impls/eth_signing.rs @@ -21,62 +21,96 @@ use jsonrpc_core::*; use ethcore::miner::MinerService; use ethcore::client::MiningBlockChainClient; use util::numbers::*; -use util::keys::store::AccountProvider; +use ethcore::account_provider::AccountProvider; use v1::helpers::{SigningQueue, ConfirmationsQueue}; use v1::traits::EthSigning; -use v1::types::TransactionRequest; -use v1::impls::sign_and_dispatch; +use v1::types::{TransactionRequest, Bytes}; +use v1::impls::{default_gas_price, sign_and_dispatch}; - -/// Implementation of functions that require signing when no trusted signer is used. -pub struct EthSigningQueueClient { - queue: Weak, +fn fill_optional_fields(request: &mut TransactionRequest, client: &C, miner: &M) + where C: MiningBlockChainClient, M: MinerService { + if request.value.is_none() { + request.value = Some(U256::zero()); + } + if request.gas.is_none() { + request.gas = Some(miner.sensible_gas_limit()); + } + if request.gas_price.is_none() { + request.gas_price = Some(default_gas_price(client, miner)); + } + if request.data.is_none() { + request.data = Some(Bytes::new(Vec::new())); + } } -impl EthSigningQueueClient { +/// Implementation of functions that require signing when no trusted signer is used. +pub struct EthSigningQueueClient where C: MiningBlockChainClient, M: MinerService { + queue: Weak, + accounts: Weak, + client: Weak, + miner: Weak, +} + +impl EthSigningQueueClient where C: MiningBlockChainClient, M: MinerService { /// Creates a new signing queue client given shared signing queue. - pub fn new(queue: &Arc) -> Self { + pub fn new(queue: &Arc, client: &Arc, miner: &Arc, accounts: &Arc) -> Self { EthSigningQueueClient { queue: Arc::downgrade(queue), + accounts: Arc::downgrade(accounts), + client: Arc::downgrade(client), + miner: Arc::downgrade(miner), } } } -impl EthSigning for EthSigningQueueClient { +impl EthSigning for EthSigningQueueClient + where C: MiningBlockChainClient + 'static, M: MinerService + 'static +{ fn sign(&self, _params: Params) -> Result { + warn!("Invoking eth_sign is not yet supported with signer enabled."); // TODO [ToDr] Implement sign when rest of the signing queue is ready. rpc_unimplemented!() } fn send_transaction(&self, params: Params) -> Result { from_params::<(TransactionRequest, )>(params) - .and_then(|(request, )| { + .and_then(|(mut request, )| { + let accounts = take_weak!(self.accounts); + let (client, miner) = (take_weak!(self.client), take_weak!(self.miner)); + + if accounts.is_unlocked(request.from) { + let sender = request.from; + return match sign_and_dispatch(&*client, &*miner, request, &*accounts, sender) { + Ok(hash) => to_value(&hash), + _ => to_value(&H256::zero()), + } + } + let queue = take_weak!(self.queue); + fill_optional_fields(&mut request, &*client, &*miner); let id = queue.add_request(request); let result = id.wait_with_timeout(); - to_value(&result.unwrap_or_else(H256::new)) + result.unwrap_or_else(|| to_value(&H256::new())) }) } } /// Implementation of functions that require signing when no trusted signer is used. -pub struct EthSigningUnsafeClient where +pub struct EthSigningUnsafeClient where C: MiningBlockChainClient, - A: AccountProvider, M: MinerService { client: Weak, - accounts: Weak, + accounts: Weak, miner: Weak, } -impl EthSigningUnsafeClient where +impl EthSigningUnsafeClient where C: MiningBlockChainClient, - A: AccountProvider, M: MinerService { /// Creates new EthClient. - pub fn new(client: &Arc, accounts: &Arc, miner: &Arc) + pub fn new(client: &Arc, accounts: &Arc, miner: &Arc) -> Self { EthSigningUnsafeClient { client: Arc::downgrade(client), @@ -86,26 +120,24 @@ impl EthSigningUnsafeClient where } } -impl EthSigning for EthSigningUnsafeClient where +impl EthSigning for EthSigningUnsafeClient where C: MiningBlockChainClient + 'static, - A: AccountProvider + 'static, M: MinerService + 'static { fn sign(&self, params: Params) -> Result { from_params::<(Address, H256)>(params).and_then(|(addr, msg)| { - to_value(&take_weak!(self.accounts).sign(&addr, &msg).unwrap_or(H520::zero())) + to_value(&take_weak!(self.accounts).sign(addr, msg).unwrap_or(H520::zero())) }) } fn send_transaction(&self, params: Params) -> Result { from_params::<(TransactionRequest, )>(params) .and_then(|(request, )| { - let accounts = take_weak!(self.accounts); - match accounts.account_secret(&request.from) { - Ok(secret) => to_value(&sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret)), - Err(_) => to_value(&H256::zero()) + let sender = request.from; + match sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, &*take_weak!(self.accounts), sender) { + Ok(hash) => to_value(&hash), + _ => to_value(&H256::zero()), } }) } - } diff --git a/rpc/src/v1/impls/ethcore.rs b/rpc/src/v1/impls/ethcore.rs index b3fe894c6..3a58d8672 100644 --- a/rpc/src/v1/impls/ethcore.rs +++ b/rpc/src/v1/impls/ethcore.rs @@ -15,38 +15,46 @@ // along with Parity. If not, see . //! Ethcore-specific rpc implementation. -use util::RotatingLogger; +use util::{RotatingLogger}; use util::network_settings::NetworkSettings; use util::misc::version_data; use std::sync::{Arc, Weak}; use std::ops::Deref; -use std::collections::BTreeMap; +use std::collections::{BTreeMap}; +use ethcore::client::{MiningBlockChainClient}; use jsonrpc_core::*; use ethcore::miner::MinerService; use v1::traits::Ethcore; use v1::types::{Bytes}; +use v1::helpers::{SigningQueue, ConfirmationsQueue}; +use v1::impls::error_codes; /// Ethcore implementation. -pub struct EthcoreClient where +pub struct EthcoreClient where + C: MiningBlockChainClient, M: MinerService { + client: Weak, miner: Weak, logger: Arc, settings: Arc, + confirmations_queue: Option>, } -impl EthcoreClient where M: MinerService { +impl EthcoreClient where C: MiningBlockChainClient, M: MinerService { /// Creates new `EthcoreClient`. - pub fn new(miner: &Arc, logger: Arc, settings: Arc) -> Self { + pub fn new(client: &Arc, miner: &Arc, logger: Arc, settings: Arc, queue: Option>) -> Self { EthcoreClient { + client: Arc::downgrade(client), miner: Arc::downgrade(miner), logger: logger, settings: settings, + confirmations_queue: queue, } } } -impl Ethcore for EthcoreClient where M: MinerService + 'static { +impl Ethcore for EthcoreClient where M: MinerService + 'static, C: MiningBlockChainClient + 'static { fn transactions_limit(&self, _: Params) -> Result { to_value(&take_weak!(self.miner).transactions_limit()) @@ -64,6 +72,10 @@ impl Ethcore for EthcoreClient where M: MinerService + 'static { to_value(&take_weak!(self.miner).gas_floor_target()) } + fn gas_ceil_target(&self, _: Params) -> Result { + to_value(&take_weak!(self.miner).gas_ceil_target()) + } + fn dev_logs(&self, _params: Params) -> Result { let logs = self.logger.logs(); to_value(&logs.deref().as_slice()) @@ -97,8 +109,34 @@ impl Ethcore for EthcoreClient where M: MinerService + 'static { Ok(Value::Object(map)) } - fn default_extra_data(&self, _params: Params) -> Result { - let version = version_data(); - to_value(&Bytes::new(version)) + fn default_extra_data(&self, params: Params) -> Result { + match params { + Params::None => to_value(&Bytes::new(version_data())), + _ => Err(Error::invalid_params()), + } + } + + fn gas_price_statistics(&self, params: Params) -> Result { + match params { + Params::None => match take_weak!(self.client).gas_price_statistics(100, 8) { + Ok(stats) => to_value(&stats + .iter() + .map(|x| to_value(&x).expect("x must be U256; qed")) + .collect::>()), + _ => Err(Error::internal_error()), + }, + _ => Err(Error::invalid_params()), + } + } + + fn unsigned_transactions_count(&self, _params: Params) -> Result { + match self.confirmations_queue { + None => Err(Error { + code: ErrorCode::ServerError(error_codes::SIGNER_DISABLED), + message: "Trusted Signer is disabled. This API is not available.".into(), + data: None + }), + Some(ref queue) => to_value(&queue.len()), + } } } diff --git a/rpc/src/v1/impls/ethcore_set.rs b/rpc/src/v1/impls/ethcore_set.rs index b07dcbf9e..baf5bf134 100644 --- a/rpc/src/v1/impls/ethcore_set.rs +++ b/rpc/src/v1/impls/ethcore_set.rs @@ -16,24 +16,28 @@ /// Ethcore-specific rpc interface for operations altering the settings. use util::{U256, Address}; +use util::network::{NetworkService, NonReservedPeerMode}; use std::sync::{Arc, Weak}; use jsonrpc_core::*; use ethcore::miner::MinerService; +use ethcore::service::SyncMessage; use v1::traits::EthcoreSet; -use v1::types::{Bytes}; +use v1::types::Bytes; /// Ethcore-specific rpc interface for operations altering the settings. pub struct EthcoreSetClient where M: MinerService { miner: Weak, + net: Weak>, } impl EthcoreSetClient where M: MinerService { /// Creates new `EthcoreSetClient`. - pub fn new(miner: &Arc) -> Self { + pub fn new(miner: &Arc, net: &Arc>) -> Self { EthcoreSetClient { miner: Arc::downgrade(miner), + net: Arc::downgrade(net), } } } @@ -48,8 +52,15 @@ impl EthcoreSet for EthcoreSetClient where M: MinerService + 'static { } fn set_gas_floor_target(&self, params: Params) -> Result { - from_params::<(U256,)>(params).and_then(|(gas_floor_target,)| { - take_weak!(self.miner).set_gas_floor_target(gas_floor_target); + from_params::<(U256,)>(params).and_then(|(target,)| { + take_weak!(self.miner).set_gas_floor_target(target); + to_value(&true) + }) + } + + fn set_gas_ceil_target(&self, params: Params) -> Result { + from_params::<(U256,)>(params).and_then(|(target,)| { + take_weak!(self.miner).set_gas_ceil_target(target); to_value(&true) }) } @@ -75,4 +86,38 @@ impl EthcoreSet for EthcoreSetClient where M: MinerService + 'static { }) } + fn set_tx_gas_limit(&self, params: Params) -> Result { + from_params::<(U256,)>(params).and_then(|(limit,)| { + take_weak!(self.miner).set_tx_gas_limit(limit.into()); + to_value(&true) + }) + } + + fn add_reserved_peer(&self, params: Params) -> Result { + from_params::<(String,)>(params).and_then(|(peer,)| { + match take_weak!(self.net).add_reserved_peer(&peer) { + Ok(()) => to_value(&true), + Err(_) => Err(Error::invalid_params()), + } + }) + } + + fn remove_reserved_peer(&self, params: Params) -> Result { + from_params::<(String,)>(params).and_then(|(peer,)| { + match take_weak!(self.net).remove_reserved_peer(&peer) { + Ok(()) => to_value(&true), + Err(_) => Err(Error::invalid_params()), + } + }) + } + + fn drop_non_reserved_peers(&self, _: Params) -> Result { + take_weak!(self.net).set_non_reserved_mode(NonReservedPeerMode::Deny); + to_value(&true) + } + + fn accept_non_reserved_peers(&self, _: Params) -> Result { + take_weak!(self.net).set_non_reserved_mode(NonReservedPeerMode::Accept); + to_value(&true) + } } diff --git a/rpc/src/v1/impls/mod.rs b/rpc/src/v1/impls/mod.rs index 7fdf57249..fdd2de8fa 100644 --- a/rpc/src/v1/impls/mod.rs +++ b/rpc/src/v1/impls/mod.rs @@ -54,14 +54,28 @@ pub use self::traces::TracesClient; pub use self::rpc::RpcClient; use v1::types::TransactionRequest; +use ethcore::error::Error as EthcoreError; use ethcore::miner::{AccountDetails, MinerService}; use ethcore::client::MiningBlockChainClient; use ethcore::transaction::{Action, SignedTransaction, Transaction}; +use ethcore::account_provider::{AccountProvider, Error as AccountError}; use util::numbers::*; use util::rlp::encode; use util::bytes::ToPretty; +use jsonrpc_core::{Error, ErrorCode, Value, to_value}; -fn dispatch_transaction(client: &C, miner: &M, signed_transaction: SignedTransaction) -> H256 +mod error_codes { + // NOTE [ToDr] Codes from [-32099, -32000] + pub const UNSUPPORTED_REQUEST_CODE: i64 = -32000; + pub const NO_WORK_CODE: i64 = -32001; + pub const NO_AUTHOR_CODE: i64 = -32002; + pub const UNKNOWN_ERROR: i64 = -32009; + pub const TRANSACTION_ERROR: i64 = -32010; + pub const ACCOUNT_LOCKED: i64 = -32020; + pub const SIGNER_DISABLED: i64 = -32030; +} + +fn dispatch_transaction(client: &C, miner: &M, signed_transaction: SignedTransaction) -> Result where C: MiningBlockChainClient, M: MinerService { let hash = signed_transaction.hash(); @@ -72,28 +86,106 @@ fn dispatch_transaction(client: &C, miner: &M, signed_transaction: SignedT } }); - import.map(|_| hash).unwrap_or(H256::zero()) + import + .map_err(transaction_error) + .and_then(|_| to_value(&hash)) } -fn sign_and_dispatch(client: &C, miner: &M, request: TransactionRequest, secret: H256) -> H256 +fn prepare_transaction(client: &C, miner: &M, request: TransactionRequest) -> Transaction where C: MiningBlockChainClient, M: MinerService { + Transaction { + nonce: request.nonce + .or_else(|| miner + .last_nonce(&request.from) + .map(|nonce| nonce + U256::one())) + .unwrap_or_else(|| client.latest_nonce(&request.from)), + + action: request.to.map_or(Action::Create, Action::Call), + gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()), + gas_price: request.gas_price.unwrap_or_else(|| default_gas_price(client, miner)), + value: request.value.unwrap_or_else(U256::zero), + data: request.data.map_or_else(Vec::new, |b| b.to_vec()), + } +} + +fn unlock_sign_and_dispatch(client: &C, miner: &M, request: TransactionRequest, account_provider: &AccountProvider, address: Address, password: String) -> Result where C: MiningBlockChainClient, M: MinerService { let signed_transaction = { - Transaction { - nonce: request.nonce - .or_else(|| miner - .last_nonce(&request.from) - .map(|nonce| nonce + U256::one())) - .unwrap_or_else(|| client.latest_nonce(&request.from)), - - action: request.to.map_or(Action::Create, Action::Call), - gas: request.gas.unwrap_or_else(|| miner.sensible_gas_limit()), - gas_price: request.gas_price.unwrap_or_else(|| miner.sensible_gas_price()), - value: request.value.unwrap_or_else(U256::zero), - data: request.data.map_or_else(Vec::new, |b| b.to_vec()), - }.sign(&secret) + let t = prepare_transaction(client, miner, request); + let hash = t.hash(); + let signature = try!(account_provider.sign_with_password(address, password, hash).map_err(signing_error)); + t.with_signature(signature) }; trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty()); dispatch_transaction(&*client, &*miner, signed_transaction) } + +fn sign_and_dispatch(client: &C, miner: &M, request: TransactionRequest, account_provider: &AccountProvider, address: Address) -> Result + where C: MiningBlockChainClient, M: MinerService { + + let signed_transaction = { + let t = prepare_transaction(client, miner, request); + let hash = t.hash(); + let signature = try!(account_provider.sign(address, hash).map_err(signing_error)); + t.with_signature(signature) + }; + + trace!(target: "miner", "send_transaction: dispatching tx: {}", encode(&signed_transaction).to_vec().pretty()); + dispatch_transaction(&*client, &*miner, signed_transaction) +} + +fn default_gas_price(client: &C, miner: &M) -> U256 where C: MiningBlockChainClient, M: MinerService { + client + .gas_price_statistics(100, 8) + .map(|x| x[4]) + .unwrap_or_else(|_| miner.sensible_gas_price()) +} + + +fn signing_error(error: AccountError) -> Error { + Error { + code: ErrorCode::ServerError(error_codes::ACCOUNT_LOCKED), + message: "Your account is locked. Unlock the account via CLI, personal_unlockAccount or use Trusted Signer.".into(), + data: Some(Value::String(format!("{:?}", error))), + } +} + +fn transaction_error(error: EthcoreError) -> Error { + use ethcore::error::TransactionError::*; + + if let EthcoreError::Transaction(e) = error { + let msg = match e { + AlreadyImported => "Transaction with the same hash was already imported.".into(), + Old => "Transaction nonce is too low. Try incrementing the nonce.".into(), + TooCheapToReplace => { + "Transaction fee is too low. There is another transaction with same nonce in the queue. Try increasing the fee or incrementing the nonce.".into() + }, + LimitReached => { + "There is too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.".into() + }, + InsufficientGasPrice { minimal, got } => { + format!("Transaction fee is to low. It does not satisfy your node's minimal fee (minimal: {}, got: {}). Try increasing the fee.", minimal, got) + }, + InsufficientBalance { balance, cost } => { + format!("Insufficient funds. Account you try to send transaction from does not have enough funds. Required {} and got: {}.", cost, balance) + }, + GasLimitExceeded { limit, got } => { + format!("Transaction cost exceeds current gas limit. Limit: {}, got: {}. Try decreasing supplied gas.", limit, got) + }, + InvalidGasLimit(_) => "Supplied gas is beyond limit.".into(), + DAORescue => "Transaction removes funds from a DAO.".into(), + }; + Error { + code: ErrorCode::ServerError(error_codes::TRANSACTION_ERROR), + message: msg, + data: None, + } + } else { + Error { + code: ErrorCode::ServerError(error_codes::UNKNOWN_ERROR), + message: "Unknown error when sending transaction.".into(), + data: Some(Value::String(format!("{:?}", error))), + } + } +} diff --git a/rpc/src/v1/impls/net.rs b/rpc/src/v1/impls/net.rs index fb502e6cf..977561ede 100644 --- a/rpc/src/v1/impls/net.rs +++ b/rpc/src/v1/impls/net.rs @@ -47,4 +47,14 @@ impl Net for NetClient where S: SyncProvider + 'static { // right now (11 march 2016), we are always listening for incoming connections Ok(Value::Bool(true)) } + + fn start_network(&self, _: Params) -> Result { + take_weak!(self.sync).start_network(); + Ok(Value::Bool(true)) + } + + fn stop_network(&self, _: Params) -> Result { + take_weak!(self.sync).stop_network(); + Ok(Value::Bool(true)) + } } diff --git a/rpc/src/v1/impls/personal.rs b/rpc/src/v1/impls/personal.rs index c62c71453..38191ed90 100644 --- a/rpc/src/v1/impls/personal.rs +++ b/rpc/src/v1/impls/personal.rs @@ -19,25 +19,23 @@ use std::sync::{Arc, Weak}; use jsonrpc_core::*; use v1::traits::Personal; use v1::types::TransactionRequest; -use v1::impls::sign_and_dispatch; -use util::keys::store::AccountProvider; +use v1::impls::unlock_sign_and_dispatch; +use ethcore::account_provider::AccountProvider; use util::numbers::*; use ethcore::client::MiningBlockChainClient; use ethcore::miner::MinerService; /// Account management (personal) rpc implementation. -pub struct PersonalClient - where A: AccountProvider, C: MiningBlockChainClient, M: MinerService { - accounts: Weak, +pub struct PersonalClient where C: MiningBlockChainClient, M: MinerService { + accounts: Weak, client: Weak, miner: Weak, signer_port: Option, } -impl PersonalClient - where A: AccountProvider, C: MiningBlockChainClient, M: MinerService { +impl PersonalClient where C: MiningBlockChainClient, M: MinerService { /// Creates new PersonalClient - pub fn new(store: &Arc, client: &Arc, miner: &Arc, signer_port: Option) -> Self { + pub fn new(store: &Arc, client: &Arc, miner: &Arc, signer_port: Option) -> Self { PersonalClient { accounts: Arc::downgrade(store), client: Arc::downgrade(client), @@ -47,8 +45,7 @@ impl PersonalClient } } -impl Personal for PersonalClient - where A: AccountProvider, C: MiningBlockChainClient, M: MinerService { +impl Personal for PersonalClient where C: MiningBlockChainClient, M: MinerService { fn signer_enabled(&self, _: Params) -> Result { self.signer_port @@ -58,10 +55,7 @@ impl Personal for PersonalClient fn accounts(&self, _: Params) -> Result { let store = take_weak!(self.accounts); - match store.accounts() { - Ok(account_list) => to_value(&account_list), - Err(_) => Err(Error::internal_error()) - } + to_value(&store.accounts()) } fn new_account(&self, params: Params) -> Result { @@ -80,7 +74,7 @@ impl Personal for PersonalClient from_params::<(Address, String, u64)>(params).and_then( |(account, account_pass, _)|{ let store = take_weak!(self.accounts); - match store.unlock_account_temp(&account, &account_pass) { + match store.unlock_account_temporarily(account, account_pass) { Ok(_) => Ok(Value::Bool(true)), Err(_) => Ok(Value::Bool(false)), } @@ -90,10 +84,12 @@ impl Personal for PersonalClient fn sign_and_send_transaction(&self, params: Params) -> Result { from_params::<(TransactionRequest, String)>(params) .and_then(|(request, password)| { + let sender = request.from; let accounts = take_weak!(self.accounts); - match accounts.locked_account_secret(&request.from, &password) { - Ok(secret) => to_value(&sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, secret)), - Err(_) => to_value(&H256::zero()), + + match unlock_sign_and_dispatch(&*take_weak!(self.client), &*take_weak!(self.miner), request, &*accounts, sender, password) { + Ok(hash) => to_value(&hash), + _ => to_value(&H256::zero()), } }) } diff --git a/rpc/src/v1/impls/personal_signer.rs b/rpc/src/v1/impls/personal_signer.rs index 88bf9a5d1..89f15c787 100644 --- a/rpc/src/v1/impls/personal_signer.rs +++ b/rpc/src/v1/impls/personal_signer.rs @@ -20,27 +20,25 @@ use std::sync::{Arc, Weak}; use jsonrpc_core::*; use v1::traits::PersonalSigner; use v1::types::TransactionModification; -use v1::impls::sign_and_dispatch; +use v1::impls::unlock_sign_and_dispatch; use v1::helpers::{SigningQueue, ConfirmationsQueue}; -use util::keys::store::AccountProvider; +use ethcore::account_provider::AccountProvider; use util::numbers::*; use ethcore::client::MiningBlockChainClient; use ethcore::miner::MinerService; /// Transactions confirmation (personal) rpc implementation. -pub struct SignerClient - where A: AccountProvider, C: MiningBlockChainClient, M: MinerService { +pub struct SignerClient where C: MiningBlockChainClient, M: MinerService { queue: Weak, - accounts: Weak, + accounts: Weak, client: Weak, miner: Weak, } -impl SignerClient - where A: AccountProvider, C: MiningBlockChainClient, M: MinerService { +impl SignerClient where C: MiningBlockChainClient, M: MinerService { /// Create new instance of signer client. - pub fn new(store: &Arc, client: &Arc, miner: &Arc, queue: &Arc) -> Self { + pub fn new(store: &Arc, client: &Arc, miner: &Arc, queue: &Arc) -> Self { SignerClient { queue: Arc::downgrade(queue), accounts: Arc::downgrade(store), @@ -50,8 +48,7 @@ impl SignerClient } } -impl PersonalSigner for SignerClient - where A: AccountProvider, C: MiningBlockChainClient, M: MinerService { +impl PersonalSigner for SignerClient where C: MiningBlockChainClient, M: MinerService { fn transactions_to_confirm(&self, _params: Params) -> Result { let queue = take_weak!(self.queue); @@ -71,13 +68,15 @@ impl PersonalSigner for SignerClient { - let hash = sign_and_dispatch(&*client, &*miner, request, secret); - queue.request_confirmed(id, hash); + + let sender = request.from; + + match unlock_sign_and_dispatch(&*client, &*miner, request, &*accounts, sender, pass) { + Ok(hash) => { + queue.request_confirmed(id, Ok(hash.clone())); Some(to_value(&hash)) }, - Err(_) => None + _ => None } }) .unwrap_or_else(|| { diff --git a/rpc/src/v1/tests/eth.rs b/rpc/src/v1/tests/eth.rs index a7f7920ad..88a12a74f 100644 --- a/rpc/src/v1/tests/eth.rs +++ b/rpc/src/v1/tests/eth.rs @@ -15,7 +15,6 @@ // along with Parity. If not, see . //! rpc integration tests. -use std::collections::HashMap; use std::sync::Arc; use std::str::FromStr; @@ -25,13 +24,12 @@ use ethcore::spec::{Genesis, Spec}; use ethcore::block::Block; use ethcore::views::BlockView; use ethcore::ethereum; -use ethcore::miner::{MinerService, ExternalMiner, Miner}; +use ethcore::miner::{MinerOptions, MinerService, ExternalMiner, Miner, PendingSet}; +use ethcore::account_provider::AccountProvider; use devtools::RandomTempPath; use util::Hashable; use util::io::IoChannel; -use util::hash::{Address, H256}; -use util::numbers::U256; -use util::keys::{AccountProvider, TestAccount, TestAccountProvider}; +use util::{U256, H256, Uint}; use jsonrpc_core::IoHandler; use ethjson::blockchain::BlockChain; @@ -39,11 +37,8 @@ use v1::traits::eth::{Eth, EthSigning}; use v1::impls::{EthClient, EthSigningUnsafeClient}; use v1::tests::helpers::{TestSyncProvider, Config}; -fn account_provider() -> Arc { - let mut accounts = HashMap::new(); - accounts.insert(Address::from(1), TestAccount::new("test")); - let ap = TestAccountProvider::new(accounts); - Arc::new(ap) +fn account_provider() -> Arc { + Arc::new(AccountProvider::transient_provider()) } fn sync_provider() -> Arc { @@ -54,7 +49,18 @@ fn sync_provider() -> Arc { } fn miner_service(spec: Spec, accounts: Arc) -> Arc { - Miner::with_accounts(true, spec, accounts) + Miner::new( + MinerOptions { + force_sealing: true, + reseal_on_external_tx: true, + reseal_on_own_tx: true, + tx_queue_size: 1024, + tx_gas_limit: !U256::zero(), + pending_set: PendingSet::SealingOrElseQueue, + }, + spec, + Some(accounts) + ) } fn make_spec(chain: &BlockChain) -> Spec { @@ -70,7 +76,7 @@ fn make_spec(chain: &BlockChain) -> Spec { struct EthTester { client: Arc, _miner: Arc, - accounts: Arc, + accounts: Arc, handler: IoHandler, } @@ -107,7 +113,8 @@ impl EthTester { &sync_provider, &account_provider, &miner_service, - &external_miner + &external_miner, + true ); let eth_sign = EthSigningUnsafeClient::new( &client, @@ -187,7 +194,8 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{ "durationLimit": "0x0d", "blockReward": "0x4563918244F40000", "registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b", - "frontierCompatibilityModeLimit": "0xffffffffffffffff" + "frontierCompatibilityModeLimit": "0xffffffffffffffff", + "daoRescueSoftFork": false } } }, @@ -225,15 +233,10 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{ fn eth_transaction_count() { use util::crypto::Secret; - let address = Address::from_str("faa34835af5c2ea724333018a515fbb7d5bc0b33").unwrap(); let secret = Secret::from_str("8a283037bb19c4fed7b1c569e40c7dcff366165eb869110a1b11532963eb9cb2").unwrap(); - let tester = EthTester::from_spec_provider(|| Spec::load(TRANSACTION_COUNT_SPEC)); - tester.accounts.accounts.write().unwrap().insert(address, TestAccount { - unlocked: false, - password: "123".into(), - secret: secret - }); + let address = tester.accounts.insert_account(secret, "").unwrap(); + tester.accounts.unlock_account_permanently(address, "".into()).unwrap(); let req_before = r#"{ "jsonrpc": "2.0", diff --git a/rpc/src/v1/tests/helpers/miner_service.rs b/rpc/src/v1/tests/helpers/miner_service.rs index daa5c9497..6329be7bd 100644 --- a/rpc/src/v1/tests/helpers/miner_service.rs +++ b/rpc/src/v1/tests/helpers/miner_service.rs @@ -39,10 +39,11 @@ pub struct TestMinerService { pub last_nonces: RwLock>, min_gas_price: RwLock, - gas_floor_target: RwLock, + gas_range_target: RwLock<(U256, U256)>, author: RwLock
, extra_data: RwLock, limit: RwLock, + tx_gas_limit: RwLock, } impl Default for TestMinerService { @@ -54,10 +55,11 @@ impl Default for TestMinerService { pending_receipts: Mutex::new(BTreeMap::new()), last_nonces: RwLock::new(HashMap::new()), min_gas_price: RwLock::new(U256::from(20_000_000)), - gas_floor_target: RwLock::new(U256::from(12345)), + gas_range_target: RwLock::new((U256::from(12345), U256::from(54321))), author: RwLock::new(Address::zero()), extra_data: RwLock::new(vec![1, 2, 3, 4]), limit: RwLock::new(1024), + tx_gas_limit: RwLock::new(!U256::zero()), } } } @@ -81,9 +83,14 @@ impl MinerService for TestMinerService { *self.extra_data.write().unwrap() = extra_data; } - /// Set the gas limit we wish to target when sealing a new block. + /// Set the lower gas limit we wish to target when sealing a new block. fn set_gas_floor_target(&self, target: U256) { - *self.gas_floor_target.write().unwrap() = target; + self.gas_range_target.write().unwrap().0 = target; + } + + /// Set the upper gas limit we wish to target when sealing a new block. + fn set_gas_ceil_target(&self, target: U256) { + self.gas_range_target.write().unwrap().1 = target; } fn set_minimal_gas_price(&self, min_gas_price: U256) { @@ -94,6 +101,10 @@ impl MinerService for TestMinerService { *self.limit.write().unwrap() = limit; } + fn set_tx_gas_limit(&self, limit: U256) { + *self.tx_gas_limit.write().unwrap() = limit; + } + fn transactions_limit(&self) -> usize { *self.limit.read().unwrap() } @@ -111,11 +122,15 @@ impl MinerService for TestMinerService { } fn gas_floor_target(&self) -> U256 { - *self.gas_floor_target.read().unwrap() + self.gas_range_target.read().unwrap().0 + } + + fn gas_ceil_target(&self) -> U256 { + self.gas_range_target.read().unwrap().1 } /// Imports transactions to transaction queue. - fn import_transactions(&self, transactions: Vec, fetch_account: T) -> + fn import_transactions(&self, _chain: &MiningBlockChainClient, transactions: Vec, fetch_account: T) -> Vec> where T: Fn(&Address) -> AccountDetails { // lets assume that all txs are valid diff --git a/rpc/src/v1/tests/helpers/sync_provider.rs b/rpc/src/v1/tests/helpers/sync_provider.rs index 114b5b08f..11fa1cb9e 100644 --- a/rpc/src/v1/tests/helpers/sync_provider.rs +++ b/rpc/src/v1/tests/helpers/sync_provider.rs @@ -59,5 +59,11 @@ impl SyncProvider for TestSyncProvider { fn status(&self) -> SyncStatus { self.status.read().unwrap().clone() } + + fn start_network(&self) { + } + + fn stop_network(&self) { + } } diff --git a/rpc/src/v1/tests/mocked/eth.rs b/rpc/src/v1/tests/mocked/eth.rs index 34708e232..29c10a92b 100644 --- a/rpc/src/v1/tests/mocked/eth.rs +++ b/rpc/src/v1/tests/mocked/eth.rs @@ -20,7 +20,7 @@ use std::sync::{Arc, RwLock}; use jsonrpc_core::IoHandler; use util::hash::{Address, H256, FixedHash}; use util::numbers::{Uint, U256}; -use util::keys::{AccountProvider, TestAccount, TestAccountProvider}; +use ethcore::account_provider::AccountProvider; use ethcore::client::{TestBlockChainClient, EachBlockWith, Executed, TransactionID}; use ethcore::log_entry::{LocalizedLogEntry, LogEntry}; use ethcore::receipt::LocalizedReceipt; @@ -36,11 +36,8 @@ fn blockchain_client() -> Arc { Arc::new(client) } -fn accounts_provider() -> Arc { - let mut accounts = HashMap::new(); - accounts.insert(Address::from(1), TestAccount::new("test")); - let ap = TestAccountProvider::new(accounts); - Arc::new(ap) +fn accounts_provider() -> Arc { + Arc::new(AccountProvider::transient_provider()) } fn sync_provider() -> Arc { @@ -57,7 +54,7 @@ fn miner_service() -> Arc { struct EthTester { pub client: Arc, pub sync: Arc, - pub accounts_provider: Arc, + pub accounts_provider: Arc, miner: Arc, hashrates: Arc>>, pub io: IoHandler, @@ -71,7 +68,7 @@ impl Default for EthTester { let miner = miner_service(); let hashrates = Arc::new(RwLock::new(HashMap::new())); let external_miner = Arc::new(ExternalMiner::new(hashrates.clone())); - let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner).to_delegate(); + let eth = EthClient::new(&client, &sync, &ap, &miner, &external_miner, true).to_delegate(); let sign = EthSigningUnsafeClient::new(&client, &ap, &miner).to_delegate(); let io = IoHandler::new(); io.add_delegate(eth); @@ -169,8 +166,9 @@ fn rpc_eth_sign() { let tester = EthTester::default(); let account = tester.accounts_provider.new_account("abcd").unwrap(); + tester.accounts_provider.unlock_account_permanently(account, "abcd".into()).unwrap(); let message = H256::from("0x0cc175b9c0f1b6a831c399e26977266192eb5ffee6ae2fec3ad71c777531578f"); - let signed = tester.accounts_provider.sign(&account, &message).unwrap(); + let signed = tester.accounts_provider.sign(account, message).unwrap(); let req = r#"{ "jsonrpc": "2.0", @@ -233,10 +231,13 @@ fn rpc_eth_gas_price() { #[test] fn rpc_eth_accounts() { - let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"#; + let tester = EthTester::default(); + let address = tester.accounts_provider.new_account("").unwrap(); - assert_eq!(EthTester::default().io.handle_request(request), Some(response.to_owned())); + let request = r#"{"jsonrpc": "2.0", "method": "eth_accounts", "params": [], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":[""#.to_owned() + &format!("0x{:?}", address) + r#""],"id":1}"#; + + assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); } #[test] @@ -558,12 +559,9 @@ fn rpc_eth_estimate_gas_default_block() { #[test] fn rpc_eth_send_transaction() { - let account = TestAccount::new("123"); - let address = account.address(); - let secret = account.secret.clone(); - let tester = EthTester::default(); - tester.accounts_provider.accounts.write().unwrap().insert(address.clone(), account); + let address = tester.accounts_provider.new_account("").unwrap(); + tester.accounts_provider.unlock_account_permanently(address, "".into()).unwrap(); let request = r#"{ "jsonrpc": "2.0", "method": "eth_sendTransaction", @@ -584,7 +582,9 @@ fn rpc_eth_send_transaction() { action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), value: U256::from(0x9184e72au64), data: vec![] - }.sign(&secret); + }; + let signature = tester.accounts_provider.sign(address, t.hash()).unwrap(); + let t = t.with_signature(signature); let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#; @@ -599,7 +599,9 @@ fn rpc_eth_send_transaction() { action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), value: U256::from(0x9184e72au64), data: vec![] - }.sign(&secret); + }; + let signature = tester.accounts_provider.sign(address, t.hash()).unwrap(); + let t = t.with_signature(signature); let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#; @@ -610,7 +612,7 @@ fn rpc_eth_send_transaction() { fn rpc_eth_send_raw_transaction() { let tester = EthTester::default(); let address = tester.accounts_provider.new_account("abcd").unwrap(); - let secret = tester.accounts_provider.account_secret(&address).unwrap(); + tester.accounts_provider.unlock_account_permanently(address, "abcd".into()).unwrap(); let t = Transaction { nonce: U256::zero(), @@ -619,7 +621,9 @@ fn rpc_eth_send_raw_transaction() { action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), value: U256::from(0x9184e72au64), data: vec![] - }.sign(&secret); + }; + let signature = tester.accounts_provider.sign(address, t.hash()).unwrap(); + let t = t.with_signature(signature); let rlp = ::util::rlp::encode(&t).to_vec().to_hex(); @@ -732,7 +736,7 @@ fn returns_no_work_if_cant_mine() { eth_tester.client.set_queue_size(10); let request = r#"{"jsonrpc": "2.0", "method": "eth_getWork", "params": [], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":["","",""],"id":1}"#; + let response = r#"{"jsonrpc":"2.0","error":{"code":-32001,"message":"Still syncing.","data":null},"id":1}"#; assert_eq!(eth_tester.io.handle_request(request), Some(response.to_owned())); } diff --git a/rpc/src/v1/tests/mocked/eth_signing.rs b/rpc/src/v1/tests/mocked/eth_signing.rs index 6eb6e3fd6..5f3e75d35 100644 --- a/rpc/src/v1/tests/mocked/eth_signing.rs +++ b/rpc/src/v1/tests/mocked/eth_signing.rs @@ -14,26 +14,41 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . +use std::str::FromStr; use std::sync::Arc; use jsonrpc_core::IoHandler; use v1::impls::EthSigningQueueClient; use v1::traits::EthSigning; use v1::helpers::{ConfirmationsQueue, SigningQueue}; -use util::keys::TestAccount; +use v1::tests::helpers::TestMinerService; +use util::{Address, FixedHash}; +use util::numbers::{Uint, U256}; +use ethcore::account_provider::AccountProvider; +use ethcore::client::TestBlockChainClient; +use ethcore::transaction::{Transaction, Action}; struct EthSigningTester { pub queue: Arc, + pub client: Arc, + pub miner: Arc, + pub accounts: Arc, pub io: IoHandler, } impl Default for EthSigningTester { fn default() -> Self { let queue = Arc::new(ConfirmationsQueue::default()); + let client = Arc::new(TestBlockChainClient::default()); + let miner = Arc::new(TestMinerService::default()); + let accounts = Arc::new(AccountProvider::transient_provider()); let io = IoHandler::new(); - io.add_delegate(EthSigningQueueClient::new(&queue).to_delegate()); + io.add_delegate(EthSigningQueueClient::new(&queue, &client, &miner, &accounts).to_delegate()); EthSigningTester { queue: queue, + client: client, + miner: miner, + accounts: accounts, io: io, } } @@ -48,8 +63,7 @@ fn eth_signing() -> EthSigningTester { fn should_add_transaction_to_queue() { // given let tester = eth_signing(); - let account = TestAccount::new("123"); - let address = account.address(); + let address = Address::random(); assert_eq!(tester.queue.requests().len(), 0); // when @@ -71,5 +85,41 @@ fn should_add_transaction_to_queue() { // then assert_eq!(tester.io.handle_request(&request), Some(response.to_owned())); assert_eq!(tester.queue.requests().len(), 1); - +} + +#[test] +fn should_dispatch_transaction_if_account_is_unlocked() { + // given + let tester = eth_signing(); + let acc = tester.accounts.new_account("test").unwrap(); + tester.accounts.unlock_account_permanently(acc, "test".into()).unwrap(); + + let t = Transaction { + nonce: U256::zero(), + gas_price: U256::from(0x9184e72a000u64), + gas: U256::from(0x76c0), + action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), + value: U256::from(0x9184e72au64), + data: vec![] + }; + let signature = tester.accounts.sign(acc, t.hash()).unwrap(); + let t = t.with_signature(signature); + + // when + let request = r#"{ + "jsonrpc": "2.0", + "method": "eth_sendTransaction", + "params": [{ + "from": ""#.to_owned() + format!("0x{:?}", acc).as_ref() + r#"", + "to": "0xd46e8dd67c5d32be8058bb8eb970870f07244567", + "gas": "0x76c0", + "gasPrice": "0x9184e72a000", + "value": "0x9184e72a" + }], + "id": 1 + }"#; + let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#; + + // then + assert_eq!(tester.io.handle_request(&request), Some(response.to_owned())); } diff --git a/rpc/src/v1/tests/mocked/ethcore.rs b/rpc/src/v1/tests/mocked/ethcore.rs index 90103adef..5b88e8756 100644 --- a/rpc/src/v1/tests/mocked/ethcore.rs +++ b/rpc/src/v1/tests/mocked/ethcore.rs @@ -15,13 +15,11 @@ // along with Parity. If not, see . use std::sync::Arc; -use std::str::FromStr; use jsonrpc_core::IoHandler; -use v1::{Ethcore, EthcoreClient, EthcoreSet, EthcoreSetClient}; -use ethcore::miner::MinerService; +use v1::{Ethcore, EthcoreClient}; use v1::tests::helpers::TestMinerService; -use util::numbers::*; -use rustc_serialize::hex::FromHex; +use v1::helpers::ConfirmationsQueue; +use ethcore::client::{TestBlockChainClient}; use util::log::RotatingLogger; use util::network_settings::NetworkSettings; @@ -29,6 +27,10 @@ fn miner_service() -> Arc { Arc::new(TestMinerService::default()) } +fn client_service() -> Arc { + Arc::new(TestBlockChainClient::default()) +} + fn logger() -> Arc { Arc::new(RotatingLogger::new("rpc=trace".to_owned())) } @@ -45,20 +47,16 @@ fn settings() -> Arc { }) } -fn ethcore_client(miner: &Arc) -> EthcoreClient { - EthcoreClient::new(&miner, logger(), settings()) -} - -fn ethcore_set_client(miner: &Arc) -> EthcoreSetClient { - EthcoreSetClient::new(&miner) +fn ethcore_client(client: &Arc, miner: &Arc) -> EthcoreClient { + EthcoreClient::new(client, miner, logger(), settings(), None) } #[test] fn rpc_ethcore_extra_data() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_extraData", "params": [], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x01020304","id":1}"#; @@ -72,9 +70,9 @@ fn rpc_ethcore_default_extra_data() { use util::ToPretty; let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_defaultExtraData", "params": [], "id": 1}"#; let response = format!(r#"{{"jsonrpc":"2.0","result":"0x{}","id":1}}"#, misc::version_data().to_hex()); @@ -85,9 +83,9 @@ fn rpc_ethcore_default_extra_data() { #[test] fn rpc_ethcore_gas_floor_target() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_gasFloorTarget", "params": [], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x3039","id":1}"#; @@ -98,9 +96,9 @@ fn rpc_ethcore_gas_floor_target() { #[test] fn rpc_ethcore_min_gas_price() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_minGasPrice", "params": [], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":"0x01312d00","id":1}"#; @@ -108,72 +106,16 @@ fn rpc_ethcore_min_gas_price() { assert_eq!(io.handle_request(request), Some(response.to_owned())); } -#[test] -fn rpc_ethcore_set_min_gas_price() { - let miner = miner_service(); - let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); - - let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; - - assert_eq!(io.handle_request(request), Some(response.to_owned())); - assert_eq!(miner.minimal_gas_price(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); -} - -#[test] -fn rpc_ethcore_set_gas_floor_target() { - let miner = miner_service(); - let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); - - let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; - - assert_eq!(io.handle_request(request), Some(response.to_owned())); - assert_eq!(miner.gas_floor_target(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); -} - -#[test] -fn rpc_ethcore_set_extra_data() { - let miner = miner_service(); - let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); - - let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; - - assert_eq!(io.handle_request(request), Some(response.to_owned())); - assert_eq!(miner.extra_data(), "cd1722f3947def4cf144679da39c4c32bdc35681".from_hex().unwrap()); -} - -#[test] -fn rpc_ethcore_set_author() { - let miner = miner_service(); - let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); - - let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; - - assert_eq!(io.handle_request(request), Some(response.to_owned())); - assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); -} - #[test] fn rpc_ethcore_dev_logs() { let miner = miner_service(); + let client = client_service(); let logger = logger(); logger.append("a".to_owned()); logger.append("b".to_owned()); - let ethcore = EthcoreClient::new(&miner, logger.clone(), settings()).to_delegate(); + let ethcore = EthcoreClient::new(&client, &miner, logger.clone(), settings(), None).to_delegate(); let io = IoHandler::new(); io.add_delegate(ethcore); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_devLogs", "params":[], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":["b","a"],"id":1}"#; @@ -184,35 +126,22 @@ fn rpc_ethcore_dev_logs() { #[test] fn rpc_ethcore_dev_logs_levels() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_devLogsLevels", "params":[], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":"rpc=trace","id":1}"#; - assert_eq!(io.handle_request(request), Some(response.to_owned())); -} - -#[test] -fn rpc_ethcore_set_transactions_limit() { - let miner = miner_service(); - let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); - - let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setTransactionsLimit", "params":[10240240], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; assert_eq!(io.handle_request(request), Some(response.to_owned())); - assert_eq!(miner.transactions_limit(), 10_240_240); } #[test] fn rpc_ethcore_transactions_limit() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_transactionsLimit", "params":[], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":1024,"id":1}"#; @@ -223,9 +152,9 @@ fn rpc_ethcore_transactions_limit() { #[test] fn rpc_ethcore_net_chain() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netChain", "params":[], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":"testchain","id":1}"#; @@ -236,9 +165,9 @@ fn rpc_ethcore_net_chain() { #[test] fn rpc_ethcore_net_max_peers() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netMaxPeers", "params":[], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":25,"id":1}"#; @@ -249,9 +178,9 @@ fn rpc_ethcore_net_max_peers() { #[test] fn rpc_ethcore_net_port() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_netPort", "params":[], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":30303,"id":1}"#; @@ -262,9 +191,9 @@ fn rpc_ethcore_net_port() { #[test] fn rpc_ethcore_rpc_settings() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_rpcSettings", "params":[], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":{"enabled":true,"interface":"all","port":8545},"id":1}"#; @@ -275,12 +204,40 @@ fn rpc_ethcore_rpc_settings() { #[test] fn rpc_ethcore_node_name() { let miner = miner_service(); + let client = client_service(); let io = IoHandler::new(); - io.add_delegate(ethcore_client(&miner).to_delegate()); - io.add_delegate(ethcore_set_client(&miner).to_delegate()); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); let request = r#"{"jsonrpc": "2.0", "method": "ethcore_nodeName", "params":[], "id": 1}"#; let response = r#"{"jsonrpc":"2.0","result":"mynode","id":1}"#; assert_eq!(io.handle_request(request), Some(response.to_owned())); } + +#[test] +fn rpc_ethcore_unsigned_transactions_count() { + let miner = miner_service(); + let client = client_service(); + let io = IoHandler::new(); + let queue = Arc::new(ConfirmationsQueue::default()); + let ethcore = EthcoreClient::new(&client, &miner, logger(), settings(), Some(queue)).to_delegate(); + io.add_delegate(ethcore); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_unsignedTransactionsCount", "params":[], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":0,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); +} + +#[test] +fn rpc_ethcore_unsigned_transactions_count_when_signer_disabled() { + let miner = miner_service(); + let client = client_service(); + let io = IoHandler::new(); + io.add_delegate(ethcore_client(&client, &miner).to_delegate()); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_unsignedTransactionsCount", "params":[], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","error":{"code":-32030,"message":"Trusted Signer is disabled. This API is not available.","data":null},"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); +} diff --git a/rpc/src/v1/tests/mocked/ethcore_set.rs b/rpc/src/v1/tests/mocked/ethcore_set.rs new file mode 100644 index 000000000..19f52025f --- /dev/null +++ b/rpc/src/v1/tests/mocked/ethcore_set.rs @@ -0,0 +1,107 @@ +// 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 . + +use std::sync::Arc; +use std::str::FromStr; +use jsonrpc_core::IoHandler; +use v1::{EthcoreSet, EthcoreSetClient}; +use ethcore::miner::MinerService; +use ethcore::service::SyncMessage; +use v1::tests::helpers::TestMinerService; +use util::numbers::*; +use util::network::{NetworkConfiguration, NetworkService}; +use rustc_serialize::hex::FromHex; + +fn miner_service() -> Arc { + Arc::new(TestMinerService::default()) +} + +fn network_service() -> Arc> { + Arc::new(NetworkService::new(NetworkConfiguration::new()).unwrap()) +} + +fn ethcore_set_client(miner: &Arc, net: &Arc>) -> EthcoreSetClient { + EthcoreSetClient::new(miner, net) +} + +#[test] +fn rpc_ethcore_set_min_gas_price() { + let miner = miner_service(); + let network = network_service(); + let io = IoHandler::new(); + io.add_delegate(ethcore_set_client(&miner, &network).to_delegate()); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setMinGasPrice", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.minimal_gas_price(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); +} +#[test] +fn rpc_ethcore_set_gas_floor_target() { + let miner = miner_service(); + let network = network_service(); + let io = IoHandler::new(); + io.add_delegate(ethcore_set_client(&miner, &network).to_delegate()); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setGasFloorTarget", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.gas_floor_target(), U256::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); +} + +#[test] +fn rpc_ethcore_set_extra_data() { + let miner = miner_service(); + let network = network_service(); + let io = IoHandler::new(); + io.add_delegate(ethcore_set_client(&miner, &network).to_delegate()); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setExtraData", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.extra_data(), "cd1722f3947def4cf144679da39c4c32bdc35681".from_hex().unwrap()); +} + +#[test] +fn rpc_ethcore_set_author() { + let miner = miner_service(); + let network = network_service(); + let io = IoHandler::new(); + io.add_delegate(ethcore_set_client(&miner, &network).to_delegate()); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setAuthor", "params":["0xcd1722f3947def4cf144679da39c4c32bdc35681"], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.author(), Address::from_str("cd1722f3947def4cf144679da39c4c32bdc35681").unwrap()); +} + +#[test] +fn rpc_ethcore_set_transactions_limit() { + let miner = miner_service(); + let network = network_service(); + let io = IoHandler::new(); + io.add_delegate(ethcore_set_client(&miner, &network).to_delegate()); + + let request = r#"{"jsonrpc": "2.0", "method": "ethcore_setTransactionsLimit", "params":[10240240], "id": 1}"#; + let response = r#"{"jsonrpc":"2.0","result":true,"id":1}"#; + + assert_eq!(io.handle_request(request), Some(response.to_owned())); + assert_eq!(miner.transactions_limit(), 10_240_240); +} diff --git a/rpc/src/v1/tests/mocked/mod.rs b/rpc/src/v1/tests/mocked/mod.rs index 986dbfdef..503c75c12 100644 --- a/rpc/src/v1/tests/mocked/mod.rs +++ b/rpc/src/v1/tests/mocked/mod.rs @@ -24,4 +24,5 @@ mod web3; mod personal; mod personal_signer; mod ethcore; +mod ethcore_set; mod rpc; diff --git a/rpc/src/v1/tests/mocked/personal.rs b/rpc/src/v1/tests/mocked/personal.rs index 02b07abd3..cca58c1d7 100644 --- a/rpc/src/v1/tests/mocked/personal.rs +++ b/rpc/src/v1/tests/mocked/personal.rs @@ -16,17 +16,16 @@ use std::sync::Arc; use std::str::FromStr; -use std::collections::HashMap; use jsonrpc_core::IoHandler; use util::numbers::*; -use util::keys::{TestAccount, TestAccountProvider}; +use ethcore::account_provider::AccountProvider; use v1::{PersonalClient, Personal}; use v1::tests::helpers::TestMinerService; use ethcore::client::TestBlockChainClient; use ethcore::transaction::{Action, Transaction}; struct PersonalTester { - accounts: Arc, + accounts: Arc, io: IoHandler, miner: Arc, // these unused fields are necessary to keep the data alive @@ -39,10 +38,8 @@ fn blockchain_client() -> Arc { Arc::new(client) } -fn accounts_provider() -> Arc { - let accounts = HashMap::new(); - let ap = TestAccountProvider::new(accounts); - Arc::new(ap) +fn accounts_provider() -> Arc { + Arc::new(AccountProvider::transient_provider()) } fn miner_service() -> Arc { @@ -99,13 +96,9 @@ fn should_return_port_number_if_signer_is_enabled() { #[test] fn accounts() { let tester = setup(None); - tester.accounts.accounts - .write() - .unwrap() - .insert(Address::from(1), TestAccount::new("test")); - + let address = tester.accounts.new_account("").unwrap(); let request = r#"{"jsonrpc": "2.0", "method": "personal_listAccounts", "params": [], "id": 1}"#; - let response = r#"{"jsonrpc":"2.0","result":["0x0000000000000000000000000000000000000001"],"id":1}"#; + let response = r#"{"jsonrpc":"2.0","result":[""#.to_owned() + &format!("0x{:?}", address) + r#""],"id":1}"#; assert_eq!(tester.io.handle_request(request), Some(response.to_owned())); } @@ -117,15 +110,9 @@ fn new_account() { let res = tester.io.handle_request(request); - let accounts = tester.accounts.accounts.read().unwrap(); + let accounts = tester.accounts.accounts(); assert_eq!(accounts.len(), 1); - - let address = accounts - .keys() - .nth(0) - .cloned() - .unwrap(); - + let address = accounts[0]; let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", address).as_ref() + r#"","id":1}"#; assert_eq!(res, Some(response)); @@ -133,11 +120,8 @@ fn new_account() { #[test] fn sign_and_send_transaction_with_invalid_password() { - let account = TestAccount::new("password123"); - let address = account.address(); - let tester = setup(None); - tester.accounts.accounts.write().unwrap().insert(address.clone(), account); + let address = tester.accounts.new_account("password123").unwrap(); let request = r#"{ "jsonrpc": "2.0", "method": "personal_signAndSendTransaction", @@ -158,12 +142,9 @@ fn sign_and_send_transaction_with_invalid_password() { #[test] fn sign_and_send_transaction() { - let account = TestAccount::new("password123"); - let address = account.address(); - let secret = account.secret.clone(); - let tester = setup(None); - tester.accounts.accounts.write().unwrap().insert(address.clone(), account); + let address = tester.accounts.new_account("password123").unwrap(); + let request = r#"{ "jsonrpc": "2.0", "method": "personal_signAndSendTransaction", @@ -184,7 +165,10 @@ fn sign_and_send_transaction() { action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), value: U256::from(0x9184e72au64), data: vec![] - }.sign(&secret); + }; + tester.accounts.unlock_account_temporarily(address, "password123".into()).unwrap(); + let signature = tester.accounts.sign(address, t.hash()).unwrap(); + let t = t.with_signature(signature); let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#; @@ -199,7 +183,10 @@ fn sign_and_send_transaction() { action: Action::Call(Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap()), value: U256::from(0x9184e72au64), data: vec![] - }.sign(&secret); + }; + tester.accounts.unlock_account_temporarily(address, "password123".into()).unwrap(); + let signature = tester.accounts.sign(address, t.hash()).unwrap(); + let t = t.with_signature(signature); let response = r#"{"jsonrpc":"2.0","result":""#.to_owned() + format!("0x{:?}", t.hash()).as_ref() + r#"","id":1}"#; diff --git a/rpc/src/v1/tests/mocked/personal_signer.rs b/rpc/src/v1/tests/mocked/personal_signer.rs index cf7661331..6fa734cec 100644 --- a/rpc/src/v1/tests/mocked/personal_signer.rs +++ b/rpc/src/v1/tests/mocked/personal_signer.rs @@ -16,10 +16,9 @@ use std::sync::Arc; use std::str::FromStr; -use std::collections::HashMap; use jsonrpc_core::IoHandler; use util::numbers::*; -use util::keys::{TestAccount, TestAccountProvider}; +use ethcore::account_provider::AccountProvider; use ethcore::client::TestBlockChainClient; use ethcore::transaction::{Transaction, Action}; use v1::{SignerClient, PersonalSigner}; @@ -30,7 +29,7 @@ use v1::types::TransactionRequest; struct PersonalSignerTester { queue: Arc, - accounts: Arc, + accounts: Arc, io: IoHandler, miner: Arc, // these unused fields are necessary to keep the data alive @@ -43,10 +42,8 @@ fn blockchain_client() -> Arc { Arc::new(client) } -fn accounts_provider() -> Arc { - let accounts = HashMap::new(); - let ap = TestAccountProvider::new(accounts); - Arc::new(ap) +fn accounts_provider() -> Arc { + Arc::new(AccountProvider::transient_provider()) } fn miner_service() -> Arc { @@ -146,16 +143,10 @@ fn should_not_remove_transaction_if_password_is_invalid() { #[test] fn should_confirm_transaction_and_dispatch() { - // given + //// given let tester = signer_tester(); - let account = TestAccount::new("test"); - let address = account.address(); - let secret = account.secret.clone(); + let address = tester.accounts.new_account("test").unwrap(); let recipient = Address::from_str("d46e8dd67c5d32be8058bb8eb970870f07244567").unwrap(); - tester.accounts.accounts - .write() - .unwrap() - .insert(address, account); tester.queue.add_request(TransactionRequest { from: address, to: Some(recipient), @@ -165,6 +156,7 @@ fn should_confirm_transaction_and_dispatch() { data: None, nonce: None, }); + let t = Transaction { nonce: U256::zero(), gas_price: U256::from(0x1000), @@ -172,7 +164,10 @@ fn should_confirm_transaction_and_dispatch() { action: Action::Call(recipient), value: U256::from(0x1), data: vec![] - }.sign(&secret); + }; + tester.accounts.unlock_account_temporarily(address, "test".into()).unwrap(); + let signature = tester.accounts.sign(address, t.hash()).unwrap(); + let t = t.with_signature(signature); assert_eq!(tester.queue.requests().len(), 1); diff --git a/rpc/src/v1/traits/ethcore.rs b/rpc/src/v1/traits/ethcore.rs index 4ce3eca59..a5032d3e2 100644 --- a/rpc/src/v1/traits/ethcore.rs +++ b/rpc/src/v1/traits/ethcore.rs @@ -30,6 +30,9 @@ pub trait Ethcore: Sized + Send + Sync + 'static { /// Returns mining gas floor target. fn gas_floor_target(&self, _: Params) -> Result; + /// Returns mining gas floor cap. + fn gas_ceil_target(&self, _: Params) -> Result; + /// Returns minimal gas price for transaction to be included in queue. fn min_gas_price(&self, _: Params) -> Result; @@ -57,12 +60,20 @@ pub trait Ethcore: Sized + Send + Sync + 'static { /// Returns default extra data fn default_extra_data(&self, _: Params) -> Result; + /// Returns distribution of gas price in latest blocks. + fn gas_price_statistics(&self, _: Params) -> Result; + + /// Returns number of unsigned transactions waiting in the signer queue (if signer enabled) + /// Returns error when signer is disabled + fn unsigned_transactions_count(&self, _: Params) -> Result; + /// Should be used to convert object to io delegate. fn to_delegate(self) -> IoDelegate { let mut delegate = IoDelegate::new(Arc::new(self)); delegate.add_method("ethcore_extraData", Ethcore::extra_data); delegate.add_method("ethcore_gasFloorTarget", Ethcore::gas_floor_target); + delegate.add_method("ethcore_gasCeilTarget", Ethcore::gas_ceil_target); delegate.add_method("ethcore_minGasPrice", Ethcore::min_gas_price); delegate.add_method("ethcore_transactionsLimit", Ethcore::transactions_limit); delegate.add_method("ethcore_devLogs", Ethcore::dev_logs); @@ -73,6 +84,8 @@ pub trait Ethcore: Sized + Send + Sync + 'static { delegate.add_method("ethcore_rpcSettings", Ethcore::rpc_settings); delegate.add_method("ethcore_nodeName", Ethcore::node_name); delegate.add_method("ethcore_defaultExtraData", Ethcore::default_extra_data); + delegate.add_method("ethcore_gasPriceStatistics", Ethcore::gas_price_statistics); + delegate.add_method("ethcore_unsignedTransactionsCount", Ethcore::unsigned_transactions_count); delegate } diff --git a/rpc/src/v1/traits/ethcore_set.rs b/rpc/src/v1/traits/ethcore_set.rs index 332c505b6..8afbcdab9 100644 --- a/rpc/src/v1/traits/ethcore_set.rs +++ b/rpc/src/v1/traits/ethcore_set.rs @@ -28,6 +28,9 @@ pub trait EthcoreSet: Sized + Send + Sync + 'static { /// Sets new gas floor target for mined blocks. fn set_gas_floor_target(&self, _: Params) -> Result; + /// Sets new gas ceiling target for mined blocks. + fn set_gas_ceil_target(&self, _: Params) -> Result; + /// Sets new extra data for mined blocks. fn set_extra_data(&self, _: Params) -> Result; @@ -37,14 +40,35 @@ pub trait EthcoreSet: Sized + Send + Sync + 'static { /// Sets the limits for transaction queue. fn set_transactions_limit(&self, _: Params) -> Result; + /// Sets the maximum amount of gas a single transaction may consume. + fn set_tx_gas_limit(&self, _: Params) -> Result; + + /// Add a reserved peer. + fn add_reserved_peer(&self, _: Params) -> Result; + + /// Remove a reserved peer. + fn remove_reserved_peer(&self, _: Params) -> Result; + + /// Drop all non-reserved peers. + fn drop_non_reserved_peers(&self, _: Params) -> Result; + + /// Accept non-reserved peers (default behavior) + fn accept_non_reserved_peers(&self, _: Params) -> Result; + /// Should be used to convert object to io delegate. fn to_delegate(self) -> IoDelegate { let mut delegate = IoDelegate::new(Arc::new(self)); delegate.add_method("ethcore_setMinGasPrice", EthcoreSet::set_min_gas_price); delegate.add_method("ethcore_setGasFloorTarget", EthcoreSet::set_gas_floor_target); + delegate.add_method("ethcore_setGasCeilTarget", EthcoreSet::set_gas_ceil_target); delegate.add_method("ethcore_setExtraData", EthcoreSet::set_extra_data); delegate.add_method("ethcore_setAuthor", EthcoreSet::set_author); + delegate.add_method("ethcore_setMaxTransactionGas", EthcoreSet::set_tx_gas_limit); delegate.add_method("ethcore_setTransactionsLimit", EthcoreSet::set_transactions_limit); + delegate.add_method("ethcore_addReservedPeer", EthcoreSet::add_reserved_peer); + delegate.add_method("ethcore_removeReservedPeer", EthcoreSet::remove_reserved_peer); + delegate.add_method("ethcore_dropNonReservedPeers", EthcoreSet::drop_non_reserved_peers); + delegate.add_method("ethcore_acceptNonReservedPeers", EthcoreSet::accept_non_reserved_peers); delegate } diff --git a/rpc/src/v1/traits/net.rs b/rpc/src/v1/traits/net.rs index 56fba3e32..2df8c8f9c 100644 --- a/rpc/src/v1/traits/net.rs +++ b/rpc/src/v1/traits/net.rs @@ -30,6 +30,12 @@ pub trait Net: Sized + Send + Sync + 'static { /// Otherwise false. fn is_listening(&self, _: Params) -> Result; + /// Start the network. + fn start_network(&self, _: Params) -> Result; + + /// Stop the network. + fn stop_network(&self, _: Params) -> Result; + /// Should be used to convert object to io delegate. fn to_delegate(self) -> IoDelegate { let mut delegate = IoDelegate::new(Arc::new(self)); diff --git a/rpc/src/v1/types/optionals.rs b/rpc/src/v1/types/optionals.rs index 2ed272ade..5f62dc4a0 100644 --- a/rpc/src/v1/types/optionals.rs +++ b/rpc/src/v1/types/optionals.rs @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use serde::{Serialize, Serializer}; +use serde::{Serialize, Serializer, Deserialize, Deserializer}; use serde_json::Value; /// Optional value @@ -26,13 +26,22 @@ pub enum OptionalValue where T: Serialize { Null } -impl Default for OptionalValue where T: Serialize { +impl Default for OptionalValue where T: Serialize + Deserialize { fn default() -> Self { OptionalValue::Null } } -impl Serialize for OptionalValue where T: Serialize { +impl Into> for OptionalValue where T: Serialize + Deserialize { + fn into(self) -> Option { + match self { + OptionalValue::Null => None, + OptionalValue::Value(t) => Some(t), + } + } +} + +impl Serialize for OptionalValue where T: Serialize + Deserialize { fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { match *self { @@ -42,6 +51,17 @@ impl Serialize for OptionalValue where T: Serialize { } } +impl Deserialize for OptionalValue where T: Serialize + Deserialize { + fn deserialize(deserializer: &mut D) -> Result, D::Error> + where D: Deserializer { + let deser_result: Result = Deserialize::deserialize(deserializer); + match deser_result { + Ok(t) => Ok(OptionalValue::Value(t)), + Err(_) => Ok(OptionalValue::Null), + } + } +} + #[cfg(test)] mod tests { use serde_json; diff --git a/rpc/src/v1/types/receipt.rs b/rpc/src/v1/types/receipt.rs index 32a7f5945..c56cdf3d3 100644 --- a/rpc/src/v1/types/receipt.rs +++ b/rpc/src/v1/types/receipt.rs @@ -17,23 +17,23 @@ use util::numbers::U256; use util::hash::{Address, H256}; use v1::types::Log; -use ethcore::receipt::LocalizedReceipt; +use ethcore::receipt::{Receipt as EthReceipt, LocalizedReceipt}; /// Receipt #[derive(Debug, Serialize)] pub struct Receipt { /// Transaction Hash #[serde(rename="transactionHash")] - pub transaction_hash: H256, + pub transaction_hash: Option, /// Transaction index #[serde(rename="transactionIndex")] - pub transaction_index: U256, + pub transaction_index: Option, /// Block hash #[serde(rename="blockHash")] - pub block_hash: H256, + pub block_hash: Option, /// Block number #[serde(rename="blockNumber")] - pub block_number: U256, + pub block_number: Option, /// Cumulative gas used #[serde(rename="cumulativeGasUsed")] pub cumulative_gas_used: U256, @@ -50,10 +50,10 @@ pub struct Receipt { impl From for Receipt { fn from(r: LocalizedReceipt) -> Self { Receipt { - transaction_hash: r.transaction_hash, - transaction_index: U256::from(r.transaction_index), - block_hash: r.block_hash, - block_number: U256::from(r.block_number), + transaction_hash: Some(r.transaction_hash), + transaction_index: Some(U256::from(r.transaction_index)), + block_hash: Some(r.block_hash), + block_number: Some(U256::from(r.block_number)), cumulative_gas_used: r.cumulative_gas_used, gas_used: r.gas_used, contract_address: r.contract_address, @@ -62,6 +62,21 @@ impl From for Receipt { } } +impl From for Receipt { + fn from(r: EthReceipt) -> Self { + Receipt { + transaction_hash: None, + transaction_index: None, + block_hash: None, + block_number: None, + cumulative_gas_used: r.gas_used, + gas_used: r.gas_used, + contract_address: None, + logs: r.logs.into_iter().map(From::from).collect(), + } + } +} + #[cfg(test)] mod tests { use serde_json; @@ -74,10 +89,10 @@ mod tests { let s = r#"{"transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","cumulativeGasUsed":"0x20","gasUsed":"0x10","contractAddress":null,"logs":[{"address":"0x33990122638b9132ca29c723bdf037f1a891a70c","topics":["0xa6697e974e6a320f454390be03f74955e8978f1a6971ea6730542e37b66179bc","0x4861736852656700000000000000000000000000000000000000000000000000"],"data":"0x","blockHash":"0xed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5","blockNumber":"0x04510c","transactionHash":"0x0000000000000000000000000000000000000000000000000000000000000000","transactionIndex":"0x00","logIndex":"0x01","type":"mined"}]}"#; let receipt = Receipt { - transaction_hash: H256::zero(), - transaction_index: U256::zero(), - block_hash: H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap(), - block_number: U256::from(0x4510c), + transaction_hash: Some(H256::zero()), + transaction_index: Some(U256::zero()), + block_hash: Some(H256::from_str("ed76641c68a1c641aee09a94b3b471f4dc0316efe5ac19cf488e2674cf8d05b5").unwrap()), + block_number: Some(U256::from(0x4510c)), cumulative_gas_used: U256::from(0x20), gas_used: U256::from(0x10), contract_address: None, diff --git a/signer/Cargo.toml b/signer/Cargo.toml index 82160d55a..4ef8bb03e 100644 --- a/signer/Cargo.toml +++ b/signer/Cargo.toml @@ -3,7 +3,7 @@ description = "Ethcore Trusted Signer" homepage = "http://ethcore.io" license = "GPL-3.0" name = "ethcore-signer" -version = "1.2.0" +version = "1.3.0" authors = ["Ethcore "] build = "build.rs" @@ -15,12 +15,12 @@ rand = "0.3.14" jsonrpc-core = "2.0" log = "0.3" env_logger = "0.3" -ws = { git = "https://github.com/ethcore/ws-rs.git" } +ws = { git = "https://github.com/ethcore/ws-rs.git", branch = "stable" } ethcore-util = { path = "../util" } ethcore-rpc = { path = "../rpc" } -parity-minimal-sysui = { git = "https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git" } +parity-minimal-sysui = { git = "https://github.com/ethcore/parity-dapps-minimal-sysui-rs.git", version = "0.2.0" } -clippy = { version = "0.0.76", optional = true} +clippy = { version = "0.0.77", optional = true} [features] dev = ["clippy"] diff --git a/signer/src/ws_server/mod.rs b/signer/src/ws_server/mod.rs index 76c0fbb16..d2d838b2c 100644 --- a/signer/src/ws_server/mod.rs +++ b/signer/src/ws_server/mod.rs @@ -92,8 +92,10 @@ impl Server { fn start(addr: SocketAddr, handler: Arc, queue: Arc, authcodes_path: PathBuf) -> Result { let config = { let mut config = ws::Settings::default(); - config.max_connections = 10; + // It's also used for handling min-sysui requests (browser can make many of them in paralel) config.method_strict = true; + // Was shutting down server when suspending on linux: + config.shutdown_on_interrupt = false; config }; @@ -108,7 +110,17 @@ impl Server { // Spawn a thread with event loop let handle = thread::spawn(move || { ph.catch_panic(move || { - ws.listen(addr).unwrap() + match ws.listen(addr).map_err(ServerError::from) { + Err(ServerError::IoError(io)) => die(format!( + "Signer: Could not start listening on specified address. Make sure that no other instance is running on Signer's port. Details: {:?}", + io + )), + Err(any_error) => die(format!( + "Signer: Unknown error occured when starting Signer. Details: {:?}", + any_error + )), + Ok(server) => server, + } }).unwrap() }); @@ -121,7 +133,11 @@ impl Server { // TODO [ToDr] Some better structure here for messages. broadcaster.send("new_message").unwrap(); }).expect("It's the only place we are running start_listening. It shouldn't fail."); - broadcaster.shutdown().expect("Broadcaster should close gently.") + let res = broadcaster.shutdown(); + + if let Err(e) = res { + warn!("Signer: Broadcaster was not closed cleanly. Details: {:?}", e); + } }).unwrap() }); @@ -146,5 +162,11 @@ impl Drop for Server { self.queue.finish(); self.broadcaster_handle.take().unwrap().join().unwrap(); self.handle.take().unwrap().join().unwrap(); + } } + +fn die(msg: String) -> ! { + println!("ERROR: {}", msg); + std::process::exit(1); +} diff --git a/signer/src/ws_server/session.rs b/signer/src/ws_server/session.rs index 8cc3f5d07..4b2eb808c 100644 --- a/signer/src/ws_server/session.rs +++ b/signer/src/ws_server/session.rs @@ -62,6 +62,19 @@ fn auth_is_valid(codes: &Path, protocols: ws::Result>) -> bool { } } +fn add_headers(mut response: ws::Response, mime: &str) -> ws::Response { + let content_len = format!("{}", response.len()); + { + let mut headers = response.headers_mut(); + headers.push(("X-Frame-Options".into(), b"SAMEORIGIN".to_vec())); + headers.push(("Server".into(), b"Parity/SignerUI".to_vec())); + headers.push(("Content-Length".into(), content_len.as_bytes().to_vec())); + headers.push(("Content-Type".into(), mime.as_bytes().to_vec())); + headers.push(("Connection".into(), b"close".to_vec())); + } + response +} + pub struct Session { out: ws::Sender, self_origin: String, @@ -75,7 +88,7 @@ impl ws::Handler for Session { let host = req.header("host").or_else(|| req.header("Host")); // Check request origin and host header. - if !origin_is_allowed(&self.self_origin, origin) && !origin_is_allowed(&self.self_origin, host) { + if !origin_is_allowed(&self.self_origin, origin) && !(origin.is_none() && origin_is_allowed(&self.self_origin, host)) { warn!(target: "signer", "Blocked connection to Signer API from untrusted origin."); return Ok(ws::Response::forbidden(format!("You are not allowed to access system ui. Use: http://{}", self.self_origin))); } @@ -98,26 +111,13 @@ impl ws::Handler for Session { } // Otherwise try to serve a page. - sysui::handle(req.resource()) + Ok(sysui::handle(req.resource()) .map_or_else( - // return error - || Ok(ws::Response::not_found("Page not found".into())), + // return 404 not found + || add_headers(ws::Response::not_found("Not found".into()), "text/plain"), // or serve the file - |f| { - let content_len = format!("{}", f.content.as_bytes().len()); - let mut res = ws::Response::ok(f.content.into()); - { - let mut headers = res.headers_mut(); - headers.push(("Server".into(), b"Parity/SignerUI".to_vec())); - headers.push(("Connection".into(), b"Closed".to_vec())); - headers.push(("Content-Length".into(), content_len.as_bytes().to_vec())); - headers.push(("Content-Type".into(), f.mime.as_bytes().to_vec())); - if !f.safe_to_embed { - headers.push(("X-Frame-Options".into(), b"SAMEORIGIN".to_vec())); - } - } - Ok(res) - }) + |f| add_headers(ws::Response::ok(f.content.into()), &f.mime) + )) } fn on_message(&mut self, msg: ws::Message) -> ws::Result<()> { diff --git a/sync/Cargo.toml b/sync/Cargo.toml index c77749c39..10edcd0ed 100644 --- a/sync/Cargo.toml +++ b/sync/Cargo.toml @@ -1,7 +1,7 @@ [package] description = "Ethcore blockchain sync" name = "ethsync" -version = "1.2.0" +version = "1.3.0" license = "GPL-3.0" authors = ["Ethcore ) { + pub fn insert_bodies(&mut self, bodies: Vec) -> usize { + let mut inserted = 0; for b in bodies.into_iter() { if let Err(e) = self.insert_body(b) { trace!(target: "sync", "Ignored invalid body: {:?}", e); } + else { + inserted += 1; + } } + inserted } /// Returns a set of block hashes that require a body download. The returned set is marked as being downloaded. @@ -231,13 +236,19 @@ impl BlockCollection { Some(ref mut block) => { trace!(target: "sync", "Got body {}", h); block.body = Some(body.as_raw().to_vec()); + Ok(()) }, - None => warn!("Got body with no header {}", h) + None => { + warn!("Got body with no header {}", h); + Err(UtilError::Network(NetworkError::BadProtocol)) + } } } - None => trace!(target: "sync", "Ignored unknown/stale block body") - }; - Ok(()) + None => { + trace!(target: "sync", "Ignored unknown/stale block body"); + Err(UtilError::Network(NetworkError::BadProtocol)) + } + } } fn insert_header(&mut self, header: Bytes) -> Result { @@ -265,7 +276,7 @@ impl BlockCollection { if header_id.transactions_root == rlp::SHA3_NULL_RLP && header_id.uncles == rlp::SHA3_EMPTY_LIST_RLP { // empty body, just mark as downloaded let mut body_stream = RlpStream::new_list(2); - body_stream.append_raw(&rlp::NULL_RLP, 1); + body_stream.append_raw(&rlp::EMPTY_LIST_RLP, 1); body_stream.append_raw(&rlp::EMPTY_LIST_RLP, 1); block.body = Some(body_stream.out()); } @@ -284,6 +295,10 @@ impl BlockCollection { let old_subchains: HashSet<_> = { self.heads.iter().cloned().collect() }; for s in self.heads.drain(..) { let mut h = s.clone(); + if !self.blocks.contains_key(&h) { + new_heads.push(h); + continue; + } loop { match self.parents.get(&h) { Some(next) => { @@ -383,7 +398,7 @@ mod test { assert_eq!(&bc.drain()[..], &blocks[6..16]); assert_eq!(hashes[15], bc.heads[0]); - bc.insert_headers(headers[16..].to_vec()); + bc.insert_headers(headers[15..].to_vec()); bc.drain(); assert!(bc.is_empty()); } @@ -409,5 +424,24 @@ mod test { assert!(bc.head.is_some()); assert_eq!(hashes[21], bc.heads[0]); } + + #[test] + fn insert_headers_no_gap() { + let mut bc = BlockCollection::new(); + assert!(is_empty(&bc)); + let client = TestBlockChainClient::new(); + let nblocks = 200; + client.add_blocks(nblocks, EachBlockWith::Nothing); + let blocks: Vec<_> = (0 .. nblocks).map(|i| (&client as &BlockChainClient).block(BlockID::Number(i as BlockNumber)).unwrap()).collect(); + let headers: Vec<_> = blocks.iter().map(|b| Rlp::new(b).at(0).as_raw().to_vec()).collect(); + let hashes: Vec<_> = headers.iter().map(|h| HeaderView::new(h).sha3()).collect(); + let heads: Vec<_> = hashes.iter().enumerate().filter_map(|(i, h)| if i % 20 == 0 { Some(h.clone()) } else { None }).collect(); + bc.reset_to(heads); + + bc.insert_headers(headers[1..2].to_vec()); + assert!(bc.drain().is_empty()); + bc.insert_headers(headers[0..1].to_vec()); + assert_eq!(bc.drain().len(), 2); + } } diff --git a/sync/src/chain.rs b/sync/src/chain.rs index 277be7fea..aa3657419 100644 --- a/sync/src/chain.rs +++ b/sync/src/chain.rs @@ -95,12 +95,12 @@ use ethcore::views::{HeaderView, BlockView}; use ethcore::header::{BlockNumber, Header as BlockHeader}; use ethcore::client::{BlockChainClient, BlockStatus, BlockID, BlockChainInfo}; use ethcore::error::*; -use ethcore::transaction::SignedTransaction; use ethcore::block::Block; use io::SyncIo; use time; use super::SyncConfig; use blocks::BlockCollection; +use rand::{thread_rng, Rng}; known_heap_size!(0, PeerInfo); @@ -118,6 +118,9 @@ const MIN_PEERS_PROPAGATION: usize = 4; const MAX_PEERS_PROPAGATION: usize = 128; const MAX_PEER_LAG_PROPAGATION: BlockNumber = 20; const SUBCHAIN_SIZE: usize = 64; +const MAX_ROUND_PARENTS: usize = 32; +const MAX_NEW_HASHES: usize = 64; +const MAX_TX_TO_IMPORT: usize = 512; const STATUS_PACKET: u8 = 0x00; const NEW_BLOCK_HASHES_PACKET: u8 = 0x01; @@ -238,6 +241,8 @@ pub struct ChainSync { _max_download_ahead_blocks: usize, /// Number of blocks imported this round imported_this_round: Option, + /// Block parents imported this round (hash, parent) + round_parents: VecDeque<(H256, H256)>, /// Network ID network_id: U256, } @@ -260,6 +265,7 @@ impl ChainSync { syncing_difficulty: U256::from(0u64), last_sent_block_number: 0, imported_this_round: None, + round_parents: VecDeque::new(), _max_download_ahead_blocks: max(MAX_HEADERS_TO_REQUEST, config.max_download_ahead_blocks), network_id: config.network_id, }; @@ -281,11 +287,9 @@ impl ChainSync { num_peers: self.peers.len(), num_active_peers: self.peers.values().filter(|p| p.asking != PeerAsking::Nothing).count(), mem_used: - // TODO: https://github.com/servo/heapsize/pull/50 - //+ self.downloading_bodies.heap_size_of_children() - //+ self.downloading_headers.heap_size_of_children() self.blocks.heap_size() - + self.peers.heap_size_of_children(), + + self.peers.heap_size_of_children() + + self.round_parents.heap_size_of_children(), } } @@ -305,7 +309,6 @@ impl ChainSync { } self.syncing_difficulty = From::from(0u64); self.state = SyncState::Idle; - self.blocks.clear(); self.active_peers = self.peers.keys().cloned().collect(); } @@ -319,6 +322,7 @@ impl ChainSync { /// Remove peer from active peer set fn deactivate_peer(&mut self, io: &mut SyncIo, peer_id: PeerId) { + trace!(target: "sync", "Deactivating peer {}", peer_id); self.active_peers.remove(&peer_id); if self.active_peers.is_empty() { trace!(target: "sync", "No more active peers"); @@ -355,9 +359,13 @@ impl ChainSync { }; trace!(target: "sync", "New peer {} (protocol: {}, network: {:?}, difficulty: {:?}, latest:{}, genesis:{})", peer_id, peer.protocol_version, peer.network_id, peer.difficulty, peer.latest_hash, peer.genesis); + if io.is_expired() { + trace!(target: "sync", "Status packet from expired session {}:{}", peer_id, io.peer_info(peer_id)); + return Ok(()); + } if self.peers.contains_key(&peer_id) { - warn!("Unexpected status packet from {}:{}", peer_id, io.peer_info(peer_id)); + debug!(target: "sync", "Unexpected status packet from {}:{}", peer_id, io.peer_info(peer_id)); return Ok(()); } let chain_info = io.chain().chain_info(); @@ -383,14 +391,15 @@ impl ChainSync { /// Called by peer once it has new block headers during sync fn on_peer_block_headers(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { self.clear_peer_download(peer_id); + let expected_hash = self.peers.get(&peer_id).and_then(|p| p.asking_hash); let expected_asking = if self.state == SyncState::ChainHead { PeerAsking::Heads } else { PeerAsking::BlockHeaders }; - if !self.reset_peer_asking(peer_id, expected_asking) { + if !self.reset_peer_asking(peer_id, expected_asking) || expected_hash.is_none() { trace!(target: "sync", "Ignored unexpected headers"); self.continue_sync(io); return Ok(()); } let item_count = r.item_count(); - trace!(target: "sync", "{} -> BlockHeaders ({} entries)", peer_id, item_count); + trace!(target: "sync", "{} -> BlockHeaders ({} entries), state = {:?}", peer_id, item_count, self.state); if self.state == SyncState::Idle { trace!(target: "sync", "Ignored unexpected block headers"); self.continue_sync(io); @@ -403,14 +412,22 @@ impl ChainSync { } if item_count == 0 && (self.state == SyncState::Blocks || self.state == SyncState::NewBlocks) { self.deactivate_peer(io, peer_id); //TODO: is this too harsh? + self.continue_sync(io); return Ok(()); } let mut headers = Vec::new(); let mut hashes = Vec::new(); + let mut valid_response = item_count == 0; //empty response is valid for i in 0..item_count { let info: BlockHeader = try!(r.val_at(i)); let number = BlockNumber::from(info.number); + // Check if any of the headers matches the hash we requested + if !valid_response { + if let Some(expected) = expected_hash { + valid_response = expected == info.hash() + } + } if self.blocks.contains(&info.hash()) { trace!(target: "sync", "Skipping existing block header {} ({:?})", number, info.hash()); continue; @@ -441,6 +458,17 @@ impl ChainSync { } } + // Disable the peer for this syncing round if it gives invalid chain + if !valid_response { + trace!(target: "sync", "{} Deactivated for invalid headers response", peer_id); + self.deactivate_peer(io, peer_id); + } + + if headers.is_empty() { + // Peer does not have any new subchain heads, deactivate it nd try with another + trace!(target: "sync", "{} Deactivated for no data", peer_id); + self.deactivate_peer(io, peer_id); + } match self.state { SyncState::ChainHead => { if headers.is_empty() { @@ -488,7 +516,10 @@ impl ChainSync { for i in 0..item_count { bodies.push(try!(r.at(i)).as_raw().to_vec()); } - self.blocks.insert_bodies(bodies); + if self.blocks.insert_bodies(bodies) != item_count { + trace!(target: "sync", "Deactivating peer for giving invalid block bodies"); + self.deactivate_peer(io, peer_id); + } self.collect_blocks(io); } self.continue_sync(io); @@ -502,57 +533,55 @@ impl ChainSync { let header_rlp = try!(block_rlp.at(0)); let h = header_rlp.as_raw().sha3(); trace!(target: "sync", "{} -> NewBlock ({})", peer_id, h); - if self.state != SyncState::Idle { - trace!(target: "sync", "NewBlock ignored while seeking"); - return Ok(()); - } let header: BlockHeader = try!(header_rlp.as_val()); + if header.number() > self.highest_block.unwrap_or(0) { + self.highest_block = Some(header.number()); + } let mut unknown = false; { let peer = self.peers.get_mut(&peer_id).unwrap(); peer.latest_hash = header.hash(); peer.latest_number = Some(header.number()); } - if header.number <= self.last_imported_block + 1 { - match io.chain().import_block(block_rlp.as_raw().to_vec()) { - Err(Error::Import(ImportError::AlreadyInChain)) => { - trace!(target: "sync", "New block already in chain {:?}", h); - }, - Err(Error::Import(ImportError::AlreadyQueued)) => { - trace!(target: "sync", "New block already queued {:?}", h); - }, - Ok(_) => { - if header.number == self.last_imported_block + 1 { - self.last_imported_block = header.number; - self.last_imported_hash = header.hash(); - } - trace!(target: "sync", "New block queued {:?} ({})", h, header.number); - }, - Err(Error::Block(BlockError::UnknownParent(p))) => { - unknown = true; - trace!(target: "sync", "New block with unknown parent ({:?}) {:?}", p, h); - }, - Err(e) => { - debug!(target: "sync", "Bad new block {:?} : {:?}", h, e); - io.disable_peer(peer_id); - } - }; - } - else { - unknown = true; - } - if unknown { - trace!(target: "sync", "New unknown block {:?}", h); - //TODO: handle too many unknown blocks - let difficulty: U256 = try!(r.val_at(1)); - if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { - if peer.difficulty.map_or(true, |pd| difficulty > pd) { - //self.state = SyncState::ChainHead; - peer.difficulty = Some(difficulty); - trace!(target: "sync", "Received block {:?} with no known parent. Peer needs syncing...", h); + match io.chain().import_block(block_rlp.as_raw().to_vec()) { + Err(Error::Import(ImportError::AlreadyInChain)) => { + trace!(target: "sync", "New block already in chain {:?}", h); + }, + Err(Error::Import(ImportError::AlreadyQueued)) => { + trace!(target: "sync", "New block already queued {:?}", h); + }, + Ok(_) => { + if header.number == self.last_imported_block + 1 { + self.last_imported_block = header.number; + self.last_imported_hash = header.hash(); } + trace!(target: "sync", "New block queued {:?} ({})", h, header.number); + }, + Err(Error::Block(BlockError::UnknownParent(p))) => { + unknown = true; + trace!(target: "sync", "New block with unknown parent ({:?}) {:?}", p, h); + }, + Err(e) => { + debug!(target: "sync", "Bad new block {:?} : {:?}", h, e); + io.disable_peer(peer_id); + } + }; + if unknown { + if self.state != SyncState::Idle { + trace!(target: "sync", "NewBlock ignored while seeking"); + } else { + trace!(target: "sync", "New unknown block {:?}", h); + //TODO: handle too many unknown blocks + let difficulty: U256 = try!(r.val_at(1)); + if let Some(ref mut peer) = self.peers.get_mut(&peer_id) { + if peer.difficulty.map_or(true, |pd| difficulty > pd) { + //self.state = SyncState::ChainHead; + peer.difficulty = Some(difficulty); + trace!(target: "sync", "Received block {:?} with no known parent. Peer needs syncing...", h); + } + } + self.sync_peer(io, peer_id, true); } - self.sync_peer(io, peer_id, true); } Ok(()) } @@ -561,15 +590,22 @@ impl ChainSync { fn on_peer_new_hashes(&mut self, io: &mut SyncIo, peer_id: PeerId, r: &UntrustedRlp) -> Result<(), PacketDecodeError> { if self.state != SyncState::Idle { trace!(target: "sync", "Ignoring new hashes since we're already downloading."); + let max = r.iter().take(MAX_NEW_HASHES).map(|item| item.val_at::(1).unwrap_or(0)).fold(0u64, max); + if max > self.highest_block.unwrap_or(0) { + self.highest_block = Some(max); + } return Ok(()); } trace!(target: "sync", "{} -> NewHashes ({} entries)", peer_id, r.item_count()); - let hashes = r.iter().map(|item| (item.val_at::(0), item.val_at::(1))); + let hashes = r.iter().take(MAX_NEW_HASHES).map(|item| (item.val_at::(0), item.val_at::(1))); let mut max_height: BlockNumber = 0; let mut new_hashes = Vec::new(); for (rh, rd) in hashes { let h = try!(rh); let d = try!(rd); + if d > self.highest_block.unwrap_or(0) { + self.highest_block = Some(d); + } if self.blocks.is_downloading(&h) { continue; } @@ -630,7 +666,8 @@ impl ChainSync { /// Resume downloading fn continue_sync(&mut self, io: &mut SyncIo) { let mut peers: Vec<(PeerId, U256)> = self.peers.iter().map(|(k, p)| (*k, p.difficulty.unwrap_or_else(U256::zero))).collect(); - peers.sort_by(|&(_, d1), &(_, d2)| d1.cmp(&d2).reverse()); //TODO: sort by rating + thread_rng().shuffle(&mut peers); //TODO: sort by rating + trace!(target: "sync", "Syncing with {}/{} peers", self.active_peers.len(), peers.len()); for (p, _) in peers { if self.active_peers.contains(&p) { self.sync_peer(io, p, false); @@ -655,7 +692,11 @@ impl ChainSync { } /// Find something to do for a peer. Called for a new peer or when a peer is done with it's task. - fn sync_peer(&mut self, io: &mut SyncIo, peer_id: PeerId, force: bool) { + fn sync_peer(&mut self, io: &mut SyncIo, peer_id: PeerId, force: bool) { + if !self.active_peers.contains(&peer_id) { + trace!(target: "sync", "Skipping deactivated peer"); + return; + } let (peer_latest, peer_difficulty) = { let peer = self.peers.get_mut(&peer_id).unwrap(); if peer.asking != PeerAsking::Nothing { @@ -703,18 +744,28 @@ impl ChainSync { trace!(target: "sync", "Starting round (last imported count = {:?}, block = {:?}", self.imported_this_round, self.last_imported_block); // Check if need to retract to find the common block. The problem is that the peers still return headers by hash even // from the non-canonical part of the tree. So we also retract if nothing has been imported last round. - if self.imported_this_round.is_some() && self.imported_this_round.unwrap() == 0 && self.last_imported_block > 0 { - match io.chain().block_hash(BlockID::Number(self.last_imported_block - 1)) { - Some(h) => { + match self.imported_this_round { + Some(n) if n == 0 && self.last_imported_block > 0 => { + // nothing was imported last round, step back to a previous block + // search parent in last round known parents first + if let Some(&(_, p)) = self.round_parents.iter().find(|&&(h, _)| h == self.last_imported_hash) { self.last_imported_block -= 1; - self.last_imported_hash = h; - trace!(target: "sync", "Searching common header {} ({})", self.last_imported_block, self.last_imported_hash); + self.last_imported_hash = p.clone(); + trace!(target: "sync", "Searching common header from the last round {} ({})", self.last_imported_block, self.last_imported_hash); + } else { + match io.chain().block_hash(BlockID::Number(self.last_imported_block - 1)) { + Some(h) => { + self.last_imported_block -= 1; + self.last_imported_hash = h; + trace!(target: "sync", "Searching common header in the blockchain {} ({})", self.last_imported_block, self.last_imported_hash); + } + None => { + debug!(target: "sync", "Could not revert to previous block, last: {} ({})", self.last_imported_block, self.last_imported_hash); + } + } } - None => { - // TODO: get hash by number from the block queue - trace!(target: "sync", "Could not revert to previous block, last: {} ({})", self.last_imported_block, self.last_imported_hash); - } - } + }, + _ => (), } self.imported_this_round = None; } @@ -761,6 +812,15 @@ impl ChainSync { peer.asking_blocks.clear(); } + fn block_imported(&mut self, hash: &H256, number: BlockNumber, parent: &H256) { + self.last_imported_block = number; + self.last_imported_hash = hash.clone(); + self.round_parents.push_back((hash.clone(), parent.clone())); + if self.round_parents.len() > MAX_ROUND_PARENTS { + self.round_parents.pop_front(); + } + } + /// Checks if there are blocks fully downloaded that can be imported into the blockchain and does the import. fn collect_blocks(&mut self, io: &mut SyncIo) { let mut restart = false; @@ -768,8 +828,10 @@ impl ChainSync { let blocks = self.blocks.drain(); let count = blocks.len(); for block in blocks { - let number = BlockView::new(&block).header_view().number(); - let h = BlockView::new(&block).header_view().sha3(); + let (h, number, parent) = { + let header = BlockView::new(&block).header_view(); + (header.sha3(), header.number(), header.parent_hash()) + }; // Perform basic block verification if !Block::is_good(&block) { @@ -780,20 +842,17 @@ impl ChainSync { match io.chain().import_block(block) { Err(Error::Import(ImportError::AlreadyInChain)) => { - self.last_imported_block = number; - self.last_imported_hash = h.clone(); trace!(target: "sync", "Block already in chain {:?}", h); + self.block_imported(&h, number, &parent); }, Err(Error::Import(ImportError::AlreadyQueued)) => { - self.last_imported_block = number; - self.last_imported_hash = h.clone(); trace!(target: "sync", "Block already queued {:?}", h); + self.block_imported(&h, number, &parent); }, Ok(_) => { trace!(target: "sync", "Block queued {:?}", h); - self.last_imported_block = number; - self.last_imported_hash = h.clone(); imported.insert(h.clone()); + self.block_imported(&h, number, &parent); }, Err(Error::Block(BlockError::UnknownParent(_))) if self.state == SyncState::NewBlocks => { trace!(target: "sync", "Unknown new block parent, restarting sync"); @@ -831,6 +890,9 @@ impl ChainSync { rlp.append(&skip); rlp.append(&if reverse {1u32} else {0u32}); self.send_request(sync, peer_id, asking, GET_BLOCK_HEADERS_PACKET, rlp.out()); + self.peers.get_mut(&peer_id) + .expect("peer_id may originate either from on_packet, where it is already validated or from enumerating self.peers. qed") + .asking_hash = Some(h.clone()); } /// Request block bodies from a peer @@ -886,15 +948,15 @@ impl ChainSync { return Ok(()); } - let item_count = r.item_count(); + let mut item_count = r.item_count(); trace!(target: "sync", "{} -> Transactions ({} entries)", peer_id, item_count); - + item_count = min(item_count, MAX_TX_TO_IMPORT); let mut transactions = Vec::with_capacity(item_count); - for i in 0..item_count { - let tx: SignedTransaction = try!(r.val_at(i)); + for i in 0 .. item_count { + let tx = try!(r.at(i)).as_raw().to_vec(); transactions.push(tx); } - let _ = io.chain().import_transactions(transactions); + io.chain().queue_transactions(transactions); Ok(()) } @@ -911,7 +973,7 @@ impl ChainSync { } /// Respond to GetBlockHeaders request - fn return_block_headers(io: &SyncIo, r: &UntrustedRlp) -> RlpResponseResult { + fn return_block_headers(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { // Packet layout: // [ block: { P , B_32 }, maxHeaders: P, skip: P, reverse: P in { 0 , 1 } ] let max_headers: usize = try!(r.val_at(1)); @@ -921,13 +983,25 @@ impl ChainSync { let number = if try!(r.at(0)).size() == 32 { // id is a hash let hash: H256 = try!(r.val_at(0)); - trace!(target: "sync", "-> GetBlockHeaders (hash: {}, max: {}, skip: {}, reverse:{})", hash, max_headers, skip, reverse); + trace!(target: "sync", "{} -> GetBlockHeaders (hash: {}, max: {}, skip: {}, reverse:{})", peer_id, hash, max_headers, skip, reverse); match io.chain().block_header(BlockID::Hash(hash)) { - Some(hdr) => From::from(HeaderView::new(&hdr).number()), + Some(hdr) => { + let number = From::from(HeaderView::new(&hdr).number()); + debug_assert_eq!(HeaderView::new(&hdr).sha3(), hash); + if max_headers == 1 || io.chain().block_hash(BlockID::Number(number)) != Some(hash) { + // Non canonical header or single header requested + // TODO: handle single-step reverse hashchains of non-canon hashes + trace!(target:"sync", "Returning single header: {:?}", hash); + let mut rlp = RlpStream::new_list(1); + rlp.append_raw(&hdr, 1); + return Ok(Some((BLOCK_HEADERS_PACKET, rlp))); + } + number + } None => return Ok(Some((BLOCK_HEADERS_PACKET, RlpStream::new_list(0)))) //no such header, return nothing } } else { - trace!(target: "sync", "-> GetBlockHeaders (number: {}, max: {}, skip: {}, reverse:{})", try!(r.val_at::(0)), max_headers, skip, reverse); + trace!(target: "sync", "{} -> GetBlockHeaders (number: {}, max: {}, skip: {}, reverse:{})", peer_id, try!(r.val_at::(0)), max_headers, skip, reverse); try!(r.val_at(0)) }; @@ -962,13 +1036,13 @@ impl ChainSync { } /// Respond to GetBlockBodies request - fn return_block_bodies(io: &SyncIo, r: &UntrustedRlp) -> RlpResponseResult { + fn return_block_bodies(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { let mut count = r.item_count(); if count == 0 { debug!(target: "sync", "Empty GetBlockBodies request, ignoring."); return Ok(None); } - trace!(target: "sync", "-> GetBlockBodies: {} entries", count); + trace!(target: "sync", "{} -> GetBlockBodies: {} entries", peer_id, count); count = min(count, MAX_BODIES_TO_SEND); let mut added = 0usize; let mut data = Bytes::new(); @@ -985,8 +1059,9 @@ impl ChainSync { } /// Respond to GetNodeData request - fn return_node_data(io: &SyncIo, r: &UntrustedRlp) -> RlpResponseResult { + fn return_node_data(io: &SyncIo, r: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { let mut count = r.item_count(); + trace!(target: "sync", "{} -> GetNodeData: {} entries", peer_id, count); if count == 0 { debug!(target: "sync", "Empty GetNodeData request, ignoring."); return Ok(None); @@ -1000,13 +1075,15 @@ impl ChainSync { added += 1; } } + trace!(target: "sync", "{} -> GetNodeData: return {} entries", peer_id, added); let mut rlp = RlpStream::new_list(added); rlp.append_raw(&data, added); Ok(Some((NODE_DATA_PACKET, rlp))) } - fn return_receipts(io: &SyncIo, rlp: &UntrustedRlp) -> RlpResponseResult { + fn return_receipts(io: &SyncIo, rlp: &UntrustedRlp, peer_id: PeerId) -> RlpResponseResult { let mut count = rlp.item_count(); + trace!(target: "sync", "{} -> GetReceipts: {} entries", peer_id, count); if count == 0 { debug!(target: "sync", "Empty GetReceipts request, ignoring."); return Ok(None); @@ -1028,11 +1105,11 @@ impl ChainSync { Ok(Some((RECEIPTS_PACKET, rlp_result))) } - fn return_rlp(&self, io: &mut SyncIo, rlp: &UntrustedRlp, rlp_func: FRlp, error_func: FError) -> Result<(), PacketDecodeError> - where FRlp : Fn(&SyncIo, &UntrustedRlp) -> RlpResponseResult, + fn return_rlp(io: &mut SyncIo, rlp: &UntrustedRlp, peer: PeerId, rlp_func: FRlp, error_func: FError) -> Result<(), PacketDecodeError> + where FRlp : Fn(&SyncIo, &UntrustedRlp, PeerId) -> RlpResponseResult, FError : FnOnce(UtilError) -> String { - let response = rlp_func(io, rlp); + let response = rlp_func(io, rlp, peer); match response { Err(e) => Err(e), Ok(Some((packet_id, rlp_stream))) => { @@ -1045,13 +1122,41 @@ impl ChainSync { } /// Dispatch incoming requests and responses - pub fn on_packet(&mut self, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { + pub fn dispatch_packet(sync: &RwLock, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { let rlp = UntrustedRlp::new(data); + let result = match packet_id { + GET_BLOCK_BODIES_PACKET => ChainSync::return_rlp(io, &rlp, peer, + ChainSync::return_block_bodies, + |e| format!("Error sending block bodies: {:?}", e)), + GET_BLOCK_HEADERS_PACKET => ChainSync::return_rlp(io, &rlp, peer, + ChainSync::return_block_headers, + |e| format!("Error sending block headers: {:?}", e)), + + GET_RECEIPTS_PACKET => ChainSync::return_rlp(io, &rlp, peer, + ChainSync::return_receipts, + |e| format!("Error sending receipts: {:?}", e)), + + GET_NODE_DATA_PACKET => ChainSync::return_rlp(io, &rlp, peer, + ChainSync::return_node_data, + |e| format!("Error sending nodes: {:?}", e)), + + _ => { + sync.write().unwrap().on_packet(io, peer, packet_id, data); + Ok(()) + } + }; + result.unwrap_or_else(|e| { + debug!(target:"sync", "{} -> Malformed packet {} : {}", peer, packet_id, e); + }) + } + + pub fn on_packet(&mut self, io: &mut SyncIo, peer: PeerId, packet_id: u8, data: &[u8]) { if packet_id != STATUS_PACKET && !self.peers.contains_key(&peer) { debug!(target:"sync", "Unexpected packet from unregistered peer: {}:{}", peer, io.peer_info(peer)); return; } + let rlp = UntrustedRlp::new(data); let result = match packet_id { STATUS_PACKET => self.on_peer_status(io, peer, &rlp), TRANSACTIONS_PACKET => self.on_peer_transactions(io, peer, &rlp), @@ -1059,23 +1164,6 @@ impl ChainSync { BLOCK_BODIES_PACKET => self.on_peer_block_bodies(io, peer, &rlp), NEW_BLOCK_PACKET => self.on_peer_new_block(io, peer, &rlp), NEW_BLOCK_HASHES_PACKET => self.on_peer_new_hashes(io, peer, &rlp), - - GET_BLOCK_BODIES_PACKET => self.return_rlp(io, &rlp, - ChainSync::return_block_bodies, - |e| format!("Error sending block bodies: {:?}", e)), - - GET_BLOCK_HEADERS_PACKET => self.return_rlp(io, &rlp, - ChainSync::return_block_headers, - |e| format!("Error sending block headers: {:?}", e)), - - GET_RECEIPTS_PACKET => self.return_rlp(io, &rlp, - ChainSync::return_receipts, - |e| format!("Error sending receipts: {:?}", e)), - - GET_NODE_DATA_PACKET => self.return_rlp(io, &rlp, - ChainSync::return_node_data, - |e| format!("Error sending nodes: {:?}", e)), - _ => { debug!(target: "sync", "Unknown packet {}", packet_id); Ok(()) @@ -1086,14 +1174,19 @@ impl ChainSync { }) } - pub fn maintain_peers(&self, io: &mut SyncIo) { + pub fn maintain_peers(&mut self, io: &mut SyncIo) { let tick = time::precise_time_s(); + let mut aborting = Vec::new(); for (peer_id, peer) in &self.peers { if peer.asking != PeerAsking::Nothing && (tick - peer.ask_time) > CONNECTION_TIMEOUT_SEC { - trace!(target:"sync", "Timeouted {}", peer_id); + trace!(target:"sync", "Timeout {}", peer_id); io.disconnect_peer(*peer_id); + aborting.push(*peer_id); } } + for p in aborting { + self.on_peer_aborting(io, p); + } } fn check_resume(&mut self, io: &mut SyncIo) { @@ -1116,10 +1209,11 @@ impl ChainSync { let mut rlp_stream = RlpStream::new_list(blocks.len()); for block_hash in blocks { let mut hash_rlp = RlpStream::new_list(2); - let difficulty = chain.block_total_difficulty(BlockID::Hash(block_hash.clone())).expect("Malformed block without a difficulty on the chain!"); + let number = HeaderView::new(&chain.block_header(BlockID::Hash(block_hash.clone())) + .expect("chain.tree_route and chain.find_uncles only return hahses of blocks that are in the blockchain. qed.")).number(); hash_rlp.append(&block_hash); - hash_rlp.append(&difficulty); - rlp_stream.append_raw(&hash_rlp.out(), 1); + hash_rlp.append(&number); + rlp_stream.append_raw(hash_rlp.as_raw(), 1); } Some(rlp_stream.out()) } @@ -1171,6 +1265,7 @@ impl ChainSync { /// propagates latest block to lagging peers fn propagate_blocks(&mut self, chain_info: &BlockChainInfo, io: &mut SyncIo) -> usize { let lucky_peers = self.select_lagging_peers(chain_info, io); + trace!(target: "sync", "Sending NewBlocks to {:?}", lucky_peers); let mut sent = 0; for (peer_id, _) in lucky_peers { let rlp = ChainSync::create_latest_block_rlp(io.chain()); @@ -1185,6 +1280,7 @@ impl ChainSync { /// propagates new known hashes to all peers fn propagate_new_hashes(&mut self, chain_info: &BlockChainInfo, io: &mut SyncIo) -> usize { let lucky_peers = self.select_lagging_peers(chain_info, io); + trace!(target: "sync", "Sending NewHashes to {:?}", lucky_peers); let mut sent = 0; let last_parent = HeaderView::new(&io.chain().block_header(BlockID::Hash(chain_info.best_block_hash.clone())).unwrap()).parent_hash(); for (peer_id, peer_number) in lucky_peers { @@ -1218,7 +1314,7 @@ impl ChainSync { return 0; } - let mut transactions = io.chain().all_transactions(); + let mut transactions = io.chain().pending_transactions(); if transactions.is_empty() { return 0; } @@ -1268,7 +1364,7 @@ impl ChainSync { self.check_resume(io); } - /// called when block is imported to chain, updates transactions queue and propagates the blocks + /// called when block is imported to chain, updates transactions queue and propagates the blocks pub fn chain_new_blocks(&mut self, io: &mut SyncIo, _imported: &[H256], invalid: &[H256], _enacted: &[H256], _retracted: &[H256]) { if io.is_chain_queue_empty() { // Propagate latests blocks @@ -1338,7 +1434,7 @@ mod tests { let mut queue = VecDeque::new(); let io = TestIo::new(&mut client, &mut queue, None); - let result = ChainSync::return_receipts(&io, &UntrustedRlp::new(&[0xc0])); + let result = ChainSync::return_receipts(&io, &UntrustedRlp::new(&[0xc0]), 0); assert!(result.is_ok()); } @@ -1347,7 +1443,7 @@ mod tests { fn return_receipts() { let mut client = TestBlockChainClient::new(); let mut queue = VecDeque::new(); - let mut sync = dummy_sync_with_peer(H256::new(), &client); + let sync = dummy_sync_with_peer(H256::new(), &client); let mut io = TestIo::new(&mut client, &mut queue, None); let mut receipt_list = RlpStream::new_list(4); @@ -1358,7 +1454,7 @@ mod tests { let receipts_request = receipt_list.out(); // it returns rlp ONLY for hashes started with "f" - let result = ChainSync::return_receipts(&io, &UntrustedRlp::new(&receipts_request.clone())); + let result = ChainSync::return_receipts(&io, &UntrustedRlp::new(&receipts_request.clone()), 0); assert!(result.is_ok()); let rlp_result = result.unwrap(); @@ -1368,7 +1464,7 @@ mod tests { assert_eq!(603, rlp_result.unwrap().1.out().len()); io.sender = Some(2usize); - sync.on_packet(&mut io, 0usize, super::GET_RECEIPTS_PACKET, &receipts_request); + ChainSync::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, super::GET_RECEIPTS_PACKET, &receipts_request); assert_eq!(1, io.queue.len()); } @@ -1406,33 +1502,33 @@ mod tests { let io = TestIo::new(&mut client, &mut queue, None); let unknown: H256 = H256::new(); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&unknown, 1, 0, false))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&unknown, 1, 0, false)), 0); assert!(to_header_vec(result).is_empty()); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&unknown, 1, 0, true))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&unknown, 1, 0, true)), 0); assert!(to_header_vec(result).is_empty()); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[2], 1, 0, true))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[2], 1, 0, true)), 0); assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[2], 1, 0, false))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[2], 1, 0, false)), 0); assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[50], 3, 5, false))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[50], 3, 5, false)), 0); assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[56].clone(), headers[62].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[50], 3, 5, true))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_hash_req(&hashes[50], 3, 5, true)), 0); assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[44].clone(), headers[38].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(2, 1, 0, true))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(2, 1, 0, true)), 0); assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(2, 1, 0, false))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(2, 1, 0, false)), 0); assert_eq!(to_header_vec(result), vec![headers[2].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(50, 3, 5, false))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(50, 3, 5, false)), 0); assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[56].clone(), headers[62].clone()]); - let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(50, 3, 5, true))); + let result = ChainSync::return_block_headers(&io, &UntrustedRlp::new(&make_num_req(50, 3, 5, true)), 0); assert_eq!(to_header_vec(result), vec![headers[50].clone(), headers[44].clone(), headers[38].clone()]); } @@ -1440,7 +1536,7 @@ mod tests { fn return_nodes() { let mut client = TestBlockChainClient::new(); let mut queue = VecDeque::new(); - let mut sync = dummy_sync_with_peer(H256::new(), &client); + let sync = dummy_sync_with_peer(H256::new(), &client); let mut io = TestIo::new(&mut client, &mut queue, None); let mut node_list = RlpStream::new_list(3); @@ -1450,7 +1546,7 @@ mod tests { let node_request = node_list.out(); // it returns rlp ONLY for hashes started with "f" - let result = ChainSync::return_node_data(&io, &UntrustedRlp::new(&node_request.clone())); + let result = ChainSync::return_node_data(&io, &UntrustedRlp::new(&node_request.clone()), 0); assert!(result.is_ok()); let rlp_result = result.unwrap(); @@ -1460,7 +1556,8 @@ mod tests { assert_eq!(34, rlp_result.unwrap().1.out().len()); io.sender = Some(2usize); - sync.on_packet(&mut io, 0usize, super::GET_NODE_DATA_PACKET, &node_request); + + ChainSync::dispatch_packet(&RwLock::new(sync), &mut io, 0usize, super::GET_NODE_DATA_PACKET, &node_request); assert_eq!(1, io.queue.len()); } diff --git a/sync/src/io.rs b/sync/src/io.rs index 53a546e1c..5d4b32464 100644 --- a/sync/src/io.rs +++ b/sync/src/io.rs @@ -41,6 +41,8 @@ pub trait SyncIo { fn is_chain_queue_empty(&self) -> bool { self.chain().queue_info().is_empty() } + /// Check if the session is expired + fn is_expired(&self) -> bool; } /// Wraps `NetworkContext` and the blockchain client @@ -83,6 +85,10 @@ impl<'s, 'h> SyncIo for NetSyncIo<'s, 'h> { fn peer_info(&self, peer_id: PeerId) -> String { self.network.peer_info(peer_id) } + + fn is_expired(&self) -> bool { + self.network.is_expired() + } } diff --git a/sync/src/lib.rs b/sync/src/lib.rs index 9c7da71ab..9bd10cb95 100644 --- a/sync/src/lib.rs +++ b/sync/src/lib.rs @@ -41,11 +41,19 @@ //! use ethcore::miner::Miner; //! //! fn main() { -//! let mut service = NetworkService::start(NetworkConfiguration::new()).unwrap(); +//! let mut service = NetworkService::new(NetworkConfiguration::new()).unwrap(); +//! service.start().unwrap(); //! let dir = env::temp_dir(); -//! let client = Client::new(ClientConfig::default(), ethereum::new_frontier(), &dir, Arc::new(Miner::default()), service.io().channel()).unwrap(); -//! let miner = Miner::new(false, ethereum::new_frontier()); -//! EthSync::register(&mut service, SyncConfig::default(), client); +//! let miner = Miner::new(Default::default(), ethereum::new_frontier(true), None); +//! let client = Client::new( +//! ClientConfig::default(), +//! ethereum::new_frontier(true), +//! &dir, +//! miner, +//! service.io().channel() +//! ).unwrap(); +//! let sync = EthSync::new(SyncConfig::default(), client); +//! EthSync::register(&mut service, sync); //! } //! ``` @@ -66,8 +74,10 @@ use util::network::{NetworkProtocolHandler, NetworkService, NetworkContext, Peer use util::TimerToken; use util::{U256, ONE_U256}; use ethcore::client::Client; -use ethcore::service::SyncMessage; +use ethcore::service::{SyncMessage, NetSyncMessage}; use io::NetSyncIo; +use util::io::IoChannel; +use util::{NetworkIoMessage, NetworkError}; use chain::ChainSync; mod chain; @@ -98,6 +108,10 @@ impl Default for SyncConfig { pub trait SyncProvider: Send + Sync { /// Get sync status fn status(&self) -> SyncStatus; + /// Start the network + fn start_network(&self); + /// Stop the network + fn stop_network(&self); } /// Ethereum network protocol handler @@ -105,21 +119,27 @@ pub struct EthSync { /// Shared blockchain client. TODO: this should evetually become an IPC endpoint chain: Arc, /// Sync strategy - sync: RwLock + sync: RwLock, + /// IO communication chnnel. + io_channel: RwLock>, } pub use self::chain::{SyncStatus, SyncState}; impl EthSync { /// Creates and register protocol with the network service - pub fn register(service: &mut NetworkService, config: SyncConfig, chain: Arc) -> Arc { + pub fn new(config: SyncConfig, chain: Arc) -> Arc { let sync = ChainSync::new(config, chain.deref()); - let sync = Arc::new(EthSync { + Arc::new(EthSync { chain: chain, sync: RwLock::new(sync), - }); - service.register_protocol(sync.clone(), "eth", &[62u8, 63u8]).expect("Error registering eth protocol handler"); - sync + io_channel: RwLock::new(IoChannel::disconnected()), + }) + } + + /// Register protocol with the network service + pub fn register(service: &NetworkService, sync: Arc) -> Result<(), NetworkError> { + service.register_protocol(sync.clone(), "eth", &[62u8, 63u8]) } /// Stop sync @@ -138,15 +158,26 @@ impl SyncProvider for EthSync { fn status(&self) -> SyncStatus { self.sync.read().unwrap().status() } + + fn start_network(&self) { + self.io_channel.read().unwrap().send(NetworkIoMessage::User(SyncMessage::StartNetwork)) + .unwrap_or_else(|e| warn!("Error sending IO notification: {:?}", e)); + } + + fn stop_network(&self) { + self.io_channel.read().unwrap().send(NetworkIoMessage::User(SyncMessage::StopNetwork)) + .unwrap_or_else(|e| warn!("Error sending IO notification: {:?}", e)); + } } impl NetworkProtocolHandler for EthSync { fn initialize(&self, io: &NetworkContext) { io.register_timer(0, 1000).expect("Error registering sync timer"); + *self.io_channel.write().unwrap() = io.io_channel(); } fn read(&self, io: &NetworkContext, peer: &PeerId, packet_id: u8, data: &[u8]) { - self.sync.write().unwrap().on_packet(&mut NetSyncIo::new(io, self.chain.deref()) , *peer, packet_id, data); + ChainSync::dispatch_packet(&self.sync, &mut NetSyncIo::new(io, self.chain.deref()) , *peer, packet_id, data); } fn connected(&self, io: &NetworkContext, peer: &PeerId) { diff --git a/sync/src/tests/chain.rs b/sync/src/tests/chain.rs index 09e83e358..2f2bde171 100644 --- a/sync/src/tests/chain.rs +++ b/sync/src/tests/chain.rs @@ -47,7 +47,7 @@ fn status_after_sync() { net.peer_mut(1).chain.add_blocks(1000, EachBlockWith::Uncle); net.peer_mut(2).chain.add_blocks(1000, EachBlockWith::Uncle); net.sync(); - let status = net.peer(0).sync.status(); + let status = net.peer(0).sync.read().unwrap().status(); assert_eq!(status.state, SyncState::Idle); } @@ -107,14 +107,14 @@ fn restart() { assert!(net.peer(0).chain.chain_info().best_block_number > 100); net.restart_peer(0); - let status = net.peer(0).sync.status(); + let status = net.peer(0).sync.read().unwrap().status(); assert_eq!(status.state, SyncState::ChainHead); } #[test] fn status_empty() { let net = TestNet::new(2); - assert_eq!(net.peer(0).sync.status().state, SyncState::Idle); + assert_eq!(net.peer(0).sync.read().unwrap().status().state, SyncState::Idle); } #[test] @@ -192,3 +192,13 @@ fn restart_on_broken_chain() { assert_eq!(net.peer(0).chain.chain_info().best_block_number, 5); } + +#[test] +fn high_td_attach() { + let mut net = TestNet::new(2); + net.peer_mut(1).chain.add_blocks(10, EachBlockWith::Uncle); + net.peer_mut(1).chain.corrupt_block_parent(6); + net.sync_steps(20); + + assert_eq!(net.peer(0).chain.chain_info().best_block_number, 5); +} diff --git a/sync/src/tests/helpers.rs b/sync/src/tests/helpers.rs index a9163b52e..831976048 100644 --- a/sync/src/tests/helpers.rs +++ b/sync/src/tests/helpers.rs @@ -43,6 +43,10 @@ impl<'p> SyncIo for TestIo<'p> { fn disconnect_peer(&mut self, _peer_id: PeerId) { } + fn is_expired(&self) -> bool { + false + } + fn respond(&mut self, packet_id: PacketId, data: Vec) -> Result<(), UtilError> { self.queue.push_back(TestPacket { data: data, @@ -74,7 +78,7 @@ pub struct TestPacket { pub struct TestPeer { pub chain: TestBlockChainClient, - pub sync: ChainSync, + pub sync: RwLock, pub queue: VecDeque, } @@ -93,7 +97,7 @@ impl TestNet { let chain = TestBlockChainClient::new(); let sync = ChainSync::new(SyncConfig::default(), &chain); net.peers.push(TestPeer { - sync: sync, + sync: RwLock::new(sync), chain: chain, queue: VecDeque::new(), }); @@ -114,7 +118,7 @@ impl TestNet { for client in 0..self.peers.len() { if peer != client { let mut p = self.peers.get_mut(peer).unwrap(); - p.sync.on_peer_connected(&mut TestIo::new(&mut p.chain, &mut p.queue, Some(client as PeerId)), client as PeerId); + p.sync.write().unwrap().on_peer_connected(&mut TestIo::new(&mut p.chain, &mut p.queue, Some(client as PeerId)), client as PeerId); } } } @@ -125,22 +129,22 @@ impl TestNet { if let Some(packet) = self.peers[peer].queue.pop_front() { let mut p = self.peers.get_mut(packet.recipient).unwrap(); trace!("--- {} -> {} ---", peer, packet.recipient); - p.sync.on_packet(&mut TestIo::new(&mut p.chain, &mut p.queue, Some(peer as PeerId)), peer as PeerId, packet.packet_id, &packet.data); + ChainSync::dispatch_packet(&p.sync, &mut TestIo::new(&mut p.chain, &mut p.queue, Some(peer as PeerId)), peer as PeerId, packet.packet_id, &packet.data); trace!("----------------"); } let mut p = self.peers.get_mut(peer).unwrap(); - p.sync.maintain_sync(&mut TestIo::new(&mut p.chain, &mut p.queue, None)); + p.sync.write().unwrap().maintain_sync(&mut TestIo::new(&mut p.chain, &mut p.queue, None)); } } pub fn sync_step_peer(&mut self, peer_num: usize) { let mut peer = self.peer_mut(peer_num); - peer.sync.maintain_sync(&mut TestIo::new(&mut peer.chain, &mut peer.queue, None)); + peer.sync.write().unwrap().maintain_sync(&mut TestIo::new(&mut peer.chain, &mut peer.queue, None)); } pub fn restart_peer(&mut self, i: usize) { let peer = self.peer_mut(i); - peer.sync.restart(&mut TestIo::new(&mut peer.chain, &mut peer.queue, None)); + peer.sync.write().unwrap().restart(&mut TestIo::new(&mut peer.chain, &mut peer.queue, None)); } pub fn sync(&mut self) -> u32 { @@ -169,6 +173,6 @@ impl TestNet { pub fn trigger_chain_new_blocks(&mut self, peer_id: usize) { let mut peer = self.peer_mut(peer_id); - peer.sync.chain_new_blocks(&mut TestIo::new(&mut peer.chain, &mut peer.queue, None), &[], &[], &[], &[]); + peer.sync.write().unwrap().chain_new_blocks(&mut TestIo::new(&mut peer.chain, &mut peer.queue, None), &[], &[], &[], &[]); } } diff --git a/test.sh b/test.sh index d89740aba..a62c835e8 100755 --- a/test.sh +++ b/test.sh @@ -2,6 +2,8 @@ # Running Parity Full Test Sute cargo test --features ethcore/json-tests $1 \ + -p ethkey \ + -p ethstore \ -p ethash \ -p ethcore-util \ -p ethcore \ diff --git a/util/Cargo.toml b/util/Cargo.toml index 173acd528..5cd0a714b 100644 --- a/util/Cargo.toml +++ b/util/Cargo.toml @@ -3,7 +3,7 @@ description = "Ethcore utility library" homepage = "http://ethcore.io" license = "GPL-3.0" name = "ethcore-util" -version = "1.2.0" +version = "1.3.0" authors = ["Ethcore "] build = "build.rs" @@ -12,13 +12,13 @@ log = "0.3" env_logger = "0.3" rustc-serialize = "0.3" arrayvec = "0.3" -mio = "0.5.1" +mio = { git = "https://github.com/ethcore/mio", branch = "v0.5.x" } nix ="0.5.0" rand = "0.3.12" time = "0.1.34" tiny-keccak = "1.0" rocksdb = { git = "https://github.com/ethcore/rust-rocksdb" } -lazy_static = "0.1" +lazy_static = "0.2" eth-secp256k1 = { git = "https://github.com/ethcore/rust-secp256k1" } rust-crypto = "0.2.34" elastic-array = "0.4" @@ -28,7 +28,7 @@ crossbeam = "0.2" slab = "0.2" sha3 = { path = "sha3" } serde = "0.7.0" -clippy = { version = "0.0.76", optional = true} +clippy = { version = "0.0.77", optional = true} json-tests = { path = "json-tests" } igd = "0.4.2" ethcore-devtools = { path = "../devtools" } diff --git a/util/bigint/Cargo.toml b/util/bigint/Cargo.toml index 1bd2b994e..fe9101df7 100644 --- a/util/bigint/Cargo.toml +++ b/util/bigint/Cargo.toml @@ -12,8 +12,6 @@ rustc_version = "0.1" [dependencies] rustc-serialize = "0.3" -arrayvec = "0.3" -rand = "0.3.12" serde = "0.7.0" heapsize = "0.3" diff --git a/util/bigint/src/uint.rs b/util/bigint/src/uint.rs index 286f6a43f..2b9863135 100644 --- a/util/bigint/src/uint.rs +++ b/util/bigint/src/uint.rs @@ -50,6 +50,12 @@ use std::cmp::*; use serde; use rustc_serialize::hex::{FromHex, FromHexError, ToHex}; +/// Conversion from decimal string error +#[derive(Debug, PartialEq)] +pub enum FromDecStrErr { + /// Value does not fit into type + InvalidLength +} macro_rules! impl_map_from { ($thing:ident, $from:ty, $to:ty) => { @@ -419,12 +425,16 @@ macro_rules! uint_overflowing_mul_reg { let (c_u, overflow_u) = mul_u32(a, b_u, c_l >> 32); ret[i + j] = (c_l & 0xFFFFFFFF) + (c_u << 32); - // Only single overflow possible here - let carry = (c_u >> 32) + (overflow_u << 32) + overflow_l + carry2; - let (carry, o) = carry.overflowing_add(ret[i + j + 1]); + // No overflow here + let res = (c_u >> 32) + (overflow_u << 32); + // possible overflows + let (res, o1) = res.overflowing_add(overflow_l); + let (res, o2) = res.overflowing_add(carry2); + let (res, o3) = res.overflowing_add(ret[i + j + 1]); + ret[i + j + 1] = res; - ret[i + j + 1] = carry; - carry2 = o as u64; + // Only single overflow possible there + carry2 = (o1 | o2 | o3) as u64; } } @@ -493,10 +503,8 @@ pub trait Uint: Sized + Default + FromStr + From + fmt::Debug + fmt::Displa /// Returns the largest value that can be represented by this integer type. fn max_value() -> Self; - /// Error type for converting from a decimal string. - type FromDecStrErr; /// Convert from a decimal string. - fn from_dec_str(value: &str) -> Result; + fn from_dec_str(value: &str) -> Result; /// Conversion to u32 fn low_u32(&self) -> u32; @@ -549,21 +557,26 @@ macro_rules! construct_uint { ($name:ident, $n_words:expr) => ( /// Little-endian large integer type #[repr(C)] - #[derive(Copy, Clone, Eq, PartialEq)] + #[derive(Copy, Clone, Eq, PartialEq, Hash)] pub struct $name(pub [u64; $n_words]); impl Uint for $name { - type FromDecStrErr = FromHexError; /// TODO: optimize, throw appropriate err - fn from_dec_str(value: &str) -> Result { - Ok(value.bytes() - .map(|b| b - 48) - .fold($name::from(0u64), | acc, c | - // fast multiplication by 10 - // (acc << 3) + (acc << 1) => acc * 10 - (acc << 3) + (acc << 1) + $name::from(c) - )) + fn from_dec_str(value: &str) -> Result { + let mut res = Self::default(); + for b in value.bytes().map(|b| b - 48) { + let (r, overflow) = res.overflowing_mul_u32(10); + if overflow { + return Err(FromDecStrErr::InvalidLength); + } + let (r, overflow) = r.overflowing_add(b.into()); + if overflow { + return Err(FromDecStrErr::InvalidLength); + } + res = r; + } + Ok(res) } #[inline] @@ -1113,14 +1126,6 @@ macro_rules! construct_uint { Ok(()) } } - - #[cfg_attr(feature="dev", allow(derive_hash_xor_eq))] // We are pretty sure it's ok. - impl Hash for $name { - fn hash(&self, state: &mut H) where H: Hasher { - unsafe { state.write(::std::slice::from_raw_parts(self.0.as_ptr() as *mut u8, self.0.len() * 8)); } - state.finish(); - } - } ); } @@ -1296,12 +1301,16 @@ impl U256 { let (c_u, overflow_u) = mul_u32(a, b_u, c_l >> 32); ret[i + j] = (c_l & 0xFFFFFFFF) + (c_u << 32); - // Only single overflow possible here - let carry = (c_u >> 32) + (overflow_u << 32) + overflow_l + carry2; - let (carry, o) = carry.overflowing_add(ret[i + j + 1]); + // No overflow here + let res = (c_u >> 32) + (overflow_u << 32); + // possible overflows + let (res, o1) = res.overflowing_add(overflow_l); + let (res, o2) = res.overflowing_add(carry2); + let (res, o3) = res.overflowing_add(ret[i + j + 1]); + ret[i + j + 1] = res; - ret[i + j + 1] = carry; - carry2 = o as u64; + // Only single overflow possible there + carry2 = (o1 | o2 | o3) as u64; } } @@ -1433,6 +1442,7 @@ known_heap_size!(0, U128, U256); mod tests { use uint::{Uint, U128, U256, U512}; use std::str::FromStr; + use super::FromDecStrErr; #[test] pub fn uint256_from() { @@ -1802,6 +1812,7 @@ mod tests { fn uint256_from_dec_str() { assert_eq!(U256::from_dec_str("10").unwrap(), U256::from(10u64)); assert_eq!(U256::from_dec_str("1024").unwrap(), U256::from(1024u64)); + assert_eq!(U256::from_dec_str("115792089237316195423570985008687907853269984665640564039457584007913129639936"), Err(FromDecStrErr::InvalidLength)); } #[test] diff --git a/util/src/hash.rs b/util/src/hash.rs index 6c1f8b2a4..16f0bde9e 100644 --- a/util/src/hash.rs +++ b/util/src/hash.rs @@ -132,15 +132,10 @@ macro_rules! impl_hash { $size } - // TODO: remove once slice::clone_from_slice is stable #[inline] fn clone_from_slice(&mut self, src: &[u8]) -> usize { - let min = ::std::cmp::min($size, src.len()); - let dst = &mut self.deref_mut()[.. min]; - let src = &src[.. min]; - for i in 0..min { - dst[i] = src[i]; - } + let min = cmp::min($size, src.len()); + self.0[..min].copy_from_slice(&src[..min]); min } @@ -151,7 +146,7 @@ macro_rules! impl_hash { } fn copy_to(&self, dest: &mut[u8]) { - let min = ::std::cmp::min($size, dest.len()); + let min = cmp::min($size, dest.len()); dest[..min].copy_from_slice(&self.0[..min]); } diff --git a/util/src/hashdb.rs b/util/src/hashdb.rs index 0a5f13d52..1ec3069d8 100644 --- a/util/src/hashdb.rs +++ b/util/src/hashdb.rs @@ -20,12 +20,10 @@ use bytes::*; use std::collections::HashMap; /// Trait modelling datastore keyed by a 32-byte Keccak hash. -pub trait HashDB : AsHashDB { +pub trait HashDB: AsHashDB { /// Get the keys in the database together with number of underlying references. fn keys(&self) -> HashMap; - /// Deprecated. use `get`. - fn lookup(&self, key: &H256) -> Option<&[u8]>; // TODO: rename to get. /// Look up a given hash into the bytes that hash to it, returning None if the /// hash is not known. /// @@ -41,10 +39,8 @@ pub trait HashDB : AsHashDB { /// assert_eq!(m.get(&hash).unwrap(), hello_bytes); /// } /// ``` - fn get(&self, key: &H256) -> Option<&[u8]> { self.lookup(key) } + fn get(&self, key: &H256) -> Option<&[u8]>; - /// Deprecated. Use `contains`. - fn exists(&self, key: &H256) -> bool; // TODO: rename to contains. /// Check for the existance of a hash-key. /// /// # Examples @@ -63,10 +59,10 @@ pub trait HashDB : AsHashDB { /// assert!(!m.contains(&key)); /// } /// ``` - fn contains(&self, key: &H256) -> bool { self.exists(key) } + fn contains(&self, key: &H256) -> bool; /// Insert a datum item into the DB and return the datum's hash for a later lookup. Insertions - /// are counted and the equivalent number of `kill()`s must be performed before the data + /// are counted and the equivalent number of `remove()`s must be performed before the data /// is considered dead. /// /// # Examples @@ -86,8 +82,6 @@ pub trait HashDB : AsHashDB { /// Like `insert()` , except you provide the key and the data is all moved. fn emplace(&mut self, key: H256, value: Bytes); - /// Deprecated - use `remove`. - fn kill(&mut self, key: &H256); // TODO: rename to remove. /// Remove a datum previously inserted. Insertions can be "owed" such that the same number of `insert()`s may /// happen without the data being eventually being inserted into the DB. /// @@ -109,7 +103,7 @@ pub trait HashDB : AsHashDB { /// assert_eq!(m.get(key).unwrap(), d); /// } /// ``` - fn remove(&mut self, key: &H256) { self.kill(key) } + fn remove(&mut self, key: &H256); } /// Upcast trait. @@ -121,6 +115,10 @@ pub trait AsHashDB { } impl AsHashDB for T { - fn as_hashdb(&self) -> &HashDB { self } - fn as_hashdb_mut(&mut self) -> &mut HashDB { self } + fn as_hashdb(&self) -> &HashDB { + self + } + fn as_hashdb_mut(&mut self) -> &mut HashDB { + self + } } diff --git a/util/src/io/mod.rs b/util/src/io/mod.rs index 93805a46a..3229c95d5 100644 --- a/util/src/io/mod.rs +++ b/util/src/io/mod.rs @@ -142,7 +142,7 @@ mod tests { #[test] fn test_service_register_handler () { - let mut service = IoService::::start().expect("Error creating network service"); + let service = IoService::::start().expect("Error creating network service"); service.register_handler(Arc::new(MyHandler)).unwrap(); } diff --git a/util/src/io/service.rs b/util/src/io/service.rs index d946463f5..07e60f766 100644 --- a/util/src/io/service.rs +++ b/util/src/io/service.rs @@ -18,9 +18,10 @@ use std::sync::*; use std::thread::{self, JoinHandle}; use std::collections::HashMap; use mio::*; +use crossbeam::sync::chase_lev; +use slab::Slab; use error::*; use io::{IoError, IoHandler}; -use crossbeam::sync::chase_lev; use io::worker::{Worker, Work, WorkType}; use panics::*; @@ -33,6 +34,7 @@ pub type HandlerId = usize; /// Maximum number of tokens a handler can use pub const TOKENS_PER_HANDLER: usize = 16384; +const MAX_HANDLERS: usize = 8; /// Messages used to communicate with the event loop from other threads. #[derive(Clone)] @@ -43,6 +45,9 @@ pub enum IoMessage where Message: Send + Clone + Sized { AddHandler { handler: Arc+Send>, }, + RemoveHandler { + handler_id: HandlerId, + }, AddTimer { handler_id: HandlerId, token: TimerToken, @@ -130,14 +135,24 @@ impl IoContext where Message: Send + Clone + 'static { } /// Broadcast a message to other IO clients - pub fn message(&self, message: Message) { - self.channel.send(message).expect("Error seding message"); + pub fn message(&self, message: Message) -> Result<(), UtilError> { + try!(self.channel.send(message)); + Ok(()) } /// Get message channel pub fn channel(&self) -> IoChannel { self.channel.clone() } + + /// Unregister current IO handler. + pub fn unregister_handler(&self) -> Result<(), IoError> { + try!(self.channel.send_io(IoMessage::RemoveHandler { + handler_id: self.handler, + })); + Ok(()) + } + } #[derive(Clone)] @@ -149,7 +164,7 @@ struct UserTimer { /// Root IO handler. Manages user handlers, messages and IO timers. pub struct IoManager where Message: Send + Sync { timers: Arc>>, - handlers: Vec>>, + handlers: Slab>, HandlerId>, workers: Vec, worker_channel: chase_lev::Worker>, work_ready: Arc, @@ -175,7 +190,7 @@ impl IoManager where Message: Send + Sync + Clone + 'static { let mut io = IoManager { timers: Arc::new(RwLock::new(HashMap::new())), - handlers: Vec::new(), + handlers: Slab::new(MAX_HANDLERS), worker_channel: worker, workers: workers, work_ready: work_ready, @@ -192,36 +207,31 @@ impl Handler for IoManager where Message: Send + Clone + Sync fn ready(&mut self, _event_loop: &mut EventLoop, token: Token, events: EventSet) { let handler_index = token.as_usize() / TOKENS_PER_HANDLER; let token_id = token.as_usize() % TOKENS_PER_HANDLER; - if handler_index >= self.handlers.len() { - panic!("Unexpected stream token: {}", token.as_usize()); - } - let handler = self.handlers[handler_index].clone(); - - if events.is_hup() { - self.worker_channel.push(Work { work_type: WorkType::Hup, token: token_id, handler: handler.clone(), handler_id: handler_index }); - } - else { - if events.is_readable() { - self.worker_channel.push(Work { work_type: WorkType::Readable, token: token_id, handler: handler.clone(), handler_id: handler_index }); + if let Some(handler) = self.handlers.get(handler_index) { + if events.is_hup() { + self.worker_channel.push(Work { work_type: WorkType::Hup, token: token_id, handler: handler.clone(), handler_id: handler_index }); } - if events.is_writable() { - self.worker_channel.push(Work { work_type: WorkType::Writable, token: token_id, handler: handler.clone(), handler_id: handler_index }); + else { + if events.is_readable() { + self.worker_channel.push(Work { work_type: WorkType::Readable, token: token_id, handler: handler.clone(), handler_id: handler_index }); + } + if events.is_writable() { + self.worker_channel.push(Work { work_type: WorkType::Writable, token: token_id, handler: handler.clone(), handler_id: handler_index }); + } } + self.work_ready.notify_all(); } - self.work_ready.notify_all(); } fn timeout(&mut self, event_loop: &mut EventLoop, token: Token) { let handler_index = token.as_usize() / TOKENS_PER_HANDLER; let token_id = token.as_usize() % TOKENS_PER_HANDLER; - if handler_index >= self.handlers.len() { - panic!("Unexpected timer token: {}", token.as_usize()); - } - if let Some(timer) = self.timers.read().unwrap().get(&token.as_usize()) { - event_loop.timeout_ms(token, timer.delay).expect("Error re-registering user timer"); - let handler = self.handlers[handler_index].clone(); - self.worker_channel.push(Work { work_type: WorkType::Timeout, token: token_id, handler: handler, handler_id: handler_index }); - self.work_ready.notify_all(); + if let Some(handler) = self.handlers.get(handler_index) { + if let Some(timer) = self.timers.read().unwrap().get(&token.as_usize()) { + event_loop.timeout_ms(token, timer.delay).expect("Error re-registering user timer"); + self.worker_channel.push(Work { work_type: WorkType::Timeout, token: token_id, handler: handler.clone(), handler_id: handler_index }); + self.work_ready.notify_all(); + } } } @@ -232,12 +242,13 @@ impl Handler for IoManager where Message: Send + Clone + Sync event_loop.shutdown(); }, IoMessage::AddHandler { handler } => { - let handler_id = { - self.handlers.push(handler.clone()); - self.handlers.len() - 1 - }; + let handler_id = self.handlers.insert(handler.clone()).unwrap_or_else(|_| panic!("Too many handlers registered")); handler.initialize(&IoContext::new(IoChannel::new(event_loop.channel()), handler_id)); }, + IoMessage::RemoveHandler { handler_id } => { + // TODO: flush event loop + self.handlers.remove(handler_id); + }, IoMessage::AddTimer { handler_id, token, delay } => { let timer_id = token + handler_id * TOKENS_PER_HANDLER; let timeout = event_loop.timeout_ms(Token(timer_id), delay).expect("Error registering user timer"); @@ -250,26 +261,32 @@ impl Handler for IoManager where Message: Send + Clone + Sync } }, IoMessage::RegisterStream { handler_id, token } => { - let handler = self.handlers.get(handler_id).expect("Unknown handler id").clone(); - handler.register_stream(token, Token(token + handler_id * TOKENS_PER_HANDLER), event_loop); + if let Some(handler) = self.handlers.get(handler_id) { + handler.register_stream(token, Token(token + handler_id * TOKENS_PER_HANDLER), event_loop); + } }, IoMessage::DeregisterStream { handler_id, token } => { - let handler = self.handlers.get(handler_id).expect("Unknown handler id").clone(); - handler.deregister_stream(token, event_loop); - // unregister a timer associated with the token (if any) - let timer_id = token + handler_id * TOKENS_PER_HANDLER; - if let Some(timer) = self.timers.write().unwrap().remove(&timer_id) { - event_loop.clear_timeout(timer.timeout); + if let Some(handler) = self.handlers.get(handler_id) { + handler.deregister_stream(token, event_loop); + // unregister a timer associated with the token (if any) + let timer_id = token + handler_id * TOKENS_PER_HANDLER; + if let Some(timer) = self.timers.write().unwrap().remove(&timer_id) { + event_loop.clear_timeout(timer.timeout); + } } }, IoMessage::UpdateStreamRegistration { handler_id, token } => { - let handler = self.handlers.get(handler_id).expect("Unknown handler id").clone(); - handler.update_stream(token, Token(token + handler_id * TOKENS_PER_HANDLER), event_loop); + if let Some(handler) = self.handlers.get(handler_id) { + handler.update_stream(token, Token(token + handler_id * TOKENS_PER_HANDLER), event_loop); + } }, IoMessage::UserMessage(data) => { - for n in 0 .. self.handlers.len() { - let handler = self.handlers[n].clone(); - self.worker_channel.push(Work { work_type: WorkType::Message(data.clone()), token: 0, handler: handler, handler_id: n }); + //TODO: better way to iterate the slab + for id in 0 .. MAX_HANDLERS { + if let Some(h) = self.handlers.get(id) { + let handler = h.clone(); + self.worker_channel.push(Work { work_type: WorkType::Message(data.clone()), token: 0, handler: handler, handler_id: id }); + } } self.work_ready.notify_all(); } @@ -335,7 +352,9 @@ impl IoService where Message: Send + Sync + Clone + 'static { /// Starts IO event loop pub fn start() -> Result, UtilError> { let panic_handler = PanicHandler::new_in_arc(); - let mut event_loop = EventLoop::new().unwrap(); + let mut config = EventLoopConfig::new(); + config.messages_per_tick(1024); + let mut event_loop = EventLoop::configured(config).expect("Error creating event loop"); let channel = event_loop.channel(); let panic = panic_handler.clone(); let thread = thread::spawn(move || { @@ -351,8 +370,8 @@ impl IoService where Message: Send + Sync + Clone + 'static { }) } - /// Regiter a IO hadnler with the event loop. - pub fn register_handler(&mut self, handler: Arc+Send>) -> Result<(), IoError> { + /// Regiter an IO handler with the event loop. + pub fn register_handler(&self, handler: Arc+Send>) -> Result<(), IoError> { try!(self.host_channel.send(IoMessage::AddHandler { handler: handler, })); @@ -360,13 +379,13 @@ impl IoService where Message: Send + Sync + Clone + 'static { } /// Send a message over the network. Normaly `HostIo::send` should be used. This can be used from non-io threads. - pub fn send_message(&mut self, message: Message) -> Result<(), IoError> { + pub fn send_message(&self, message: Message) -> Result<(), IoError> { try!(self.host_channel.send(IoMessage::UserMessage(message))); Ok(()) } /// Create a new message channel - pub fn channel(&mut self) -> IoChannel { + pub fn channel(&self) -> IoChannel { IoChannel { channel: Some(self.host_channel.clone()) } } } @@ -374,7 +393,7 @@ impl IoService where Message: Send + Sync + Clone + 'static { impl Drop for IoService where Message: Send + Sync + Clone { fn drop(&mut self) { trace!(target: "shutdown", "[IoService] Closing..."); - self.host_channel.send(IoMessage::Shutdown).unwrap(); + self.host_channel.send(IoMessage::Shutdown).unwrap_or_else(|e| warn!("Error on IO service shutdown: {:?}", e)); self.thread.take().unwrap().join().ok(); trace!(target: "shutdown", "[IoService] Closed."); } diff --git a/util/src/journaldb/archivedb.rs b/util/src/journaldb/archivedb.rs index c6acc1280..a01ed807f 100644 --- a/util/src/journaldb/archivedb.rs +++ b/util/src/journaldb/archivedb.rs @@ -20,6 +20,7 @@ use common::*; use rlp::*; use hashdb::*; use memorydb::*; +use super::{DB_PREFIX_LEN, LATEST_ERA_KEY, VERSION_KEY}; use super::traits::JournalDB; use kvdb::{Database, DBTransaction, DatabaseConfig}; #[cfg(test)] @@ -38,19 +39,12 @@ pub struct ArchiveDB { latest_era: Option, } -// all keys must be at least 12 bytes -const LATEST_ERA_KEY : [u8; 12] = [ b'l', b'a', b's', b't', 0, 0, 0, 0, 0, 0, 0, 0 ]; -const VERSION_KEY : [u8; 12] = [ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0, 0, 0, 0 ]; const DB_VERSION : u32 = 0x103; impl ArchiveDB { /// Create a new instance from file - pub fn new(path: &str) -> ArchiveDB { - let opts = DatabaseConfig { - //use 12 bytes as prefix, this must match account_db prefix - prefix_size: Some(12), - max_open_files: 256, - }; + pub fn new(path: &str, config: DatabaseConfig) -> ArchiveDB { + let opts = config.prefix(DB_PREFIX_LEN); let backing = Database::open(&opts, path).unwrap_or_else(|e| { panic!("Error opening state db: {}", e); }); @@ -76,7 +70,7 @@ impl ArchiveDB { fn new_temp() -> ArchiveDB { let mut dir = env::temp_dir(); dir.push(H32::random().hex()); - Self::new(dir.to_str().unwrap()) + Self::new(dir.to_str().unwrap(), DatabaseConfig::default()) } fn payload(&self, key: &H256) -> Option { @@ -99,7 +93,7 @@ impl HashDB for ArchiveDB { ret } - fn lookup(&self, key: &H256) -> Option<&[u8]> { + fn get(&self, key: &H256) -> Option<&[u8]> { let k = self.overlay.raw(key); match k { Some(&(ref d, rc)) if rc > 0 => Some(d), @@ -114,8 +108,8 @@ impl HashDB for ArchiveDB { } } - fn exists(&self, key: &H256) -> bool { - self.lookup(key).is_some() + fn contains(&self, key: &H256) -> bool { + self.get(key).is_some() } fn insert(&mut self, value: &[u8]) -> H256 { @@ -124,8 +118,8 @@ impl HashDB for ArchiveDB { fn emplace(&mut self, key: H256, value: Bytes) { self.overlay.emplace(key, value); } - fn kill(&mut self, key: &H256) { - self.overlay.kill(key); + fn remove(&mut self, key: &H256) { + self.overlay.remove(key); } } @@ -188,6 +182,7 @@ mod tests { use super::*; use hashdb::*; use journaldb::traits::JournalDB; + use kvdb::DatabaseConfig; #[test] fn insert_same_in_fork() { @@ -208,7 +203,7 @@ mod tests { jdb.commit(5, &b"1004a".sha3(), Some((3, b"1002a".sha3()))).unwrap(); jdb.commit(6, &b"1005a".sha3(), Some((4, b"1003a".sha3()))).unwrap(); - assert!(jdb.exists(&x)); + assert!(jdb.contains(&x)); } #[test] @@ -217,14 +212,14 @@ mod tests { let mut jdb = ArchiveDB::new_temp(); let h = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.remove(&h); jdb.commit(1, &b"1".sha3(), None).unwrap(); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(2, &b"2".sha3(), None).unwrap(); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(3, &b"3".sha3(), Some((0, b"0".sha3()))).unwrap(); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(4, &b"4".sha3(), Some((1, b"1".sha3()))).unwrap(); } @@ -236,26 +231,26 @@ mod tests { let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); jdb.commit(0, &b"0".sha3(), None).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.remove(&foo); jdb.remove(&bar); let baz = jdb.insert(b"baz"); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); + assert!(jdb.contains(&baz)); let foo = jdb.insert(b"foo"); jdb.remove(&baz); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&baz)); jdb.remove(&foo); jdb.commit(3, &b"3".sha3(), Some((2, b"2".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(4, &b"4".sha3(), Some((3, b"3".sha3()))).unwrap(); } @@ -268,8 +263,8 @@ mod tests { let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); jdb.commit(0, &b"0".sha3(), None).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.remove(&foo); let baz = jdb.insert(b"baz"); @@ -278,12 +273,12 @@ mod tests { jdb.remove(&bar); jdb.commit(1, &b"1b".sha3(), Some((0, b"0".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); + assert!(jdb.contains(&baz)); jdb.commit(2, &b"2b".sha3(), Some((1, b"1b".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } #[test] @@ -293,16 +288,16 @@ mod tests { let foo = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.remove(&foo); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); jdb.insert(b"foo"); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(3, &b"2".sha3(), Some((0, b"2".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } #[test] @@ -316,10 +311,10 @@ mod tests { jdb.insert(b"foo"); jdb.commit(1, &b"1b".sha3(), Some((0, b"0".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(2, &b"2a".sha3(), Some((1, b"1a".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } #[test] @@ -329,7 +324,7 @@ mod tests { let bar = H256::random(); let foo = { - let mut jdb = ArchiveDB::new(dir.to_str().unwrap()); + let mut jdb = ArchiveDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 let foo = jdb.insert(b"foo"); jdb.emplace(bar.clone(), b"bar".to_vec()); @@ -338,15 +333,15 @@ mod tests { }; { - let mut jdb = ArchiveDB::new(dir.to_str().unwrap()); + let mut jdb = ArchiveDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.remove(&foo); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); } { - let mut jdb = ArchiveDB::new(dir.to_str().unwrap()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + let mut jdb = ArchiveDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); } } @@ -357,7 +352,7 @@ mod tests { dir.push(H32::random().hex()); let foo = { - let mut jdb = ArchiveDB::new(dir.to_str().unwrap()); + let mut jdb = ArchiveDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 let foo = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); @@ -371,10 +366,10 @@ mod tests { }; { - let mut jdb = ArchiveDB::new(dir.to_str().unwrap()); + let mut jdb = ArchiveDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.remove(&foo); jdb.commit(3, &b"3".sha3(), Some((2, b"2".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.remove(&foo); jdb.commit(4, &b"4".sha3(), Some((3, b"3".sha3()))).unwrap(); jdb.commit(5, &b"5".sha3(), Some((4, b"4".sha3()))).unwrap(); @@ -386,7 +381,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); let (foo, _, _) = { - let mut jdb = ArchiveDB::new(dir.to_str().unwrap()); + let mut jdb = ArchiveDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -401,9 +396,9 @@ mod tests { }; { - let mut jdb = ArchiveDB::new(dir.to_str().unwrap()); + let mut jdb = ArchiveDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(2, &b"2b".sha3(), Some((1, b"1b".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } } @@ -412,14 +407,14 @@ mod tests { let temp = ::devtools::RandomTempPath::new(); let key = { - let mut jdb = ArchiveDB::new(temp.as_str()); + let mut jdb = ArchiveDB::new(temp.as_str(), DatabaseConfig::default()); let key = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); key }; { - let jdb = ArchiveDB::new(temp.as_str()); + let jdb = ArchiveDB::new(temp.as_str(), DatabaseConfig::default()); let state = jdb.state(&key); assert!(state.is_some()); } diff --git a/util/src/journaldb/earlymergedb.rs b/util/src/journaldb/earlymergedb.rs index 7cb117447..2b87f8345 100644 --- a/util/src/journaldb/earlymergedb.rs +++ b/util/src/journaldb/earlymergedb.rs @@ -20,6 +20,7 @@ use common::*; use rlp::*; use hashdb::*; use memorydb::*; +use super::{DB_PREFIX_LEN, LATEST_ERA_KEY, VERSION_KEY}; use super::traits::JournalDB; use kvdb::{Database, DBTransaction, DatabaseConfig}; #[cfg(test)] @@ -67,20 +68,13 @@ pub struct EarlyMergeDB { latest_era: Option, } -// all keys must be at least 12 bytes -const LATEST_ERA_KEY : [u8; 12] = [ b'l', b'a', b's', b't', 0, 0, 0, 0, 0, 0, 0, 0 ]; -const VERSION_KEY : [u8; 12] = [ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0, 0, 0, 0 ]; const DB_VERSION : u32 = 0x003; const PADDING : [u8; 10] = [ 0u8; 10 ]; impl EarlyMergeDB { /// Create a new instance from file - pub fn new(path: &str) -> EarlyMergeDB { - let opts = DatabaseConfig { - //use 12 bytes as prefix, this must match account_db prefix - prefix_size: Some(12), - max_open_files: 256, - }; + pub fn new(path: &str, config: DatabaseConfig) -> EarlyMergeDB { + let opts = config.prefix(DB_PREFIX_LEN); let backing = Database::open(&opts, path).unwrap_or_else(|e| { panic!("Error opening state db: {}", e); }); @@ -108,7 +102,7 @@ impl EarlyMergeDB { fn new_temp() -> EarlyMergeDB { let mut dir = env::temp_dir(); dir.push(H32::random().hex()); - Self::new(dir.to_str().unwrap()) + Self::new(dir.to_str().unwrap(), DatabaseConfig::default()) } fn morph_key(key: &H256, index: u8) -> Bytes { @@ -173,8 +167,8 @@ impl EarlyMergeDB { trace!(target: "jdb.fine", "replay_keys: (end) refs={:?}", refs); } - fn kill_keys(deletes: &[H256], refs: &mut HashMap, batch: &DBTransaction, from: RemoveFrom, trace: bool) { - // with a kill on {queue_refs: 1, in_archive: true}, we have two options: + fn remove_keys(deletes: &[H256], refs: &mut HashMap, batch: &DBTransaction, from: RemoveFrom, trace: bool) { + // with a remove on {queue_refs: 1, in_archive: true}, we have two options: // - convert to {queue_refs: 1, in_archive: false} (i.e. remove it from the conceptual archive) // - convert to {queue_refs: 0, in_archive: true} (i.e. remove it from the conceptual queue) // (the latter option would then mean removing the RefInfo, since it would no longer be counted in the queue.) @@ -187,13 +181,13 @@ impl EarlyMergeDB { c.in_archive = false; Self::reset_already_in(batch, h); if trace { - trace!(target: "jdb.fine", " kill({}): In archive, 1 in queue: Reducing to queue only and recording", h); + trace!(target: "jdb.fine", " remove({}): In archive, 1 in queue: Reducing to queue only and recording", h); } continue; } else if c.queue_refs > 1 { c.queue_refs -= 1; if trace { - trace!(target: "jdb.fine", " kill({}): In queue > 1 refs: Decrementing ref count to {}", h, c.queue_refs); + trace!(target: "jdb.fine", " remove({}): In queue > 1 refs: Decrementing ref count to {}", h, c.queue_refs); } continue; } else { @@ -205,14 +199,14 @@ impl EarlyMergeDB { refs.remove(h); Self::reset_already_in(batch, h); if trace { - trace!(target: "jdb.fine", " kill({}): In archive, 1 in queue: Removing from queue and leaving in archive", h); + trace!(target: "jdb.fine", " remove({}): In archive, 1 in queue: Removing from queue and leaving in archive", h); } } Some(RefInfo{queue_refs: 1, in_archive: false}) => { refs.remove(h); batch.delete(&h.bytes()).expect("Low-level database error. Some issue with your hard disk?"); if trace { - trace!(target: "jdb.fine", " kill({}): Not in archive, only 1 ref in queue: Removing from queue and DB", h); + trace!(target: "jdb.fine", " remove({}): Not in archive, only 1 ref in queue: Removing from queue and DB", h); } } None => { @@ -220,7 +214,7 @@ impl EarlyMergeDB { //assert!(!Self::is_already_in(db, &h)); batch.delete(&h.bytes()).expect("Low-level database error. Some issue with your hard disk?"); if trace { - trace!(target: "jdb.fine", " kill({}): Not in queue - MUST BE IN ARCHIVE: Removing from DB", h); + trace!(target: "jdb.fine", " remove({}): Not in queue - MUST BE IN ARCHIVE: Removing from DB", h); } } _ => panic!("Invalid value in refs: {:?}", n), @@ -291,7 +285,7 @@ impl HashDB for EarlyMergeDB { ret } - fn lookup(&self, key: &H256) -> Option<&[u8]> { + fn get(&self, key: &H256) -> Option<&[u8]> { let k = self.overlay.raw(key); match k { Some(&(ref d, rc)) if rc > 0 => Some(d), @@ -306,8 +300,8 @@ impl HashDB for EarlyMergeDB { } } - fn exists(&self, key: &H256) -> bool { - self.lookup(key).is_some() + fn contains(&self, key: &H256) -> bool { + self.get(key).is_some() } fn insert(&mut self, value: &[u8]) -> H256 { @@ -316,8 +310,8 @@ impl HashDB for EarlyMergeDB { fn emplace(&mut self, key: H256, value: Bytes) { self.overlay.emplace(key, value); } - fn kill(&mut self, key: &H256) { - self.overlay.kill(key); + fn remove(&mut self, key: &H256) { + self.overlay.remove(key); } } @@ -473,7 +467,7 @@ impl JournalDB for EarlyMergeDB { if trace { trace!(target: "jdb.ops", " Expunging: {:?}", deletes); } - Self::kill_keys(&deletes, &mut refs, &batch, RemoveFrom::Archive, trace); + Self::remove_keys(&deletes, &mut refs, &batch, RemoveFrom::Archive, trace); if trace { trace!(target: "jdb.ops", " Finalising: {:?}", inserts); @@ -505,7 +499,7 @@ impl JournalDB for EarlyMergeDB { if trace { trace!(target: "jdb.ops", " Reverting: {:?}", inserts); } - Self::kill_keys(&inserts, &mut refs, &batch, RemoveFrom::Queue, trace); + Self::remove_keys(&inserts, &mut refs, &batch, RemoveFrom::Queue, trace); } try!(batch.delete(&last)); @@ -538,6 +532,7 @@ mod tests { use super::super::traits::JournalDB; use hashdb::*; use log::init_log; + use kvdb::DatabaseConfig; #[test] fn insert_same_in_fork() { @@ -566,7 +561,7 @@ mod tests { jdb.commit(6, &b"1005a".sha3(), Some((4, b"1003a".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&x)); + assert!(jdb.contains(&x)); } #[test] @@ -585,8 +580,8 @@ mod tests { assert!(jdb.can_reconstruct_refs()); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); } #[test] @@ -596,20 +591,20 @@ mod tests { let h = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.remove(&h); jdb.commit(1, &b"1".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(2, &b"2".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(3, &b"3".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(4, &b"4".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&h)); + assert!(!jdb.contains(&h)); } #[test] @@ -621,38 +616,38 @@ mod tests { let bar = jdb.insert(b"bar"); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.remove(&foo); jdb.remove(&bar); let baz = jdb.insert(b"baz"); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); + assert!(jdb.contains(&baz)); let foo = jdb.insert(b"foo"); jdb.remove(&baz); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&bar)); + assert!(jdb.contains(&baz)); jdb.remove(&foo); jdb.commit(3, &b"3".sha3(), Some((2, b"2".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&bar)); - assert!(!jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&bar)); + assert!(!jdb.contains(&baz)); jdb.commit(4, &b"4".sha3(), Some((3, b"3".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&foo)); - assert!(!jdb.exists(&bar)); - assert!(!jdb.exists(&baz)); + assert!(!jdb.contains(&foo)); + assert!(!jdb.contains(&bar)); + assert!(!jdb.contains(&baz)); } #[test] @@ -664,8 +659,8 @@ mod tests { let bar = jdb.insert(b"bar"); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.remove(&foo); let baz = jdb.insert(b"baz"); @@ -676,15 +671,15 @@ mod tests { jdb.commit(1, &b"1b".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); + assert!(jdb.contains(&baz)); jdb.commit(2, &b"2b".sha3(), Some((1, b"1b".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&baz)); - assert!(!jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&baz)); + assert!(!jdb.contains(&bar)); } #[test] @@ -695,19 +690,19 @@ mod tests { let foo = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.remove(&foo); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); jdb.insert(b"foo"); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(3, &b"2".sha3(), Some((0, b"2".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } #[test] @@ -715,7 +710,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -731,11 +726,11 @@ mod tests { jdb.commit(1, &b"1c".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(2, &b"2a".sha3(), Some((1, b"1a".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } #[test] @@ -743,7 +738,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -759,11 +754,11 @@ mod tests { jdb.commit(1, &b"1c".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(2, &b"2b".sha3(), Some((1, b"1b".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } #[test] @@ -771,7 +766,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -809,7 +804,7 @@ mod tests { let bar = H256::random(); let foo = { - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 let foo = jdb.insert(b"foo"); jdb.emplace(bar.clone(), b"bar".to_vec()); @@ -819,19 +814,19 @@ mod tests { }; { - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.remove(&foo); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); } { - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&foo)); + assert!(!jdb.contains(&foo)); } } @@ -841,7 +836,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 4 let foo = jdb.insert(b"foo"); @@ -870,7 +865,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 4 let foo = jdb.insert(b"foo"); @@ -919,7 +914,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 let foo = jdb.insert(b"foo"); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); @@ -934,7 +929,7 @@ mod tests { jdb.insert(b"foo"); jdb.commit(3, &b"3".sha3(), Some((2, b"2".sha3()))).unwrap(); // BROKEN assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.remove(&foo); jdb.commit(4, &b"4".sha3(), Some((3, b"3".sha3()))).unwrap(); @@ -942,7 +937,7 @@ mod tests { jdb.commit(5, &b"5".sha3(), Some((4, b"4".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&foo)); + assert!(!jdb.contains(&foo)); } #[test] @@ -950,7 +945,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 4 let foo = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); @@ -990,7 +985,7 @@ mod tests { let foo = b"foo".sha3(); { - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); @@ -1003,34 +998,34 @@ mod tests { jdb.remove(&foo); jdb.commit(2, &b"2".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.insert(b"foo"); jdb.commit(3, &b"3".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); // incantation to reopen the db - }; { let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + }; { let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.remove(&foo); jdb.commit(4, &b"4".sha3(), Some((2, b"2".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); // incantation to reopen the db - }; { let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + }; { let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(5, &b"5".sha3(), Some((3, b"3".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); // incantation to reopen the db - }; { let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + }; { let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(6, &b"6".sha3(), Some((4, b"4".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&foo)); + assert!(!jdb.contains(&foo)); } } @@ -1039,7 +1034,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); let (foo, bar, baz) = { - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -1057,12 +1052,12 @@ mod tests { }; { - let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap()); + let mut jdb = EarlyMergeDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(2, &b"2b".sha3(), Some((1, b"1b".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&baz)); - assert!(!jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&baz)); + assert!(!jdb.contains(&bar)); } } } diff --git a/util/src/journaldb/mod.rs b/util/src/journaldb/mod.rs index 6e389b3c0..4715273dd 100644 --- a/util/src/journaldb/mod.rs +++ b/util/src/journaldb/mod.rs @@ -17,6 +17,7 @@ //! `JournalDB` interface and implementation. use common::*; +use kvdb::DatabaseConfig; /// Export the journaldb module. pub mod traits; @@ -71,11 +72,16 @@ impl fmt::Display for Algorithm { } /// Create a new `JournalDB` trait object. -pub fn new(path: &str, algorithm: Algorithm) -> Box { +pub fn new(path: &str, algorithm: Algorithm, config: DatabaseConfig) -> Box { match algorithm { - Algorithm::Archive => Box::new(archivedb::ArchiveDB::new(path)), - Algorithm::EarlyMerge => Box::new(earlymergedb::EarlyMergeDB::new(path)), - Algorithm::OverlayRecent => Box::new(overlayrecentdb::OverlayRecentDB::new(path)), - Algorithm::RefCounted => Box::new(refcounteddb::RefCountedDB::new(path)), + Algorithm::Archive => Box::new(archivedb::ArchiveDB::new(path, config)), + Algorithm::EarlyMerge => Box::new(earlymergedb::EarlyMergeDB::new(path, config)), + Algorithm::OverlayRecent => Box::new(overlayrecentdb::OverlayRecentDB::new(path, config)), + Algorithm::RefCounted => Box::new(refcounteddb::RefCountedDB::new(path, config)), } } + +// all keys must be at least 12 bytes +const DB_PREFIX_LEN : usize = 12; +const LATEST_ERA_KEY : [u8; DB_PREFIX_LEN] = [ b'l', b'a', b's', b't', 0, 0, 0, 0, 0, 0, 0, 0 ]; +const VERSION_KEY : [u8; DB_PREFIX_LEN] = [ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0, 0, 0, 0 ]; diff --git a/util/src/journaldb/overlayrecentdb.rs b/util/src/journaldb/overlayrecentdb.rs index 86d8d5c4d..0ffea308b 100644 --- a/util/src/journaldb/overlayrecentdb.rs +++ b/util/src/journaldb/overlayrecentdb.rs @@ -20,6 +20,7 @@ use common::*; use rlp::*; use hashdb::*; use memorydb::*; +use super::{DB_PREFIX_LEN, LATEST_ERA_KEY, VERSION_KEY}; use kvdb::{Database, DBTransaction, DatabaseConfig}; #[cfg(test)] use std::env; @@ -92,25 +93,18 @@ impl Clone for OverlayRecentDB { } } -// all keys must be at least 12 bytes -const LATEST_ERA_KEY : [u8; 12] = [ b'l', b'a', b's', b't', 0, 0, 0, 0, 0, 0, 0, 0 ]; -const VERSION_KEY : [u8; 12] = [ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0, 0, 0, 0 ]; const DB_VERSION : u32 = 0x203; const PADDING : [u8; 10] = [ 0u8; 10 ]; impl OverlayRecentDB { /// Create a new instance from file - pub fn new(path: &str) -> OverlayRecentDB { - Self::from_prefs(path) + pub fn new(path: &str, config: DatabaseConfig) -> OverlayRecentDB { + Self::from_prefs(path, config) } /// Create a new instance from file - pub fn from_prefs(path: &str) -> OverlayRecentDB { - let opts = DatabaseConfig { - //use 12 bytes as prefix, this must match account_db prefix - prefix_size: Some(12), - max_open_files: 256, - }; + pub fn from_prefs(path: &str, config: DatabaseConfig) -> OverlayRecentDB { + let opts = config.prefix(DB_PREFIX_LEN); let backing = Database::open(&opts, path).unwrap_or_else(|e| { panic!("Error opening state db: {}", e); }); @@ -136,7 +130,7 @@ impl OverlayRecentDB { pub fn new_temp() -> OverlayRecentDB { let mut dir = env::temp_dir(); dir.push(H32::random().hex()); - Self::new(dir.to_str().unwrap()) + Self::new(dir.to_str().unwrap(), DatabaseConfig::default()) } #[cfg(test)] @@ -289,11 +283,11 @@ impl JournalDB for OverlayRecentDB { } // update the overlay for k in overlay_deletions { - journal_overlay.backing_overlay.kill(&k); + journal_overlay.backing_overlay.remove(&k); } // apply canon deletions for k in canon_deletions { - if !journal_overlay.backing_overlay.exists(&k) { + if !journal_overlay.backing_overlay.contains(&k) { try!(batch.delete(&k)); } } @@ -322,12 +316,12 @@ impl HashDB for OverlayRecentDB { ret } - fn lookup(&self, key: &H256) -> Option<&[u8]> { + fn get(&self, key: &H256) -> Option<&[u8]> { let k = self.transaction_overlay.raw(key); match k { Some(&(ref d, rc)) if rc > 0 => Some(d), _ => { - let v = self.journal_overlay.read().unwrap().backing_overlay.lookup(key).map(|v| v.to_vec()); + let v = self.journal_overlay.read().unwrap().backing_overlay.get(key).map(|v| v.to_vec()); match v { Some(x) => { Some(&self.transaction_overlay.denote(key, x).0) @@ -345,8 +339,8 @@ impl HashDB for OverlayRecentDB { } } - fn exists(&self, key: &H256) -> bool { - self.lookup(key).is_some() + fn contains(&self, key: &H256) -> bool { + self.get(key).is_some() } fn insert(&mut self, value: &[u8]) -> H256 { @@ -355,8 +349,8 @@ impl HashDB for OverlayRecentDB { fn emplace(&mut self, key: H256, value: Bytes) { self.transaction_overlay.emplace(key, value); } - fn kill(&mut self, key: &H256) { - self.transaction_overlay.kill(key); + fn remove(&mut self, key: &H256) { + self.transaction_overlay.remove(key); } } @@ -370,6 +364,7 @@ mod tests { use hashdb::*; use log::init_log; use journaldb::JournalDB; + use kvdb::DatabaseConfig; #[test] fn insert_same_in_fork() { @@ -398,7 +393,7 @@ mod tests { jdb.commit(6, &b"1005a".sha3(), Some((4, b"1003a".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&x)); + assert!(jdb.contains(&x)); } #[test] @@ -408,20 +403,20 @@ mod tests { let h = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.remove(&h); jdb.commit(1, &b"1".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(2, &b"2".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(3, &b"3".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(4, &b"4".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&h)); + assert!(!jdb.contains(&h)); } #[test] @@ -433,38 +428,38 @@ mod tests { let bar = jdb.insert(b"bar"); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.remove(&foo); jdb.remove(&bar); let baz = jdb.insert(b"baz"); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); + assert!(jdb.contains(&baz)); let foo = jdb.insert(b"foo"); jdb.remove(&baz); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&bar)); + assert!(jdb.contains(&baz)); jdb.remove(&foo); jdb.commit(3, &b"3".sha3(), Some((2, b"2".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&bar)); - assert!(!jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&bar)); + assert!(!jdb.contains(&baz)); jdb.commit(4, &b"4".sha3(), Some((3, b"3".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&foo)); - assert!(!jdb.exists(&bar)); - assert!(!jdb.exists(&baz)); + assert!(!jdb.contains(&foo)); + assert!(!jdb.contains(&bar)); + assert!(!jdb.contains(&baz)); } #[test] @@ -476,8 +471,8 @@ mod tests { let bar = jdb.insert(b"bar"); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.remove(&foo); let baz = jdb.insert(b"baz"); @@ -488,15 +483,15 @@ mod tests { jdb.commit(1, &b"1b".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); + assert!(jdb.contains(&baz)); jdb.commit(2, &b"2b".sha3(), Some((1, b"1b".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&baz)); - assert!(!jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&baz)); + assert!(!jdb.contains(&bar)); } #[test] @@ -507,19 +502,19 @@ mod tests { let foo = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.remove(&foo); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); jdb.insert(b"foo"); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(3, &b"2".sha3(), Some((0, b"2".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } #[test] @@ -527,7 +522,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -543,11 +538,11 @@ mod tests { jdb.commit(1, &b"1c".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(2, &b"2a".sha3(), Some((1, b"1a".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } #[test] @@ -555,7 +550,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -571,11 +566,11 @@ mod tests { jdb.commit(1, &b"1c".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.commit(2, &b"2b".sha3(), Some((1, b"1b".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); } #[test] @@ -583,7 +578,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(0, &b"0".sha3(), None).unwrap(); assert!(jdb.can_reconstruct_refs()); @@ -621,7 +616,7 @@ mod tests { let bar = H256::random(); let foo = { - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 let foo = jdb.insert(b"foo"); jdb.emplace(bar.clone(), b"bar".to_vec()); @@ -631,19 +626,19 @@ mod tests { }; { - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.remove(&foo); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); } { - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&foo)); + assert!(!jdb.contains(&foo)); } } @@ -653,7 +648,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 4 let foo = jdb.insert(b"foo"); @@ -682,7 +677,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 4 let foo = jdb.insert(b"foo"); @@ -731,7 +726,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 let foo = jdb.insert(b"foo"); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); @@ -746,7 +741,7 @@ mod tests { jdb.insert(b"foo"); jdb.commit(3, &b"3".sha3(), Some((2, b"2".sha3()))).unwrap(); // BROKEN assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.remove(&foo); jdb.commit(4, &b"4".sha3(), Some((3, b"3".sha3()))).unwrap(); @@ -754,7 +749,7 @@ mod tests { jdb.commit(5, &b"5".sha3(), Some((4, b"4".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&foo)); + assert!(!jdb.contains(&foo)); } #[test] @@ -762,7 +757,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 4 let foo = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); @@ -802,7 +797,7 @@ mod tests { let foo = b"foo".sha3(); { - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); @@ -815,34 +810,34 @@ mod tests { jdb.remove(&foo); jdb.commit(2, &b"2".sha3(), Some((0, b"0".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); jdb.insert(b"foo"); jdb.commit(3, &b"3".sha3(), Some((1, b"1".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); // incantation to reopen the db - }; { let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + }; { let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.remove(&foo); jdb.commit(4, &b"4".sha3(), Some((2, b"2".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); // incantation to reopen the db - }; { let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + }; { let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(5, &b"5".sha3(), Some((3, b"3".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); + assert!(jdb.contains(&foo)); // incantation to reopen the db - }; { let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + }; { let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(6, &b"6".sha3(), Some((4, b"4".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(!jdb.exists(&foo)); + assert!(!jdb.contains(&foo)); } } @@ -851,7 +846,7 @@ mod tests { let mut dir = ::std::env::temp_dir(); dir.push(H32::random().hex()); let (foo, bar, baz) = { - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); // history is 1 let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); @@ -869,12 +864,12 @@ mod tests { }; { - let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap()); + let mut jdb = OverlayRecentDB::new(dir.to_str().unwrap(), DatabaseConfig::default()); jdb.commit(2, &b"2b".sha3(), Some((1, b"1b".sha3()))).unwrap(); assert!(jdb.can_reconstruct_refs()); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&baz)); - assert!(!jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&baz)); + assert!(!jdb.contains(&bar)); } } @@ -894,7 +889,7 @@ mod tests { assert!(jdb.can_reconstruct_refs()); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); } } diff --git a/util/src/journaldb/refcounteddb.rs b/util/src/journaldb/refcounteddb.rs index 7f24a729c..4be6a1eda 100644 --- a/util/src/journaldb/refcounteddb.rs +++ b/util/src/journaldb/refcounteddb.rs @@ -20,6 +20,7 @@ use common::*; use rlp::*; use hashdb::*; use overlaydb::*; +use super::{DB_PREFIX_LEN, LATEST_ERA_KEY, VERSION_KEY}; use super::traits::JournalDB; use kvdb::{Database, DBTransaction, DatabaseConfig}; #[cfg(test)] @@ -40,19 +41,13 @@ pub struct RefCountedDB { removes: Vec, } -const LATEST_ERA_KEY : [u8; 12] = [ b'l', b'a', b's', b't', 0, 0, 0, 0, 0, 0, 0, 0 ]; -const VERSION_KEY : [u8; 12] = [ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0, 0, 0, 0 ]; const DB_VERSION : u32 = 0x200; const PADDING : [u8; 10] = [ 0u8; 10 ]; impl RefCountedDB { /// Create a new instance given a `backing` database. - pub fn new(path: &str) -> RefCountedDB { - let opts = DatabaseConfig { - //use 12 bytes as prefix, this must match account_db prefix - prefix_size: Some(12), - max_open_files: 256, - }; + pub fn new(path: &str, config: DatabaseConfig) -> RefCountedDB { + let opts = config.prefix(DB_PREFIX_LEN); let backing = Database::open(&opts, path).unwrap_or_else(|e| { panic!("Error opening state db: {}", e); }); @@ -82,17 +77,17 @@ impl RefCountedDB { fn new_temp() -> RefCountedDB { let mut dir = env::temp_dir(); dir.push(H32::random().hex()); - Self::new(dir.to_str().unwrap()) + Self::new(dir.to_str().unwrap(), DatabaseConfig::default()) } } impl HashDB for RefCountedDB { fn keys(&self) -> HashMap { self.forward.keys() } - fn lookup(&self, key: &H256) -> Option<&[u8]> { self.forward.lookup(key) } - fn exists(&self, key: &H256) -> bool { self.forward.exists(key) } + fn get(&self, key: &H256) -> Option<&[u8]> { self.forward.get(key) } + fn contains(&self, key: &H256) -> bool { self.forward.contains(key) } fn insert(&mut self, value: &[u8]) -> H256 { let r = self.forward.insert(value); self.inserts.push(r.clone()); r } fn emplace(&mut self, key: H256, value: Bytes) { self.inserts.push(key.clone()); self.forward.emplace(key, value); } - fn kill(&mut self, key: &H256) { self.removes.push(key.clone()); } + fn remove(&mut self, key: &H256) { self.removes.push(key.clone()); } } impl JournalDB for RefCountedDB { @@ -212,16 +207,16 @@ mod tests { let mut jdb = RefCountedDB::new_temp(); let h = jdb.insert(b"foo"); jdb.commit(0, &b"0".sha3(), None).unwrap(); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.remove(&h); jdb.commit(1, &b"1".sha3(), None).unwrap(); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(2, &b"2".sha3(), None).unwrap(); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(3, &b"3".sha3(), Some((0, b"0".sha3()))).unwrap(); - assert!(jdb.exists(&h)); + assert!(jdb.contains(&h)); jdb.commit(4, &b"4".sha3(), Some((1, b"1".sha3()))).unwrap(); - assert!(!jdb.exists(&h)); + assert!(!jdb.contains(&h)); } #[test] @@ -251,34 +246,34 @@ mod tests { let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); jdb.commit(0, &b"0".sha3(), None).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.remove(&foo); jdb.remove(&bar); let baz = jdb.insert(b"baz"); jdb.commit(1, &b"1".sha3(), Some((0, b"0".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); + assert!(jdb.contains(&baz)); let foo = jdb.insert(b"foo"); jdb.remove(&baz); jdb.commit(2, &b"2".sha3(), Some((1, b"1".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&bar)); + assert!(jdb.contains(&baz)); jdb.remove(&foo); jdb.commit(3, &b"3".sha3(), Some((2, b"2".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&bar)); - assert!(!jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&bar)); + assert!(!jdb.contains(&baz)); jdb.commit(4, &b"4".sha3(), Some((3, b"3".sha3()))).unwrap(); - assert!(!jdb.exists(&foo)); - assert!(!jdb.exists(&bar)); - assert!(!jdb.exists(&baz)); + assert!(!jdb.contains(&foo)); + assert!(!jdb.contains(&bar)); + assert!(!jdb.contains(&baz)); } #[test] @@ -289,8 +284,8 @@ mod tests { let foo = jdb.insert(b"foo"); let bar = jdb.insert(b"bar"); jdb.commit(0, &b"0".sha3(), None).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); jdb.remove(&foo); let baz = jdb.insert(b"baz"); @@ -299,13 +294,13 @@ mod tests { jdb.remove(&bar); jdb.commit(1, &b"1b".sha3(), Some((0, b"0".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(jdb.exists(&bar)); - assert!(jdb.exists(&baz)); + assert!(jdb.contains(&foo)); + assert!(jdb.contains(&bar)); + assert!(jdb.contains(&baz)); jdb.commit(2, &b"2b".sha3(), Some((1, b"1b".sha3()))).unwrap(); - assert!(jdb.exists(&foo)); - assert!(!jdb.exists(&baz)); - assert!(!jdb.exists(&bar)); + assert!(jdb.contains(&foo)); + assert!(!jdb.contains(&baz)); + assert!(!jdb.contains(&bar)); } } diff --git a/util/src/keys/directory.rs b/util/src/keys/directory.rs deleted file mode 100644 index 20be7df7b..000000000 --- a/util/src/keys/directory.rs +++ /dev/null @@ -1,1252 +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 . - -//! Keys Directory - -use common::*; -use std::path::{PathBuf}; - -const CURRENT_DECLARED_VERSION: u64 = 3; -const MAX_KEY_FILE_LEN: u64 = 1024 * 80; -const MAX_CACHE_USAGE_TRACK: usize = 128; - -/// Cipher type (currently only aes-128-ctr) -#[derive(PartialEq, Debug, Clone)] -pub enum CryptoCipherType { - /// aes-128-ctr with 128-bit initialisation vector(iv) - Aes128Ctr(H128) -} - -#[derive(PartialEq, Debug, Clone)] -enum KeyFileVersion { - V3(u64) -} - -/// key generator function -#[derive(PartialEq, Debug, Clone)] -pub enum Pbkdf2CryptoFunction { - /// keyed-hash generator (HMAC-256) - HMacSha256 -} - -#[derive(Clone)] -/// Kdf of type `Pbkdf2` -/// https://en.wikipedia.org/wiki/PBKDF2 -pub struct KdfPbkdf2Params { - /// desired length of the derived key, in octets - pub dk_len: u32, - /// cryptographic salt - pub salt: H256, - /// number of iterations for derived key - pub c: u32, - /// pseudo-random 2-parameters function - pub prf: Pbkdf2CryptoFunction -} - -#[derive(Debug)] -enum Pbkdf2ParseError { - InvalidParameter(&'static str), - InvalidPrf(Mismatch), - InvalidSaltFormat(UtilError), - MissingParameter(&'static str), -} - -impl KdfPbkdf2Params { - fn from_json(json: &BTreeMap) -> Result { - Ok(KdfPbkdf2Params{ - salt: match try!(json.get("salt").ok_or(Pbkdf2ParseError::MissingParameter("salt"))).as_string() { - None => { return Err(Pbkdf2ParseError::InvalidParameter("salt")) }, - Some(salt_value) => match H256::from_str(salt_value) { - Ok(salt_hex_value) => salt_hex_value, - Err(from_hex_error) => { return Err(Pbkdf2ParseError::InvalidSaltFormat(from_hex_error)); }, - } - }, - prf: match try!(json.get("prf").ok_or(Pbkdf2ParseError::MissingParameter("prf"))).as_string() { - Some("hmac-sha256") => Pbkdf2CryptoFunction::HMacSha256, - Some(unexpected_prf) => { return Err(Pbkdf2ParseError::InvalidPrf(Mismatch { expected: "hmac-sha256".to_owned(), found: unexpected_prf.to_owned() })); }, - None => { return Err(Pbkdf2ParseError::InvalidParameter("prf")); }, - }, - dk_len: try!(try!(json.get("dklen").ok_or(Pbkdf2ParseError::MissingParameter("dklen"))).as_u64().ok_or(Pbkdf2ParseError::InvalidParameter("dkLen"))) as u32, - c: try!(try!(json.get("c").ok_or(Pbkdf2ParseError::MissingParameter("c"))).as_u64().ok_or(Pbkdf2ParseError::InvalidParameter("c"))) as u32, - }) - } - - fn to_json(&self) -> Json { - let mut map = BTreeMap::new(); - map.insert("dklen".to_owned(), json_from_u32(self.dk_len)); - map.insert("salt".to_owned(), Json::String(format!("{:?}", self.salt))); - map.insert("prf".to_owned(), Json::String("hmac-sha256".to_owned())); - map.insert("c".to_owned(), json_from_u32(self.c)); - Json::Object(map) - } -} - -#[derive(Clone)] -/// Kdf of type `Scrypt`. -/// https://en.wikipedia.org/wiki/Scrypt -pub struct KdfScryptParams { - /// Desired length of the derived key, in octets. - pub dk_len: u32, - /// Parallelization parameter. - pub p: u32, - /// CPU/memory cost parameter. - pub n: u32, - /// TODO: comment - pub r: u32, - /// Cryptographic salt. - pub salt: H256, -} - -#[derive(Debug)] -enum ScryptParseError { - InvalidParameter(&'static str), - InvalidSaltFormat(UtilError), - MissingParameter(&'static str), -} - -fn json_from_u32(number: u32) -> Json { Json::U64(number as u64) } - -impl KdfScryptParams { - fn from_json(json: &BTreeMap) -> Result { - Ok(KdfScryptParams{ - salt: match try!(json.get("salt").ok_or(ScryptParseError::MissingParameter("salt"))).as_string() { - None => { return Err(ScryptParseError::InvalidParameter("salt")) }, - Some(salt_value) => match H256::from_str(salt_value) { - Ok(salt_hex_value) => salt_hex_value, - Err(from_hex_error) => { return Err(ScryptParseError::InvalidSaltFormat(from_hex_error)); }, - } - }, - dk_len: try!(try!(json.get("dklen").ok_or(ScryptParseError::MissingParameter("dklen"))).as_u64().ok_or(ScryptParseError::InvalidParameter("dkLen"))) as u32, - p: try!(try!(json.get("p").ok_or(ScryptParseError::MissingParameter("p"))).as_u64().ok_or(ScryptParseError::InvalidParameter("p"))) as u32, - n: try!(try!(json.get("n").ok_or(ScryptParseError::MissingParameter("n"))).as_u64().ok_or(ScryptParseError::InvalidParameter("n"))) as u32, - r: try!(try!(json.get("r").ok_or(ScryptParseError::MissingParameter("r"))).as_u64().ok_or(ScryptParseError::InvalidParameter("r"))) as u32, - }) - } - - fn to_json(&self) -> Json { - let mut map = BTreeMap::new(); - map.insert("dklen".to_owned(), json_from_u32(self.dk_len)); - map.insert("salt".to_owned(), Json::String(format!("{:?}", self.salt))); - map.insert("p".to_owned(), json_from_u32(self.p)); - map.insert("n".to_owned(), json_from_u32(self.n)); - map.insert("r".to_owned(), json_from_u32(self.r)); - Json::Object(map) - } -} - -#[derive(Clone)] -/// Settings for password derived key geberator function. -pub enum KeyFileKdf { - /// Password-Based Key Derivation Function 2 (PBKDF2) type. - /// https://en.wikipedia.org/wiki/PBKDF2 - Pbkdf2(KdfPbkdf2Params), - /// Scrypt password-based key derivation function. - /// https://en.wikipedia.org/wiki/Scrypt - Scrypt(KdfScryptParams) -} - -#[derive(Clone)] -/// Encrypted password or other arbitrary message -/// with settings for password derived key generator for decrypting content. -pub struct KeyFileCrypto { - /// Cipher type. - pub cipher_type: CryptoCipherType, - /// Cipher text (encrypted message). - pub cipher_text: Bytes, - /// Password derived key generator function settings. - pub kdf: KeyFileKdf, - /// Mac - pub mac: H256 -} - -impl KeyFileCrypto { - fn from_json(json: &Json) -> Result { - let as_object = match json.as_object() { - None => { return Err(CryptoParseError::InvalidJsonFormat); } - Some(obj) => obj - }; - - let cipher_type = match try!(as_object.get("cipher").ok_or(CryptoParseError::NoCipherType)).as_string() { - None => { return Err(CryptoParseError::InvalidCipherType(Mismatch { expected: "aes-128-ctr".to_owned(), found: "not a json string".to_owned() })); } - Some("aes-128-ctr") => CryptoCipherType::Aes128Ctr( - match try!(as_object.get("cipherparams").ok_or(CryptoParseError::NoCipherParameters)).as_object() { - None => { return Err(CryptoParseError::NoCipherParameters); }, - Some(cipher_param) => match H128::from_str(match cipher_param["iv"].as_string() { - None => { return Err(CryptoParseError::NoInitialVector); }, - Some(iv_hex_string) => iv_hex_string - }) - { - Ok(iv_value) => iv_value, - Err(hex_error) => { return Err(CryptoParseError::InvalidInitialVector(hex_error)); } - } - } - ), - Some(other_cipher_type) => { - return Err(CryptoParseError::InvalidCipherType( - Mismatch { expected: "aes-128-ctr".to_owned(), found: other_cipher_type.to_owned() })); - } - }; - - let kdf = match (try!(as_object.get("kdf").ok_or(CryptoParseError::NoKdf)).as_string(), try!(as_object.get("kdfparams").ok_or(CryptoParseError::NoKdfType)).as_object()) { - (None, _) => { return Err(CryptoParseError::NoKdfType); }, - (Some("scrypt"), Some(kdf_params)) => - match KdfScryptParams::from_json(kdf_params) { - Err(scrypt_params_error) => { return Err(CryptoParseError::Scrypt(scrypt_params_error)); }, - Ok(scrypt_params) => KeyFileKdf::Scrypt(scrypt_params) - }, - (Some("pbkdf2"), Some(kdf_params)) => - match KdfPbkdf2Params::from_json(kdf_params) { - Err(pbkdf2_params_error) => { return Err(CryptoParseError::KdfPbkdf2(pbkdf2_params_error)); }, - Ok(pbkdf2_params) => KeyFileKdf::Pbkdf2(pbkdf2_params) - }, - (Some(other_kdf), _) => { - return Err(CryptoParseError::InvalidKdfType( - Mismatch { expected: "pbkdf2/scrypt".to_owned(), found: other_kdf.to_owned()})); - } - }; - - let cipher_text = match try!(as_object.get("ciphertext").ok_or(CryptoParseError::NoCipherText)).as_string() { - None => { return Err(CryptoParseError::InvalidCipherText); } - Some(text) => text - }; - - let mac: H256 = match try!(as_object.get("mac").ok_or(CryptoParseError::NoMac)).as_string() { - None => { return Err(CryptoParseError::InvalidMacFormat(None)) }, - Some(salt_value) => match H256::from_str(salt_value) { - Ok(salt_hex_value) => salt_hex_value, - Err(from_hex_error) => { return Err(CryptoParseError::InvalidMacFormat(Some(from_hex_error))); }, - } - }; - - Ok(KeyFileCrypto { - cipher_text: match FromHex::from_hex(cipher_text) { Ok(bytes) => bytes, Err(_) => { return Err(CryptoParseError::InvalidCipherText); } }, - cipher_type: cipher_type, - kdf: kdf, - mac: mac, - }) - } - - fn to_json(&self) -> Json { - let mut map = BTreeMap::new(); - match self.cipher_type { - CryptoCipherType::Aes128Ctr(ref iv) => { - map.insert("cipher".to_owned(), Json::String("aes-128-ctr".to_owned())); - let mut cipher_params = BTreeMap::new(); - cipher_params.insert("iv".to_owned(), Json::String(format!("{:?}", iv))); - map.insert("cipherparams".to_owned(), Json::Object(cipher_params)); - } - } - map.insert("ciphertext".to_owned(), Json::String( - self.cipher_text.iter().map(|b| format!("{:02x}", b)).collect::>().join(""))); - - map.insert("kdf".to_owned(), Json::String(match self.kdf { - KeyFileKdf::Pbkdf2(_) => "pbkdf2".to_owned(), - KeyFileKdf::Scrypt(_) => "scrypt".to_owned() - })); - - map.insert("kdfparams".to_owned(), match self.kdf { - KeyFileKdf::Pbkdf2(ref pbkdf2_params) => pbkdf2_params.to_json(), - KeyFileKdf::Scrypt(ref scrypt_params) => scrypt_params.to_json() - }); - - map.insert("mac".to_owned(), Json::String(format!("{:?}", self.mac))); - - Json::Object(map) - } - - /// New pbkdf2-type secret. - /// `cipher-text` - encrypted cipher text. - /// `dk-len` - desired length of the derived key, in octets. - /// `c` - number of iterations for derived key. - /// `salt` - cryptographic site, random 256-bit hash (ensure it's crypto-random). - /// `iv` - initialisation vector. - pub fn new_pbkdf2(cipher_text: Bytes, iv: H128, salt: H256, mac: H256, c: u32, dk_len: u32) -> KeyFileCrypto { - KeyFileCrypto { - cipher_type: CryptoCipherType::Aes128Ctr(iv), - cipher_text: cipher_text, - kdf: KeyFileKdf::Pbkdf2(KdfPbkdf2Params { - dk_len: dk_len, - salt: salt, - c: c, - prf: Pbkdf2CryptoFunction::HMacSha256 - }), - mac: mac, - } - } -} - -/// Universally unique identifier -pub type Uuid = H128; - -fn new_uuid() -> Uuid { - H128::random() -} - -fn uuid_to_string(uuid: &Uuid) -> String { - let d1 = &uuid.as_slice()[0..4]; - let d2 = &uuid.as_slice()[4..6]; - let d3 = &uuid.as_slice()[6..8]; - let d4 = &uuid.as_slice()[8..10]; - let d5 = &uuid.as_slice()[10..16]; - format!("{}-{}-{}-{}-{}", d1.to_hex(), d2.to_hex(), d3.to_hex(), d4.to_hex(), d5.to_hex()) -} - -fn uuid_from_string(s: &str) -> Result { - let parts: Vec<&str> = s.split('-').collect(); - if parts.len() != 5 { return Err(UtilError::BadSize); } - - let mut uuid = H128::zero(); - - if parts[0].len() != 8 { return Err(UtilError::BadSize); } - uuid[0..4].clone_from_slice(&try!(FromHex::from_hex(parts[0]))); - if parts[1].len() != 4 { return Err(UtilError::BadSize); } - uuid[4..6].clone_from_slice(&try!(FromHex::from_hex(parts[1]))); - if parts[2].len() != 4 { return Err(UtilError::BadSize); } - uuid[6..8].clone_from_slice(&try!(FromHex::from_hex(parts[2]))); - if parts[3].len() != 4 { return Err(UtilError::BadSize); } - uuid[8..10].clone_from_slice(&try!(FromHex::from_hex(parts[3]))); - if parts[4].len() != 12 { return Err(UtilError::BadSize); } - uuid[10..16].clone_from_slice(&try!(FromHex::from_hex(parts[4]))); - - Ok(uuid) -} - - -#[derive(Clone)] -/// Stored key file struct with encrypted message `(cipher_text)` -/// also contains password derivation function settings (PBKDF2/Scrypt) -pub struct KeyFileContent { - version: KeyFileVersion, - /// Holds cypher and decrypt function settings. - pub crypto: KeyFileCrypto, - /// The identifier. - pub id: Uuid, - /// Account (if present) - pub account: Option
, -} - -#[derive(Debug)] -enum CryptoParseError { - InvalidMacFormat(Option), - NoMac, - NoCipherText, - InvalidCipherText, - NoCipherType, - InvalidJsonFormat, - InvalidKdfType(Mismatch), - InvalidCipherType(Mismatch), - NoInitialVector, - NoCipherParameters, - InvalidInitialVector(UtilError), - NoKdf, - NoKdfType, - Scrypt(ScryptParseError), - KdfPbkdf2(Pbkdf2ParseError) -} - -#[derive(Debug)] -enum KeyFileParseError { - InvalidVersion, - UnsupportedVersion(OutOfBounds), - InvalidJsonFormat, - InvalidJson, - InvalidIdentifier, - NoCryptoSection, - Crypto(CryptoParseError), -} - -impl KeyFileContent { - /// New stored key file struct with encrypted message (`cipher_text`) - /// also contains password derivation function settings (PBKDF2/Scrypt) - /// to decrypt `cipher_text` given the password is provided. - pub fn new(crypto: KeyFileCrypto) -> KeyFileContent { - KeyFileContent { - id: new_uuid(), - version: KeyFileVersion::V3(3), - crypto: crypto, - account: None - } - } - - /// Loads key from valid json, returns error and records warning if key is malformed - pub fn load(json: &Json) -> Result { - match Self::from_json(json) { - Ok(key_file) => Ok(key_file), - Err(e) => { - warn!(target: "sstore", "Error parsing json for key: {:?}", e); - Err(()) - } - } - } - - /// Returns key file version if it is known. - pub fn version(&self) -> Option { - match self.version { - KeyFileVersion::V3(declared) => Some(declared) - } - } - - fn from_json(json: &Json) -> Result { - let as_object = match json.as_object() { - None => { return Err(KeyFileParseError::InvalidJsonFormat); }, - Some(obj) => obj - }; - - let version = match as_object["version"].as_u64() { - None => { return Err(KeyFileParseError::InvalidVersion); }, - Some(json_version) => { - if json_version <= 2 { - return Err(KeyFileParseError::UnsupportedVersion(OutOfBounds { min: Some(3), max: None, found: json_version })) - }; - KeyFileVersion::V3(json_version) - } - }; - - let id_text = try!(as_object.get("id").and_then(|json| json.as_string()).ok_or(KeyFileParseError::InvalidIdentifier)); - let id = match uuid_from_string(&id_text) { - Err(_) => { return Err(KeyFileParseError::InvalidIdentifier); }, - Ok(id) => id - }; - - let account = as_object.get("address").and_then(|json| json.as_string()).and_then( - |account_text| match Address::from_str(account_text) { Ok(account) => Some(account), Err(_) => None }); - - let crypto = match as_object.get("crypto") { - None => { return Err(KeyFileParseError::NoCryptoSection); } - Some(crypto_json) => match KeyFileCrypto::from_json(crypto_json) { - Ok(crypto) => crypto, - Err(crypto_error) => { return Err(KeyFileParseError::Crypto(crypto_error)); } - } - }; - - Ok(KeyFileContent { - version: version, - id: id.clone(), - crypto: crypto, - account: account - }) - } - - fn to_json(&self) -> Json { - let mut map = BTreeMap::new(); - map.insert("id".to_owned(), Json::String(uuid_to_string(&self.id))); - map.insert("version".to_owned(), Json::U64(CURRENT_DECLARED_VERSION)); - map.insert("crypto".to_owned(), self.crypto.to_json()); - if let Some(ref address) = self.account { map.insert("address".to_owned(), Json::String(format!("{:?}", address))); } - Json::Object(map) - } -} - -#[derive(Debug)] -enum KeyFileLoadError { - TooLarge(OutOfBounds), - ParseError(KeyFileParseError), - ReadError(::std::io::Error), -} - -/// Represents directory for saving/loading key files. -pub struct KeyDirectory { - /// Directory path for key management. - path: String, - cache: RwLock>, - cache_usage: RwLock>, -} - -/// Restricts the permissions of given path only to the owner. -pub fn restrict_permissions_owner(file_path: &Path) -> Result<(), i32> { - let cstr = ::std::ffi::CString::new(file_path.to_str().unwrap()).unwrap(); - match unsafe { ::libc::chmod(cstr.as_ptr(), ::libc::S_IWUSR | ::libc::S_IRUSR) } { - 0 => Ok(()), - x => Err(x), - } -} - -impl KeyDirectory { - /// Initializes new cache directory context with a given `path` - pub fn new(path: &Path) -> KeyDirectory { - KeyDirectory { - cache: RwLock::new(HashMap::new()), - path: path.to_str().expect("Initialized key directory with empty path").to_owned(), - cache_usage: RwLock::new(VecDeque::new()), - } - } - - /// saves (inserts or updates) given key - pub fn save(&mut self, key_file: KeyFileContent) -> Result<(Uuid), ::std::io::Error> { - { - let mut file = try!(fs::File::create(self.key_path(&key_file.id))); - let json = key_file.to_json(); - let json_text = format!("{}", json.pretty()); - let json_bytes = json_text.into_bytes(); - try!(file.write(&json_bytes)); - } - if let Err(error_code) = restrict_permissions_owner(self.key_path(&key_file.id).as_path()) { - fs::remove_file(self.key_path(&key_file.id)).unwrap(); - warn!(target: "sstore", "fatal: failed to modify permissions of the file (chmod: {})", error_code); - return Err(::std::io::Error::last_os_error()); - } - let mut cache = self.cache.write().unwrap(); - let id = key_file.id.clone(); - cache.insert(id.clone(), key_file); - Ok(id.clone()) - } - - /// Returns key given by id if corresponding file exists and no load error occured. - /// Warns if any error occured during the key loading - pub fn get(&self, id: &Uuid) -> Option { - let path = self.key_path(id); - { - let mut usage = self.cache_usage.write().unwrap(); - usage.push_back(id.clone()); - } - - if !self.cache.read().unwrap().contains_key(id) { - match KeyDirectory::load_key(&path) { - Ok(loaded_key) => { - self.cache.write().unwrap().insert(id.to_owned(), loaded_key); - } - Err(error) => { - warn!(target: "sstore", "error loading key {:?}: {:?}", id, error); - return None; - } - } - } - - // todo: replace with Ref::map when it stabilized to avoid copies - Some(self.cache.read().unwrap().get(id) - .expect("Key should be there, we have just inserted or checked it.") - .clone()) - } - - /// Returns current path to the directory with keys - pub fn path(&self) -> &str { - &self.path - } - - /// Removes keys that never been requested during last `MAX_USAGE_TRACK` times - pub fn collect_garbage(&mut self) { - let mut cache_usage = self.cache_usage.write().unwrap(); - - let total_usages = cache_usage.len(); - let untracked_usages = max(total_usages as i64 - MAX_CACHE_USAGE_TRACK as i64, 0) as usize; - if untracked_usages > 0 { - cache_usage.drain(..untracked_usages); - } - - if self.cache.read().unwrap().len() <= MAX_CACHE_USAGE_TRACK { return; } - - let uniqs: HashSet<&Uuid> = cache_usage.iter().collect(); - let removes:Vec = { - let cache = self.cache.read().unwrap(); - cache.keys().cloned().filter(|key| !uniqs.contains(key)).collect() - }; - if removes.is_empty() { return; } - let mut cache = self.cache.write().unwrap(); - for key in removes { cache.remove(&key); } - - cache.shrink_to_fit(); - } - - /// Reports how many keys are currently cached. - pub fn cache_size(&self) -> usize { - self.cache.read().unwrap().len() - } - - /// Removes key file from key directory - pub fn delete(&mut self, id: &Uuid) -> Result<(), ::std::io::Error> { - let path = self.key_path(id); - - if !self.cache.read().unwrap().contains_key(id) { - return match fs::remove_file(&path) { - Ok(_) => { - self.cache.write().unwrap().remove(&id); - Ok(()) - }, - Err(e) => Err(e) - }; - } - Ok(()) - } - - /// Enumerates all keys in the directory - pub fn list(&self) -> Result, ::std::io::Error> { - let mut result = Vec::new(); - for entry in try!(fs::read_dir(&self.path)) { - let entry = try!(entry); - if !try!(fs::metadata(entry.path())).is_dir() { - match entry.file_name().to_str() { - Some(ref name) => { - if let Ok(uuid) = uuid_from_string(name) { result.push(uuid); } - }, - None => { continue; } - }; - - } - } - Ok(result) - } - - fn key_path(&self, id: &Uuid) -> PathBuf { - let mut path = PathBuf::new(); - path.push(self.path.clone()); - path.push(uuid_to_string(&id)); - path - } - - fn load_key(path: &PathBuf) -> Result { - match fs::File::open(path.clone()) { - Ok(mut open_file) => { - match open_file.metadata() { - Ok(metadata) => - if metadata.len() > MAX_KEY_FILE_LEN { Err(KeyFileLoadError::TooLarge(OutOfBounds { min: Some(2), max: Some(MAX_KEY_FILE_LEN), found: metadata.len() })) } - else { KeyDirectory::load_from_file(&mut open_file) }, - Err(read_error) => Err(KeyFileLoadError::ReadError(read_error)) - } - }, - Err(read_error) => Err(KeyFileLoadError::ReadError(read_error)) - } - } - - fn load_from_file(file: &mut fs::File) -> Result { - let mut buf = String::new(); - match file.read_to_string(&mut buf) { - Ok(_) => {}, - Err(read_error) => { return Err(KeyFileLoadError::ReadError(read_error)); } - } - match Json::from_str(&buf) { - Ok(json) => match KeyFileContent::from_json(&json) { - Ok(key_file_content) => Ok(key_file_content), - Err(parse_error) => Err(KeyFileLoadError::ParseError(parse_error)) - }, - Err(_) => Err(KeyFileLoadError::ParseError(KeyFileParseError::InvalidJson)) - } - } - - -} - - -#[cfg(test)] -mod file_tests { - use super::{KeyFileContent, KeyFileVersion, KeyFileKdf, KeyFileParseError, CryptoParseError, uuid_from_string, uuid_to_string, KeyFileCrypto, KdfPbkdf2Params}; - use common::*; - - #[test] - fn uuid_parses() { - let uuid = uuid_from_string("3198bc9c-6672-5ab3-d995-4942343ae5b6").unwrap(); - assert!(uuid > H128::zero()); - } - - #[test] - fn uuid_serializes() { - let uuid = uuid_from_string("3198bc9c-6fff-5ab3-d995-4942343ae5b6").unwrap(); - assert_eq!(uuid_to_string(&uuid), "3198bc9c-6fff-5ab3-d995-4942343ae5b6"); - } - - #[test] - fn can_read_keyfile() { - let json = Json::from_str( - r#" - { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "6087dab2f9fdbbfaddc31a909735c1e6" - }, - "ciphertext" : "5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46", - "kdf" : "pbkdf2", - "kdfparams" : { - "c" : 262144, - "dklen" : 32, - "prf" : "hmac-sha256", - "salt" : "ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd" - }, - "mac" : "517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 - } - "#).unwrap(); - - match KeyFileContent::from_json(&json) { - Ok(key_file) => { - assert_eq!(KeyFileVersion::V3(3), key_file.version) - }, - Err(e) => panic!("Error parsing valid file: {:?}", e) - } - } - - #[test] - fn can_read_scrypt_kdf() { - let json = Json::from_str( - r#" - { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 - } - "#).unwrap(); - - match KeyFileContent::from_json(&json) { - Ok(key_file) => { - match key_file.crypto.kdf { - KeyFileKdf::Scrypt(_) => {}, - _ => { panic!("expected kdf params of crypto to be of scrypt type" ); } - } - }, - Err(e) => panic!("Error parsing valid file: {:?}", e) - } - } - - #[test] - fn can_read_scrypt_kdf_params() { - let json = Json::from_str( - r#" - { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 - } - "#).unwrap(); - - match KeyFileContent::from_json(&json) { - Ok(key_file) => { - match key_file.crypto.kdf { - KeyFileKdf::Scrypt(scrypt_params) => { - assert_eq!(262144, scrypt_params.n); - assert_eq!(1, scrypt_params.r); - assert_eq!(8, scrypt_params.p); - }, - _ => { panic!("expected kdf params of crypto to be of scrypt type" ); } - } - }, - Err(e) => panic!("Error parsing valid file: {:?}", e) - } - } - - #[test] - fn can_return_error_no_id() { - let json = Json::from_str( - r#" - { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "version" : 3 - } - "#).unwrap(); - - match KeyFileContent::from_json(&json) { - Ok(_) => { - panic!("Should be error of no crypto section, got ok"); - }, - Err(KeyFileParseError::InvalidIdentifier) => { }, - Err(other_error) => { panic!("should be error of no crypto section, got {:?}", other_error); } - } - } - - #[test] - fn can_return_error_no_crypto() { - let json = Json::from_str( - r#" - { - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 - } - "#).unwrap(); - - match KeyFileContent::from_json(&json) { - Ok(_) => { - panic!("Should be error of no identifier, got ok"); - }, - Err(KeyFileParseError::NoCryptoSection) => { }, - Err(other_error) => { panic!("should be error of no identifier, got {:?}", other_error); } - } - } - - #[test] - fn can_return_error_unsupported_version() { - let json = Json::from_str( - r#" - { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 1 - } - "#).unwrap(); - - match KeyFileContent::from_json(&json) { - Ok(_) => { - panic!("should be error of unsupported version, got ok"); - }, - Err(KeyFileParseError::UnsupportedVersion(_)) => { }, - Err(other_error) => { panic!("should be error of unsupported version, got {:?}", other_error); } - } - } - - - #[test] - fn can_return_error_initial_vector() { - let json = Json::from_str( - r#" - { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e4______66191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 - } - "#).unwrap(); - - match KeyFileContent::from_json(&json) { - Ok(_) => { - panic!("should be error of invalid initial vector, got ok"); - }, - Err(KeyFileParseError::Crypto(CryptoParseError::InvalidInitialVector(_))) => { }, - Err(other_error) => { panic!("should be error of invalid initial vector, got {:?}", other_error); } - } - } - - #[test] - fn can_return_error_for_invalid_scrypt_kdf() { - let json = Json::from_str( - r#" - { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen2" : 32, - "n5" : "xx", - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 - } - "#).unwrap(); - - match KeyFileContent::from_json(&json) { - Ok(_) => { - panic!("Should be error of no identifier, got ok"); - }, - Err(KeyFileParseError::Crypto(CryptoParseError::Scrypt(_))) => { }, - Err(other_error) => { panic!("should be scrypt parse error, got {:?}", other_error); } - } - } - - #[test] - fn can_serialize_scrypt_back() { - let json = Json::from_str( - r#" - { - "crypto" : { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }, - "id" : "3198bc9c-6672-5ab3-d995-4942343ae5b6", - "version" : 3 - } - "#).unwrap(); - - let key = KeyFileContent::from_json(&json).unwrap(); - let serialized = key.to_json(); - - assert!(serialized.as_object().is_some()); - } - - #[test] - fn can_create_key_with_new_id() { - let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); - let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, H128::zero(), H256::random(), H256::random(), 32, 32)); - assert!(!uuid_to_string(&key.id).is_empty()); - } - - #[test] - fn can_load_json_from_itself() { - let cipher_text: Bytes = FromHex::from_hex("aaaaaaaaaaaaaaaaaaaaaaaaaaa22222222222222222222222").unwrap(); - let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, H128::zero(), H256::random(), H256::random(), 32, 32)); - let json = key.to_json(); - - let loaded_key = KeyFileContent::from_json(&json).unwrap(); - - assert_eq!(loaded_key.id, key.id); - } - - #[test] - fn can_parse_kdf_params_fail() { - let json = Json::from_str( - r#" - { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - } - "#).unwrap(); - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.remove("dklen"); - let kdf = KdfPbkdf2Params::from_json(&invalid_json); - assert!(!kdf.is_ok()); - } - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.remove("n"); - let kdf = KdfPbkdf2Params::from_json(&invalid_json); - assert!(!kdf.is_ok()); - } - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.remove("r"); - let kdf = KdfPbkdf2Params::from_json(&invalid_json); - assert!(!kdf.is_ok()); - } - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.remove("p"); - let kdf = KdfPbkdf2Params::from_json(&invalid_json); - assert!(!kdf.is_ok()); - } - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.remove("salt"); - let kdf = KdfPbkdf2Params::from_json(&invalid_json); - assert!(!kdf.is_ok()); - } - - } - - #[test] - fn can_parse_kdf_params_scrypt_fail() { - let json = Json::from_str( - r#" - { - "dklen" : 32, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - } - "#).unwrap(); - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.remove("dklen"); - let kdf = KdfPbkdf2Params::from_json(&invalid_json); - assert!(!kdf.is_ok()); - } - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.remove("r"); - let kdf = KdfPbkdf2Params::from_json(&invalid_json); - assert!(!kdf.is_ok()); - } - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.remove("p"); - let kdf = KdfPbkdf2Params::from_json(&invalid_json); - assert!(!kdf.is_ok()); - } - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.remove("salt"); - let kdf = KdfPbkdf2Params::from_json(&invalid_json); - assert!(!kdf.is_ok()); - } - } - - #[test] - fn can_parse_crypto_fails() { - let json = Json::from_str( - r#" - { - "cipher" : "aes-128-ctr", - "cipherparams" : { - "iv" : "83dbcc02d8ccb40e466191a123791e0e" - }, - "ciphertext" : "d172bf743a674da9cdad04534d56926ef8358534d458fffccd4e6ad2fbde479c", - "kdf" : "scrypt", - "kdfparams" : { - "dklen" : 32, - "n" : 262144, - "r" : 1, - "p" : 8, - "salt" : "ab0c7876052600dd703518d6fc3fe8984592145b591fc8fb5c6d43190334ba19" - }, - "mac" : "2103ac29920d71da29f15d75b4a16dbe95cfd7ff8faea1056c33131d846e3097" - }"#).unwrap(); - - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.insert("cipher".to_owned(), Json::String("unknown".to_owned())); - let crypto = KeyFileCrypto::from_json(&Json::Object(invalid_json)); - assert!(!crypto.is_ok()); - } - - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.insert("kdfparams".to_owned(), Json::String("122".to_owned())); - let crypto = KeyFileCrypto::from_json(&Json::Object(invalid_json)); - assert!(!crypto.is_ok()); - } - - { - let mut invalid_json = json.as_object().unwrap().clone(); - invalid_json.insert("kdf".to_owned(), Json::String("15522".to_owned())); - let crypto = KeyFileCrypto::from_json(&Json::Object(invalid_json)); - assert!(!crypto.is_ok()); - } - - } - -} - -#[cfg(test)] -mod directory_tests { - use super::{KeyDirectory, new_uuid, uuid_to_string, KeyFileContent, KeyFileCrypto, MAX_CACHE_USAGE_TRACK}; - use common::*; - use devtools::*; - - #[test] - fn key_directory_locates_keys() { - let temp_path = RandomTempPath::create_dir(); - let directory = KeyDirectory::new(temp_path.as_path()); - let uuid = new_uuid(); - - let path = directory.key_path(&uuid); - - assert!(path.to_str().unwrap().contains(&uuid_to_string(&uuid))); - } - - #[test] - fn loads_key() { - let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); - let temp_path = RandomTempPath::create_dir(); - let mut directory = KeyDirectory::new(&temp_path.as_path()); - let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, H128::zero(), H256::random(), H256::random(), 32, 32))).unwrap(); - let path = directory.key_path(&uuid); - - let key = KeyDirectory::load_key(&path).unwrap(); - - assert_eq!(key.id, uuid); - } - - #[test] - fn caches_keys() { - let temp_path = RandomTempPath::create_dir(); - let mut directory = KeyDirectory::new(&temp_path.as_path()); - - let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); - let mut keys = Vec::new(); - for _ in 0..1000 { - let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32)); - keys.push(directory.save(key).unwrap()); - } - - for key_id in keys { - directory.get(&key_id).unwrap(); - } - - assert_eq!(1000, directory.cache_size()) - - } - - #[test] - fn collects_garbage() { - let temp_path = RandomTempPath::create_dir(); - let mut directory = KeyDirectory::new(&temp_path.as_path()); - - let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); - let mut keys = Vec::new(); - for _ in 0..1000 { - let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32)); - keys.push(directory.save(key).unwrap()); - } - - for key_id in keys { - directory.get(&key_id).unwrap(); - } - - directory.collect_garbage(); - // since all keys are different, should be exactly MAX_CACHE_USAGE_TRACK - assert_eq!(MAX_CACHE_USAGE_TRACK, directory.cache_size()) - } - - #[test] - fn collects_garbage_on_empty() { - let temp_path = RandomTempPath::create_dir(); - let mut directory = KeyDirectory::new(&temp_path.as_path()); - directory.collect_garbage(); - assert_eq!(0, directory.cache_size()) - } -} - -#[cfg(test)] -mod specs { - use super::*; - use common::*; - use devtools::*; - - #[test] - fn can_initiate_key_directory() { - let temp_path = RandomTempPath::create_dir(); - let directory = KeyDirectory::new(&temp_path.as_path()); - assert!(directory.path().len() > 0); - } - - #[test] - fn can_save_key() { - let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); - let temp_path = RandomTempPath::create_dir(); - let mut directory = KeyDirectory::new(&temp_path.as_path()); - - let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text, H128::zero(), H256::random(), H256::random(), 32, 32))); - - assert!(uuid.is_ok()); - } - - #[test] - fn can_load_key() { - let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); - let temp_path = RandomTempPath::create_dir(); - let mut directory = KeyDirectory::new(&temp_path.as_path()); - let uuid = directory.save(KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32))).unwrap(); - - let key = directory.get(&uuid).unwrap(); - - assert_eq!(key.crypto.cipher_text, cipher_text); - } - - #[test] - fn can_store_10_keys() { - let temp_path = RandomTempPath::create_dir(); - let mut directory = KeyDirectory::new(&temp_path.as_path()); - - let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); - let mut keys = Vec::new(); - for _ in 0..10 { - let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32)); - keys.push(directory.save(key).unwrap()); - } - - assert_eq!(10, keys.len()) - } - - #[test] - fn can_list_keys() { - let temp_path = RandomTempPath::create_dir(); - let mut directory = KeyDirectory::new(&temp_path.as_path()); - - let cipher_text: Bytes = FromHex::from_hex("a0f05555").unwrap(); - let mut keys = Vec::new(); - for _ in 0..33 { - let key = KeyFileContent::new(KeyFileCrypto::new_pbkdf2(cipher_text.clone(), H128::zero(), H256::random(), H256::random(), 32, 32)); - keys.push(directory.save(key).unwrap()); - } - - assert_eq!(33, directory.list().unwrap().len()); - } -} diff --git a/util/src/keys/geth_import.rs b/util/src/keys/geth_import.rs deleted file mode 100644 index 509ebc89f..000000000 --- a/util/src/keys/geth_import.rs +++ /dev/null @@ -1,261 +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 . - -//! Geth keys import/export tool - -use common::*; -use keys::store::SecretStore; -use keys::directory::KeyFileContent; -use std::path::PathBuf; -use path; - -/// Enumerates all geth keys in the directory and returns collection of tuples `(accountId, filename)` -pub fn enumerate_geth_keys(path: &Path) -> Result, ImportError> { - let mut entries = Vec::new(); - for entry in try!(fs::read_dir(path)) { - let entry = try!(entry); - if !try!(fs::metadata(entry.path())).is_dir() { - match entry.file_name().to_str() { - Some(name) => { - let parts: Vec<&str> = name.split("--").collect(); - if parts.len() != 3 { continue; } - let account_id = try!(Address::from_str(parts[2]).map_err(|_| ImportError::Format)); - entries.push((account_id, name.to_owned())); - }, - None => { continue; } - }; - } - } - Ok(entries) -} - -/// Geth import error -#[derive(Debug)] -pub enum ImportError { - /// Io error reading geth file - Io(io::Error), - /// format error - Format, -} - -impl From for ImportError { - fn from (err: io::Error) -> ImportError { - ImportError::Io(err) - } -} - -/// Imports one geth key to the store -pub fn import_geth_key(secret_store: &mut SecretStore, geth_keyfile_path: &Path) -> Result<(), ImportError> { - let mut file = try!(fs::File::open(geth_keyfile_path)); - let mut buf = String::new(); - try!(file.read_to_string(&mut buf)); - - let mut json_result = Json::from_str(&buf); - let mut json = match json_result { - Ok(ref mut parsed_json) => try!(parsed_json.as_object_mut().ok_or(ImportError::Format)), - Err(_) => { return Err(ImportError::Format); } - }; - if let Some(crypto_object) = json.get("Crypto").and_then(|crypto| crypto.as_object()).cloned() { - json.insert("crypto".to_owned(), Json::Object(crypto_object)); - json.remove("Crypto"); - } - match KeyFileContent::load(&Json::Object(json.clone())) { - Ok(key_file) => try!(secret_store.import_key(key_file)), - Err(_) => { return Err(ImportError::Format); } - }; - Ok(()) -} - -/// Imports all geth keys in the directory -pub fn import_geth_keys(secret_store: &mut SecretStore, geth_keyfiles_directory: &Path) -> Result { - use std::path::PathBuf; - let geth_files = try!(enumerate_geth_keys(geth_keyfiles_directory)); - let mut total = 0; - for &(ref address, ref file_path) in &geth_files { - let mut path = PathBuf::new(); - path.push(geth_keyfiles_directory); - path.push(file_path); - if let Err(e) = import_geth_key(secret_store, Path::new(&path)) { - warn!("Skipped geth address {}, error importing: {:?}", address, e) - } - else { total = total + 1} - } - Ok(total) -} - - -/// Gets the default geth keystore directory. -pub fn keystore_dir(is_testnet: bool) -> PathBuf { - path::ethereum::with_default(if is_testnet {"testnet/keystore"} else {"keystore"}) -} - -/// Imports key(s) from provided file/directory -pub fn import_keys_path(secret_store: &mut SecretStore, path: &str) -> Result { - // check if it is just one file or directory - if let Ok(meta) = fs::metadata(path) { - if meta.is_file() { - try!(import_geth_key(secret_store, Path::new(path))); - return Ok(1); - } - else if meta.is_dir() { - return Ok(try!(fs::read_dir(path)).fold( - 0, - |total, p| - total + - match p { - Ok(dir_entry) => import_keys_path(secret_store, dir_entry.path().to_str().unwrap()).unwrap_or_else(|_| 0), - Err(e) => { warn!("Error importing dir entry: {:?}", e); 0 }, - } - )) - } - } - Ok(0) -} - -/// Imports all keys from list of provided files/directories -pub fn import_keys_paths(secret_store: &mut SecretStore, path: &[String]) -> Result { - Ok(path.iter().fold(0, |total, ref p| total + import_keys_path(secret_store, &p).unwrap_or_else(|_| 0))) -} - -#[cfg(test)] -mod tests { - use super::*; - use common::*; - use keys::store::SecretStore; - - fn test_path() -> &'static str { - match ::std::fs::metadata("res") { - Ok(_) => "res/geth_keystore", - Err(_) => "util/res/geth_keystore" - } - } - - fn pat_path() -> &'static str { - match ::std::fs::metadata("res") { - Ok(_) => "res/pat", - Err(_) => "util/res/pat" - } - } - - fn test_path_param(param_val: &'static str) -> String { - test_path().to_owned() + param_val - } - - fn pat_path_param(param_val: &'static str) -> String { - pat_path().to_owned() + param_val - } - - #[test] - fn can_enumerate() { - let keys = enumerate_geth_keys(Path::new(test_path())).unwrap(); - assert_eq!(3, keys.len()); - } - - #[test] - fn can_import_geth_old() { - let temp = ::devtools::RandomTempPath::create_dir(); - let mut secret_store = SecretStore::new_in(temp.as_path()); - import_geth_key(&mut secret_store, Path::new(&test_path_param("/UTC--2016-02-17T09-20-45.721400158Z--3f49624084b67849c7b4e805c5988c21a430f9d9"))).unwrap(); - let key = secret_store.account(&Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap()); - assert!(key.is_some()); - } - - #[test] - fn can_import_geth140() { - let temp = ::devtools::RandomTempPath::create_dir(); - let mut secret_store = SecretStore::new_in(temp.as_path()); - import_geth_key(&mut secret_store, Path::new(&test_path_param("/UTC--2016-04-03T08-58-49.834202900Z--63121b431a52f8043c16fcf0d1df9cb7b5f66649"))).unwrap(); - let key = secret_store.account(&Address::from_str("63121b431a52f8043c16fcf0d1df9cb7b5f66649").unwrap()); - assert!(key.is_some()); - } - - #[test] - fn can_import_directory() { - let temp = ::devtools::RandomTempPath::create_dir(); - let mut secret_store = SecretStore::new_in(temp.as_path()); - import_geth_keys(&mut secret_store, Path::new(test_path())).unwrap(); - - let key = secret_store.account(&Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap()); - assert!(key.is_some()); - - let key = secret_store.account(&Address::from_str("5ba4dcf897e97c2bdf8315b9ef26c13c085988cf").unwrap()); - assert!(key.is_some()); - } - - #[test] - fn imports_as_scrypt_keys() { - use keys::directory::{KeyDirectory, KeyFileKdf}; - let temp = ::devtools::RandomTempPath::create_dir(); - { - let mut secret_store = SecretStore::new_in(temp.as_path()); - import_geth_keys(&mut secret_store, Path::new(test_path())).unwrap(); - } - - let key_directory = KeyDirectory::new(&temp.as_path()); - let key_file = key_directory.get(&H128::from_str("62a0ad73556d496a8e1c0783d30d3ace").unwrap()).unwrap(); - - match key_file.crypto.kdf { - KeyFileKdf::Scrypt(scrypt_params) => { - assert_eq!(262144, scrypt_params.n); - assert_eq!(8, scrypt_params.r); - assert_eq!(1, scrypt_params.p); - }, - _ => { panic!("expected kdf params of crypto to be of scrypt type" ); } - } - } - - #[test] - #[cfg(feature="heavy-tests")] - fn can_decrypt_with_imported() { - use keys::store::EncryptedHashMap; - - let temp = ::devtools::RandomTempPath::create_dir(); - let mut secret_store = SecretStore::new_in(temp.as_path()); - import_geth_keys(&mut secret_store, Path::new(test_path())).unwrap(); - - let val = secret_store.get::(&H128::from_str("62a0ad73556d496a8e1c0783d30d3ace").unwrap(), "123"); - assert!(val.is_ok()); - assert_eq!(32, val.unwrap().len()); - } - - #[test] - fn can_import_by_filename() { - let temp = ::devtools::RandomTempPath::create_dir(); - let mut secret_store = SecretStore::new_in(temp.as_path()); - - let amount = import_keys_path(&mut secret_store, &pat_path_param("/p1.json")).unwrap(); - assert_eq!(1, amount); - } - - #[test] - fn can_import_by_dir() { - let temp = ::devtools::RandomTempPath::create_dir(); - let mut secret_store = SecretStore::new_in(temp.as_path()); - - let amount = import_keys_path(&mut secret_store, pat_path()).unwrap(); - assert_eq!(2, amount); - } - - #[test] - fn can_import_mulitple() { - let temp = ::devtools::RandomTempPath::create_dir(); - let mut secret_store = SecretStore::new_in(temp.as_path()); - - let amount = import_keys_paths(&mut secret_store, &[pat_path_param("/p1.json"), pat_path_param("/p2.json")]).unwrap(); - assert_eq!(2, amount); - } - -} diff --git a/util/src/keys/store.rs b/util/src/keys/store.rs deleted file mode 100644 index f6f41745f..000000000 --- a/util/src/keys/store.rs +++ /dev/null @@ -1,750 +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 . - -//! Secret Store - -use keys::directory::*; -use common::*; -use rcrypto::pbkdf2::*; -use rcrypto::scrypt::*; -use rcrypto::hmac::*; -use crypto; -use chrono::*; - -const KEY_LENGTH: u32 = 32; -const KEY_ITERATIONS: u32 = 10240; -const KEY_LENGTH_AES: u32 = KEY_LENGTH/2; - -const KEY_LENGTH_USIZE: usize = KEY_LENGTH as usize; -const KEY_LENGTH_AES_USIZE: usize = KEY_LENGTH_AES as usize; - -// TODO: this file needs repotting into several separate files. - -/// Encrypted hash-map, each request should contain password -pub trait EncryptedHashMap { - /// Returns existing value for the key, if any - fn get(&self, key: &Key, password: &str) -> Result; - /// Insert new encrypted key-value and returns previous if there was any - fn insert(&mut self, key: Key, value: Value, password: &str) -> Option; - /// Removes key-value by key and returns the removed one, if any exists and password was provided - fn remove (&mut self, key: &Key, password: Option<&str>) -> Option; - /// Deletes key-value by key and returns if the key-value existed - fn delete(&mut self, key: &Key) -> bool { - self.remove::(key, None).is_some() - } -} - -/// Error retrieving value from encrypted hashmap -#[derive(Debug)] -pub enum EncryptedHashMapError { - /// Encryption failed - InvalidPassword, - /// No key in the hashmap - UnknownIdentifier, - /// Stored value is not well formed for the requested type - InvalidValueFormat(FromBytesError), -} - -/// Error while signing a message -#[derive(Debug)] -pub enum SigningError { - /// Account passed does not exist - NoAccount, - /// Account passed is not unlocked - AccountNotUnlocked, - /// Invalid passphrase - InvalidPassword, - /// Invalid secret in store - InvalidSecret -} - -/// Represent service for storing encrypted arbitrary data -pub struct SecretStore { - directory: KeyDirectory, - unlocks: RwLock>, - key_iterations: u32, -} - -struct AccountUnlock { - secret: H256, - /// expiration datetime (None - never) - expires: Option>, - /// Sccount should be relocked after first use. - relock_on_use: bool, -} - -/// Basic account management trait -pub trait AccountProvider: Send + Sync { - /// Lists all accounts - fn accounts(&self) -> Result, ::std::io::Error>; - /// Unlocks account with the password provided - fn unlock_account(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError>; - /// Unlocks account with the password provided; relocks it on the next call to `account_secret` or `sign`. - fn unlock_account_temp(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError>; - /// Creates account - fn new_account(&self, pass: &str) -> Result; - /// Returns secret for unlocked `account`. - fn account_secret(&self, account: &Address) -> Result; - /// Returns secret for locked account given passphrase. - fn locked_account_secret(&self, account: &Address, pass: &str) -> Result; - /// Returns signature when unlocked `account` signs `message`. - fn sign(&self, account: &Address, message: &H256) -> Result { - self.account_secret(account).and_then(|s| crypto::ec::sign(&s, message).map_err(|_| SigningError::InvalidSecret)) - } -} - -/// Thread-safe accounts management -pub struct AccountService { - secret_store: RwLock, -} - -impl AccountProvider for AccountService { - /// Lists all accounts - fn accounts(&self) -> Result, ::std::io::Error> { - Ok(try!(self.secret_store.read().unwrap().accounts()).iter().map(|&(addr, _)| addr).collect::>()) - } - /// Unlocks account with the password provided - fn unlock_account(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> { - self.secret_store.read().unwrap().unlock_account(account, pass) - } - fn unlock_account_temp(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> { - self.secret_store.read().unwrap().unlock_account_temp(account, pass) - } - /// Creates account - fn new_account(&self, pass: &str) -> Result { - self.secret_store.write().unwrap().new_account(pass) - } - /// Returns secret for unlocked account - fn account_secret(&self, account: &Address) -> Result { - self.secret_store.read().unwrap().account_secret(account) - } - /// Returns secret for locked account given passphrase. - fn locked_account_secret(&self, account: &Address, pass: &str) -> Result { - self.secret_store.read().unwrap().locked_account_secret(account, pass) - } - /// Signs a message using key of given unlocked account address. - fn sign(&self, account: &Address, message: &H256) -> Result { - self.secret_store.read().unwrap().sign(account, message) - } -} - -/// Which set of keys to import. -#[derive(PartialEq)] -pub enum ImportKeySet { - /// Empty set. - None, - /// Import legacy client's general keys. - Legacy, - /// Import legacy client's testnet keys. - LegacyTestnet, -} - -impl AccountService { - /// New account service with the keys store in specific location and configured security parameters. - pub fn with_security(path: &Path, key_iterations: u32, import_keys: ImportKeySet) -> Self { - let secret_store = RwLock::new(SecretStore::with_security(path, key_iterations)); - match import_keys { - ImportKeySet::None => {} - _ => { secret_store.write().unwrap().try_import_existing(import_keys == ImportKeySet::LegacyTestnet); } - } - AccountService { - secret_store: secret_store, - } - } - - #[cfg(test)] - fn new_test(temp: &::devtools::RandomTempPath) -> Self { - let secret_store = RwLock::new(SecretStore::new_test(temp)); - AccountService { - secret_store: secret_store - } - } - - /// Ticks the account service - pub fn tick(&self) { - self.secret_store.write().unwrap().collect_garbage(); - } - - /// Unlocks account for use (no expiration of unlock) - pub fn unlock_account_no_expire(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> { - self.secret_store.write().unwrap().unlock_account_with_expiration(account, pass, None, false) - } -} - -impl SecretStore { - /// new instance of Secret Store in specific directory - pub fn new_in(path: &Path) -> Self { - SecretStore::with_security(path, KEY_ITERATIONS) - } - - /// new instance of Secret Store in specific directory and configured security parameters - pub fn with_security(path: &Path, key_iterations: u32) -> Self { - ::std::fs::create_dir_all(&path).expect("Cannot access requested key directory - critical"); - SecretStore { - directory: KeyDirectory::new(path), - unlocks: RwLock::new(HashMap::new()), - key_iterations: key_iterations, - } - } - - /// trys to import keys in the known locations - pub fn try_import_existing(&mut self, is_testnet: bool) { - use keys::geth_import; - - let import_path = geth_import::keystore_dir(is_testnet); - if let Err(e) = geth_import::import_geth_keys(self, &import_path) { - trace!(target: "sstore", "Geth key not imported: {:?}", e); - } - } - - /// Lists all accounts and corresponding key ids - pub fn accounts(&self) -> Result, ::std::io::Error> { - let accounts = try!(self.directory.list()).iter().map(|key_id| self.directory.get(key_id)) - .filter(|key| key.is_some()) - .map(|key| { let some_key = key.unwrap(); (some_key.account, some_key.id) }) - .filter(|&(ref account, _)| account.is_some()) - .map(|(account, id)| (account.unwrap(), id)) - .collect::>(); - Ok(accounts) - } - - /// Resolves key_id by account address - pub fn account(&self, account: &Address) -> Option { - let mut accounts = match self.accounts() { - Ok(accounts) => accounts, - Err(e) => { warn!(target: "sstore", "Failed to load accounts: {}", e); return None; } - }; - accounts.retain(|&(ref store_account, _)| account == store_account); - accounts.first().and_then(|&(_, ref key_id)| Some(key_id.clone())) - } - - /// Imports pregenerated key, returns error if not saved correctly - pub fn import_key(&mut self, key_file: KeyFileContent) -> Result<(), ::std::io::Error> { - try!(self.directory.save(key_file)); - Ok(()) - } - - #[cfg(test)] - fn new_test(path: &::devtools::RandomTempPath) -> SecretStore { - SecretStore { - directory: KeyDirectory::new(path.as_path()), - unlocks: RwLock::new(HashMap::new()), - key_iterations: KEY_ITERATIONS, - } - } - - /// Unlocks account for use - pub fn unlock_account(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> { - self.unlock_account_with_expiration(account, pass, Some(UTC::now() + Duration::minutes(20)), false) - } - - /// Unlocks account for use (no expiration of unlock) - pub fn unlock_account_no_expire(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> { - self.unlock_account_with_expiration(account, pass, None, false) - } - - /// Unlocks account for use (no expiration of unlock) - pub fn unlock_account_temp(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> { - self.unlock_account_with_expiration(account, pass, None, true) - } - - fn unlock_account_with_expiration(&self, account: &Address, pass: &str, expiration: Option>, relock_on_use: bool) -> Result<(), EncryptedHashMapError> { - let secret_id = try!(self.account(&account).ok_or(EncryptedHashMapError::UnknownIdentifier)); - let secret = try!(self.get(&secret_id, pass)); - { - let mut write_lock = self.unlocks.write().unwrap(); - let mut unlock = write_lock.entry(*account) - .or_insert_with(|| AccountUnlock { secret: secret, expires: Some(UTC::now()), relock_on_use: relock_on_use }); - unlock.secret = secret; - unlock.expires = expiration; - } - Ok(()) - } - - /// Creates new account - pub fn new_account(&mut self, pass: &str) -> Result { - let key_pair = crypto::KeyPair::create().expect("Error creating key-pair. Something wrong with crypto libraries?"); - let address = Address::from(key_pair.public().sha3()); - let key_id = H128::random(); - self.insert(key_id.clone(), key_pair.secret().clone(), pass); - - let mut key_file = self.directory.get(&key_id).expect("the key was just inserted"); - key_file.account = Some(address); - try!(self.directory.save(key_file)); - Ok(address) - } - - /// Signs message with unlocked account. - pub fn sign(&self, account: &Address, message: &H256) -> Result { - let (relock, ret) = { - let read_lock = self.unlocks.read().unwrap(); - if let Some(unlock) = read_lock.get(account) { - (unlock.relock_on_use, match crypto::KeyPair::from_secret(unlock.secret) { - Ok(pair) => match pair.sign(message) { - Ok(signature) => Ok(signature), - Err(_) => Err(SigningError::InvalidSecret) - }, - Err(_) => Err(SigningError::InvalidSecret) - }) - } else { - (false, Err(SigningError::AccountNotUnlocked)) - } - }; - if relock { - self.unlocks.write().unwrap().remove(account); - } - ret - } - - /// Returns secret for unlocked account. - pub fn account_secret(&self, account: &Address) -> Result { - let (relock, ret) = { - let read_lock = self.unlocks.read().unwrap(); - if let Some(unlock) = read_lock.get(account) { - (unlock.relock_on_use, Ok(unlock.secret as crypto::Secret)) - } else { - (false, Err(SigningError::AccountNotUnlocked)) - } - }; - if relock { - self.unlocks.write().unwrap().remove(account); - } - ret - } - - /// Returns secret for locked account. - pub fn locked_account_secret(&self, account: &Address, pass: &str) -> Result { - let secret_id = try!(self.account(&account).ok_or(SigningError::NoAccount)); - self.get(&secret_id, pass).or_else(|e| Err(match e { - EncryptedHashMapError::InvalidPassword => SigningError::InvalidPassword, - EncryptedHashMapError::UnknownIdentifier => SigningError::NoAccount, - EncryptedHashMapError::InvalidValueFormat(_) => SigningError::InvalidSecret, - })) - } - - /// Makes account unlocks expire and removes unused key files from memory - pub fn collect_garbage(&mut self) { - let mut garbage_lock = self.unlocks.write().unwrap(); - self.directory.collect_garbage(); - let utc = UTC::now(); - let expired_addresses = garbage_lock.iter() - .filter(|&(_, unlock)| match unlock.expires { Some(ref expire_val) => expire_val < &utc, _ => false }) - .map(|(address, _)| address.clone()).collect::>(); - - for expired in expired_addresses { garbage_lock.remove(&expired); } - - garbage_lock.shrink_to_fit(); - } -} - -fn derive_key_iterations(password: &str, salt: &H256, c: u32) -> (Bytes, Bytes) { - let mut h_mac = Hmac::new(::rcrypto::sha2::Sha256::new(), password.as_bytes()); - let mut derived_key = vec![0u8; KEY_LENGTH_USIZE]; - pbkdf2(&mut h_mac, &salt.as_slice(), c, &mut derived_key); - let derived_right_bits = &derived_key[0..KEY_LENGTH_AES_USIZE]; - let derived_left_bits = &derived_key[KEY_LENGTH_AES_USIZE..KEY_LENGTH_USIZE]; - (derived_right_bits.to_vec(), derived_left_bits.to_vec()) -} - -fn derive_key(password: &str, salt: &H256, iterations: u32) -> (Bytes, Bytes) { - derive_key_iterations(password, salt, iterations) -} - -fn derive_key_scrypt(password: &str, salt: &H256, n: u32, p: u32, r: u32) -> (Bytes, Bytes) { - let mut derived_key = vec![0u8; KEY_LENGTH_USIZE]; - let scrypt_params = ScryptParams::new(n.trailing_zeros() as u8, r, p); - scrypt(password.as_bytes(), &salt.as_slice(), &scrypt_params, &mut derived_key); - let derived_right_bits = &derived_key[0..KEY_LENGTH_AES_USIZE]; - let derived_left_bits = &derived_key[KEY_LENGTH_AES_USIZE..KEY_LENGTH_USIZE]; - (derived_right_bits.to_vec(), derived_left_bits.to_vec()) -} - -fn derive_mac(derived_left_bits: &[u8], cipher_text: &[u8]) -> Bytes { - let mut mac = vec![0u8; KEY_LENGTH_AES_USIZE + cipher_text.len()]; - mac[0..KEY_LENGTH_AES_USIZE].clone_from_slice(derived_left_bits); - mac[KEY_LENGTH_AES_USIZE..cipher_text.len()+KEY_LENGTH_AES_USIZE].clone_from_slice(cipher_text); - mac -} - -impl EncryptedHashMap for SecretStore { - fn get(&self, key: &H128, password: &str) -> Result { - match self.directory.get(key) { - Some(key_file) => { - let (derived_left_bits, derived_right_bits) = match key_file.crypto.kdf { - KeyFileKdf::Pbkdf2(ref params) => derive_key_iterations(password, ¶ms.salt, params.c), - KeyFileKdf::Scrypt(ref params) => derive_key_scrypt(password, ¶ms.salt, params.n, params.p, params.r) - }; - - if derive_mac(&derived_right_bits, &key_file.crypto.cipher_text) - .sha3() != key_file.crypto.mac { return Err(EncryptedHashMapError::InvalidPassword); } - - let mut val = vec![0u8; key_file.crypto.cipher_text.len()]; - match key_file.crypto.cipher_type { - CryptoCipherType::Aes128Ctr(ref iv) => { - crypto::aes::decrypt(&derived_left_bits, &iv.as_slice(), &key_file.crypto.cipher_text, &mut val); - } - }; - - match Value::from_bytes_variable(&val) { - Ok(value) => Ok(value), - Err(bytes_error) => Err(EncryptedHashMapError::InvalidValueFormat(bytes_error)) - } - }, - None => Err(EncryptedHashMapError::UnknownIdentifier) - } - } - - fn insert(&mut self, key: H128, value: Value, password: &str) -> Option { - let previous = if let Ok(previous_value) = self.get(&key, password) { Some(previous_value) } else { None }; - - // crypto random initiators - let salt = H256::random(); - let iv = H128::random(); - - // two parts of derived key - // DK = [ DK[0..15] DK[16..31] ] = [derived_left_bits, derived_right_bits] - let (derived_left_bits, derived_right_bits) = derive_key(password, &salt, self.key_iterations); - - let mut cipher_text = vec![0u8; value.as_slice().len()]; - // aes-128-ctr with initial vector of iv - crypto::aes::encrypt(&derived_left_bits, &iv.clone(), &value.as_slice(), &mut cipher_text); - - // KECCAK(DK[16..31] ++ ), where DK[16..31] - derived_right_bits - let mac = derive_mac(&derived_right_bits, &cipher_text.clone()).sha3(); - - let mut key_file = KeyFileContent::new( - KeyFileCrypto::new_pbkdf2( - cipher_text, - iv, - salt, - mac, - self.key_iterations, - KEY_LENGTH)); - key_file.id = key; - if let Err(io_error) = self.directory.save(key_file) { - warn!("Error saving key file: {:?}", io_error); - } - previous - } - - fn remove(&mut self, key: &H128, password: Option<&str>) -> Option { - let previous = if let Some(pass) = password { - if let Ok(previous_value) = self.get(&key, pass) { Some(previous_value) } else { None } - } - else { None }; - - if let Err(io_error) = self.directory.delete(key) { - warn!("Error saving key file: {:?}", io_error); - } - previous - } - -} - -#[cfg(all(test, feature="heavy-tests"))] -mod vector_tests { - use super::{derive_mac,derive_key_iterations}; - use common::*; - - #[test] - fn mac_vector() { - let password = "testpassword"; - let salt = H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap(); - let cipher_text = FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap(); - let iterations = 262144u32; - - let (derived_left_bits, derived_right_bits) = derive_key_iterations(password, &salt, iterations); - assert_eq!("f06d69cdc7da0faffb1008270bca38f5", derived_left_bits.to_hex()); - assert_eq!("e31891a3a773950e6d0fea48a7188551", derived_right_bits.to_hex()); - - let mac_body = derive_mac(&derived_right_bits, &cipher_text); - assert_eq!("e31891a3a773950e6d0fea48a71885515318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46", mac_body.to_hex()); - - let mac = mac_body.sha3(); - assert_eq!("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2", format!("{:?}", mac)); - } -} - - -#[cfg(test)] -mod tests { - use super::*; - use devtools::*; - use common::*; - use crypto::KeyPair; - use chrono::*; - - #[test] - fn can_insert() { - let temp = RandomTempPath::create_dir(); - let mut sstore = SecretStore::new_test(&temp); - - let id = H128::random(); - sstore.insert(id.clone(), "Cat".to_owned(), "pass"); - - assert!(sstore.get::(&id, "pass").is_ok()); - } - - #[test] - fn can_get_fail() { - let temp = RandomTempPath::create_dir(); - { - use keys::directory::{KeyFileContent, KeyFileCrypto}; - let mut write_sstore = SecretStore::new_test(&temp); - write_sstore.directory.save( - KeyFileContent::new( - KeyFileCrypto::new_pbkdf2( - FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap(), - H128::from_str("6087dab2f9fdbbfaddc31a909735c1e6").unwrap(), - H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap(), - H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(), - 262144, - 32))) - .unwrap(); - } - let sstore = SecretStore::new_test(&temp); - if let Ok(_) = sstore.get::(&H128::from_str("3198bc9c66725ab3d9954942343ae5b6").unwrap(), "testpassword") { - panic!("should be error loading key, we requested the wrong key"); - } - } - - fn pregenerate_keys(temp: &RandomTempPath, count: usize) -> Vec { - use keys::directory::{KeyFileContent, KeyFileCrypto}; - let mut write_sstore = SecretStore::new_test(&temp); - let mut result = Vec::new(); - for _ in 0..count { - result.push(write_sstore.directory.save( - KeyFileContent::new( - KeyFileCrypto::new_pbkdf2( - FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap(), - H128::from_str("6087dab2f9fdbbfaddc31a909735c1e6").unwrap(), - H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap(), - H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(), - 262144, - 32))) - .unwrap()); - } - result - } - - fn pregenerate_accounts(temp: &RandomTempPath, count: usize) -> Vec { - use keys::directory::{KeyFileContent, KeyFileCrypto}; - let mut write_sstore = SecretStore::new_test(&temp); - let mut result = Vec::new(); - for i in 0..count { - let mut key_file = - KeyFileContent::new( - KeyFileCrypto::new_pbkdf2( - FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap(), - H128::from_str("6087dab2f9fdbbfaddc31a909735c1e6").unwrap(), - H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap(), - H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(), - 262144, - 32)); - key_file.account = Some((i as u64).into()); - result.push(key_file.id.clone()); - write_sstore.import_key(key_file).unwrap(); - } - result - } - - #[test] - #[cfg(feature="heavy-tests")] - fn can_get() { - let temp = RandomTempPath::create_dir(); - let key_id = { - use keys::directory::{KeyFileContent, KeyFileCrypto}; - let mut write_sstore = SecretStore::new_test(&temp); - write_sstore.directory.save( - KeyFileContent::new( - KeyFileCrypto::new_pbkdf2( - FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap(), - H128::from_str("6087dab2f9fdbbfaddc31a909735c1e6").unwrap(), - H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap(), - H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(), - 262144, - 32))) - .unwrap() - }; - let sstore = SecretStore::new_test(&temp); - if let Err(e) = sstore.get::(&key_id, "testpassword") { - panic!("got no key: {:?}", e); - } - } - - #[test] - fn can_delete() { - let temp = RandomTempPath::create_dir(); - let keys = pregenerate_keys(&temp, 5); - - let mut sstore = SecretStore::new_test(&temp); - sstore.delete(&keys[2]); - - assert_eq!(4, sstore.directory.list().unwrap().len()) - } - - #[test] - fn can_create_account() { - let temp = RandomTempPath::create_dir(); - let mut sstore = SecretStore::new_test(&temp); - sstore.new_account("123").unwrap(); - assert_eq!(1, sstore.accounts().unwrap().len()); - } - - #[test] - fn can_unlock_account() { - let temp = RandomTempPath::create_dir(); - let mut sstore = SecretStore::new_test(&temp); - let address = sstore.new_account("123").unwrap(); - - let secret = sstore.unlock_account(&address, "123"); - assert!(secret.is_ok()); - } - - #[test] - fn can_sign_data() { - let temp = RandomTempPath::create_dir(); - let address = { - let mut sstore = SecretStore::new_test(&temp); - sstore.new_account("334").unwrap() - }; - let signature = { - let sstore = SecretStore::new_test(&temp); - sstore.unlock_account(&address, "334").unwrap(); - sstore.sign(&address, &H256::random()).unwrap() - }; - - assert!(signature != 0.into()); - } - - #[test] - fn can_relock_temp_account() { - let temp = RandomTempPath::create_dir(); - let address = { - let mut sstore = SecretStore::new_test(&temp); - sstore.new_account("334").unwrap() - }; - let signature = { - let sstore = SecretStore::new_test(&temp); - sstore.unlock_account_temp(&address, "334").unwrap(); - sstore.sign(&address, &H256::random()).unwrap(); - sstore.sign(&address, &H256::random()) - }; - assert!(signature.is_err()); - - let secret = { - let sstore = SecretStore::new_test(&temp); - sstore.unlock_account_temp(&address, "334").unwrap(); - sstore.account_secret(&address).unwrap(); - sstore.account_secret(&address) - }; - assert!(secret.is_err()); - } - - #[test] - fn can_import_account() { - use keys::directory::{KeyFileContent, KeyFileCrypto}; - let temp = RandomTempPath::create_dir(); - let mut key_file = - KeyFileContent::new( - KeyFileCrypto::new_pbkdf2( - FromHex::from_hex("5318b4d5bcd28de64ee5559e671353e16f075ecae9f99c7a79a38af5f869aa46").unwrap(), - H128::from_str("6087dab2f9fdbbfaddc31a909735c1e6").unwrap(), - H256::from_str("ae3cd4e7013836a3df6bd7241b12db061dbe2c6785853cce422d148a624ce0bd").unwrap(), - H256::from_str("517ead924a9d0dc3124507e3393d175ce3ff7c1e96529c6c555ce9e51205e9b2").unwrap(), - 262144, - 32)); - key_file.account = Some(Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap()); - - let mut sstore = SecretStore::new_test(&temp); - - sstore.import_key(key_file).unwrap(); - - assert_eq!(1, sstore.accounts().unwrap().len()); - assert!(sstore.account(&Address::from_str("3f49624084b67849c7b4e805c5988c21a430f9d9").unwrap()).is_some()); - } - - #[test] - fn can_list_accounts() { - let temp = RandomTempPath::create_dir(); - pregenerate_accounts(&temp, 30); - let sstore = SecretStore::new_test(&temp); - let accounts = sstore.accounts().unwrap(); - assert_eq!(30, accounts.len()); - } - - #[test] - fn validate_generated_addresses() { - let temp = RandomTempPath::create_dir(); - let mut sstore = SecretStore::new_test(&temp); - let addr = sstore.new_account("test").unwrap(); - sstore.unlock_account(&addr, "test").unwrap(); - let secret = sstore.account_secret(&addr).unwrap(); - let kp = KeyPair::from_secret(secret).unwrap(); - assert_eq!(Address::from(kp.public().sha3()), addr); - } - - - #[test] - fn secret_for_locked_account() { - // given - let temp = RandomTempPath::create_dir(); - let mut sstore = SecretStore::new_test(&temp); - let addr = sstore.new_account("test-pass").unwrap(); - - // when - // Invalid pass - let secret1 = sstore.locked_account_secret(&addr, "test-pass123"); - // Valid pass - let secret2 = sstore.locked_account_secret(&addr, "test-pass"); - // Account not unlocked - let secret3 = sstore.account_secret(&addr); - - - assert!(secret1.is_err(), "Invalid password should not return secret."); - assert!(secret2.is_ok(), "Should return secret provided valid passphrase."); - assert!(secret3.is_err(), "Account should still be locked."); - } - - - #[test] - fn can_create_service() { - let temp = RandomTempPath::create_dir(); - let svc = AccountService::new_test(&temp); - assert!(svc.accounts().unwrap().is_empty()); - } - - #[test] - fn accounts_expire() { - use std::collections::hash_map::*; - - let temp = RandomTempPath::create_dir(); - let svc = AccountService::new_test(&temp); - let address = svc.new_account("pass").unwrap(); - svc.unlock_account(&address, "pass").unwrap(); - assert!(svc.account_secret(&address).is_ok()); - { - let ss_rw = svc.secret_store.write().unwrap(); - let mut ua_rw = ss_rw.unlocks.write().unwrap(); - let entry = ua_rw.entry(address); - if let Entry::Occupied(mut occupied) = entry { occupied.get_mut().expires = Some(UTC::now() - Duration::minutes(1)) } - } - - svc.tick(); - - assert!(svc.account_secret(&address).is_err()); - } -} diff --git a/util/src/keys/test_account_provider.rs b/util/src/keys/test_account_provider.rs deleted file mode 100644 index 148996172..000000000 --- a/util/src/keys/test_account_provider.rs +++ /dev/null @@ -1,118 +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 . - -//! Test implementation of account provider. - -use std::sync::RwLock; -use std::collections::HashMap; -use std::io; -use hash::Address; -use crypto::{Secret, KeyPair}; -use super::store::{AccountProvider, SigningError, EncryptedHashMapError}; - -/// Account mock. -#[derive(Clone)] -pub struct TestAccount { - /// True if account is unlocked. - pub unlocked: bool, - /// Account's password. - pub password: String, - /// Account's secret. - pub secret: Secret, -} - -impl TestAccount { - /// Creates new test account. - pub fn new(password: &str) -> Self { - let pair = KeyPair::create().unwrap(); - TestAccount { - unlocked: false, - password: password.to_owned(), - secret: pair.secret().clone() - } - } - - /// Returns account address. - pub fn address(&self) -> Address { - KeyPair::from_secret(self.secret.clone()).unwrap().address() - } -} - -/// Test account provider. -pub struct TestAccountProvider { - /// Test provider accounts. - pub accounts: RwLock>, -} - -impl TestAccountProvider { - /// Basic constructor. - pub fn new(accounts: HashMap) -> Self { - TestAccountProvider { - accounts: RwLock::new(accounts), - } - } -} - -impl AccountProvider for TestAccountProvider { - fn accounts(&self) -> Result, io::Error> { - Ok(self.accounts.read().unwrap().keys().cloned().collect()) - } - - fn unlock_account(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> { - match self.accounts.write().unwrap().get_mut(account) { - Some(ref mut acc) if acc.password == pass => { - acc.unlocked = true; - Ok(()) - }, - Some(_) => Err(EncryptedHashMapError::InvalidPassword), - None => Err(EncryptedHashMapError::UnknownIdentifier), - } - } - - fn unlock_account_temp(&self, account: &Address, pass: &str) -> Result<(), EncryptedHashMapError> { - // TODO; actually make it relock on use - self.unlock_account(account, pass) - } - - fn new_account(&self, pass: &str) -> Result { - let account = TestAccount::new(pass); - let address = KeyPair::from_secret(account.secret.clone()).unwrap().address(); - self.accounts.write().unwrap().insert(address.clone(), account); - Ok(address) - } - - fn account_secret(&self, address: &Address) -> Result { - // todo: consider checking if account is unlock. some test may need alteration then. - self.accounts - .read() - .unwrap() - .get(address) - .ok_or(SigningError::NoAccount) - .map(|acc| acc.secret.clone()) - } - - fn locked_account_secret(&self, address: &Address, pass: &str) -> Result { - let accounts = self.accounts.read().unwrap(); - match accounts.get(address) { - Some(ref acc) if acc.password == pass => { - Ok(acc.secret.clone()) - }, - Some(ref _acc) => Err(SigningError::InvalidPassword), - _ => Err(SigningError::NoAccount), - } - } -} - diff --git a/util/src/kvdb.rs b/util/src/kvdb.rs index 40b7ef090..aeb8b9fa7 100644 --- a/util/src/kvdb.rs +++ b/util/src/kvdb.rs @@ -20,6 +20,9 @@ use std::default::Default; use rocksdb::{DB, Writable, WriteBatch, IteratorMode, DBVector, DBIterator, IndexType, Options, DBCompactionStyle, BlockBasedOptions, Direction}; +const DB_BACKGROUND_FLUSHES: i32 = 2; +const DB_BACKGROUND_COMPACTIONS: i32 = 2; + /// Write transaction. Batches a sequence of put/delete operations for efficiency. pub struct DBTransaction { batch: WriteBatch, @@ -48,12 +51,81 @@ impl DBTransaction { } } +/// Compaction profile for the database settings +pub struct CompactionProfile { + /// L0-L1 target file size + pub initial_file_size: u64, + /// L2-LN target file size multiplier + pub file_size_multiplier: i32, + /// rate limiter for background flushes and compactions, bytes/sec, if any + pub write_rate_limit: Option, +} + +impl CompactionProfile { + /// Default profile suitable for most storage + pub fn default() -> CompactionProfile { + CompactionProfile { + initial_file_size: 32 * 1024 * 1024, + file_size_multiplier: 2, + write_rate_limit: None, + } + } + + /// Slow hdd compaction profile + pub fn hdd() -> CompactionProfile { + CompactionProfile { + initial_file_size: 192 * 1024 * 1024, + file_size_multiplier: 1, + write_rate_limit: Some(8 * 1024 * 1024), + } + } +} + /// Database configuration pub struct DatabaseConfig { /// Optional prefix size in bytes. Allows lookup by partial key. pub prefix_size: Option, /// Max number of open files. pub max_open_files: i32, + /// Cache-size + pub cache_size: Option, + /// Compaction profile + pub compaction: CompactionProfile, +} + +impl DatabaseConfig { + /// Database with default settings and specified cache size + pub fn with_cache(cache_size: usize) -> DatabaseConfig { + DatabaseConfig { + cache_size: Some(cache_size), + prefix_size: None, + max_open_files: -1, + compaction: CompactionProfile::default(), + } + } + + /// Modify the compaction profile + pub fn compaction(mut self, profile: CompactionProfile) -> Self { + self.compaction = profile; + self + } + + /// Modify the prefix of the db + pub fn prefix(mut self, prefix_size: usize) -> Self { + self.prefix_size = Some(prefix_size); + self + } +} + +impl Default for DatabaseConfig { + fn default() -> DatabaseConfig { + DatabaseConfig { + cache_size: None, + prefix_size: None, + max_open_files: -1, + compaction: CompactionProfile::default(), + } + } } /// Database iterator @@ -77,16 +149,32 @@ pub struct Database { impl Database { /// Open database with default settings. pub fn open_default(path: &str) -> Result { - Database::open(&DatabaseConfig { prefix_size: None, max_open_files: 256 }, path) + Database::open(&DatabaseConfig::default(), path) } /// Open database file. Creates if it does not exist. pub fn open(config: &DatabaseConfig, path: &str) -> Result { let mut opts = Options::new(); + if let Some(rate_limit) = config.compaction.write_rate_limit { + try!(opts.set_parsed_options(&format!("rate_limiter_bytes_per_sec={}", rate_limit))); + } opts.set_max_open_files(config.max_open_files); opts.create_if_missing(true); opts.set_use_fsync(false); + + // compaction settings opts.set_compaction_style(DBCompactionStyle::DBUniversalCompaction); + opts.set_target_file_size_base(config.compaction.initial_file_size); + opts.set_target_file_size_multiplier(config.compaction.file_size_multiplier); + + opts.set_max_background_flushes(DB_BACKGROUND_FLUSHES); + opts.set_max_background_compactions(DB_BACKGROUND_COMPACTIONS); + if let Some(cache_size) = config.cache_size { + // half goes to read cache + opts.set_block_cache_size_mb(cache_size as u64 / 2); + // quarter goes to each of the two write buffers + opts.set_write_buffer_size(cache_size * 1024 * 256); + } /* opts.set_bytes_per_sync(8388608); opts.set_disable_data_sync(false); @@ -111,7 +199,16 @@ impl Database { opts.set_block_based_table_factory(&block_opts); opts.set_prefix_extractor_fixed_size(size); } - let db = try!(DB::open(&opts, path)); + let db = match DB::open(&opts, path) { + Ok(db) => db, + Err(ref s) if s.starts_with("Corruption:") => { + info!("{}", s); + info!("Attempting DB repair for {}", path); + try!(DB::repair(&opts, path)); + try!(DB::open(&opts, path)) + }, + Err(s) => { return Err(s); } + }; Ok(Database { db: db }) } @@ -205,10 +302,10 @@ mod tests { let path = RandomTempPath::create_dir(); let smoke = Database::open_default(path.as_path().to_str().unwrap()).unwrap(); assert!(smoke.is_empty()); - test_db(&DatabaseConfig { prefix_size: None, max_open_files: 256 }); - test_db(&DatabaseConfig { prefix_size: Some(1), max_open_files: 256 }); - test_db(&DatabaseConfig { prefix_size: Some(8), max_open_files: 256 }); - test_db(&DatabaseConfig { prefix_size: Some(32), max_open_files: 256 }); + test_db(&DatabaseConfig::default()); + test_db(&DatabaseConfig::default().prefix(12)); + test_db(&DatabaseConfig::default().prefix(22)); + test_db(&DatabaseConfig::default().prefix(8)); } } diff --git a/util/src/lib.rs b/util/src/lib.rs index 255dd8a97..afd6255fd 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -151,11 +151,11 @@ pub mod io; pub mod network; pub mod log; pub mod panics; -pub mod keys; pub mod table; pub mod network_settings; pub mod path; pub mod snappy; +mod timer; pub use common::*; pub use misc::*; @@ -177,6 +177,7 @@ pub use network::*; pub use io::*; pub use log::*; pub use kvdb::*; +pub use timer::*; #[cfg(test)] mod tests { diff --git a/util/src/memorydb.rs b/util/src/memorydb.rs index cfd7237e6..ea77f4aa2 100644 --- a/util/src/memorydb.rs +++ b/util/src/memorydb.rs @@ -162,7 +162,7 @@ impl MemoryDB { static NULL_RLP_STATIC: [u8; 1] = [0x80; 1]; impl HashDB for MemoryDB { - fn lookup(&self, key: &H256) -> Option<&[u8]> { + fn get(&self, key: &H256) -> Option<&[u8]> { if key == &SHA3_NULL_RLP { return Some(&NULL_RLP_STATIC); } @@ -176,7 +176,7 @@ impl HashDB for MemoryDB { self.data.iter().filter_map(|(k, v)| if v.1 != 0 {Some((k.clone(), v.1))} else {None}).collect() } - fn exists(&self, key: &H256) -> bool { + fn contains(&self, key: &H256) -> bool { if key == &SHA3_NULL_RLP { return true; } @@ -222,7 +222,7 @@ impl HashDB for MemoryDB { self.data.insert(key, (value, 1)); } - fn kill(&mut self, key: &H256) { + fn remove(&mut self, key: &H256) { if key == &SHA3_NULL_RLP { return; } diff --git a/util/src/network/connection.rs b/util/src/network/connection.rs index 3f20b8f7b..9ee045c87 100644 --- a/util/src/network/connection.rs +++ b/util/src/network/connection.rs @@ -17,6 +17,7 @@ use std::sync::Arc; use std::collections::VecDeque; use std::net::SocketAddr; +use std::sync::atomic::{AtomicBool, Ordering as AtomicOrdering}; use mio::{Handler, Token, EventSet, EventLoop, PollOpt, TryRead, TryWrite}; use mio::tcp::*; use hash::*; @@ -60,45 +61,57 @@ pub struct GenericConnection { interest: EventSet, /// Shared network statistics stats: Arc, + /// Registered flag + registered: AtomicBool, } impl GenericConnection { pub fn expect(&mut self, size: usize) { + trace!(target:"network", "Expect to read {} bytes", size); if self.rec_size != self.rec_buf.len() { - warn!(target:"net", "Unexpected connection read start"); + warn!(target:"network", "Unexpected connection read start"); } - unsafe { self.rec_buf.set_len(0) } self.rec_size = size; } /// Readable IO handler. Called when there is some data to be read. pub fn readable(&mut self) -> io::Result> { if self.rec_size == 0 || self.rec_buf.len() >= self.rec_size { - warn!(target:"net", "Unexpected connection read"); + warn!(target:"network", "Unexpected connection read"); } - let max = self.rec_size - self.rec_buf.len(); - // resolve "multiple applicable items in scope [E0034]" error let sock_ref = ::by_ref(&mut self.socket); - match sock_ref.take(max as u64).try_read_buf(&mut self.rec_buf) { - Ok(Some(size)) if size != 0 => { - self.stats.inc_recv(size); - if self.rec_size != 0 && self.rec_buf.len() == self.rec_size { - self.rec_size = 0; - Ok(Some(::std::mem::replace(&mut self.rec_buf, Bytes::new()))) - } else { Ok(None) } - }, - Ok(_) => Ok(None), - Err(e) => Err(e), - } - } + loop { + let max = self.rec_size - self.rec_buf.len(); + match sock_ref.take(max as u64).try_read_buf(&mut self.rec_buf) { + Ok(Some(size)) if size != 0 => { + self.stats.inc_recv(size); + trace!(target:"network", "{}: Read {} of {} bytes", self.token, self.rec_buf.len(), self.rec_size); + if self.rec_size != 0 && self.rec_buf.len() == self.rec_size { + self.rec_size = 0; + return Ok(Some(::std::mem::replace(&mut self.rec_buf, Bytes::new()))) + } + else if self.rec_buf.len() > self.rec_size { + warn!(target:"network", "Read past buffer {} bytes", self.rec_buf.len() - self.rec_size); + return Ok(Some(::std::mem::replace(&mut self.rec_buf, Bytes::new()))) + } + }, + Ok(_) => return Ok(None), + Err(e) => { + debug!(target:"network", "Read error {} ({})", self.token, e); + return Err(e) + } + } + } + } /// Add a packet to send queue. - pub fn send(&mut self, data: Bytes) { + pub fn send(&mut self, io: &IoContext, data: Bytes) where Message: Send + Clone { if !data.is_empty() { self.send_queue.push_back(Cursor::new(data)); } if !self.interest.is_writable() { self.interest.insert(EventSet::writable()); + io.update_registration(self.token).ok(); } } @@ -108,7 +121,7 @@ impl GenericConnection { } /// Writable IO handler. Called when the socket is ready to send. - pub fn writable(&mut self) -> io::Result { + pub fn writable(&mut self, io: &IoContext) -> Result where Message: Send + Clone { if self.send_queue.is_empty() { return Ok(WriteStatus::Complete) } @@ -121,17 +134,17 @@ impl GenericConnection { } match self.socket.try_write_buf(buf) { Ok(Some(size)) if (buf.position() as usize) < send_size => { - self.interest.insert(EventSet::writable()); self.stats.inc_send(size); Ok(WriteStatus::Ongoing) }, Ok(Some(size)) if (buf.position() as usize) == send_size => { self.stats.inc_send(size); + trace!(target:"network", "{}: Wrote {} bytes", self.token, send_size); Ok(WriteStatus::Complete) }, Ok(Some(_)) => { panic!("Wrote past buffer");}, Ok(None) => Ok(WriteStatus::Ongoing), - Err(e) => Err(e) + Err(e) => try!(Err(e)) } }.and_then(|r| { if r == WriteStatus::Complete { @@ -139,9 +152,7 @@ impl GenericConnection { } if self.send_queue.is_empty() { self.interest.remove(EventSet::writable()); - } - else { - self.interest.insert(EventSet::writable()); + try!(io.update_registration(self.token)); } Ok(r) }) @@ -162,6 +173,7 @@ impl Connection { rec_size: 0, interest: EventSet::hup() | EventSet::readable(), stats: stats, + registered: AtomicBool::new(false), } } @@ -188,27 +200,36 @@ impl Connection { rec_buf: Vec::new(), rec_size: 0, send_queue: self.send_queue.clone(), - interest: EventSet::hup() | EventSet::readable(), + interest: EventSet::hup(), stats: self.stats.clone(), + registered: AtomicBool::new(false), }) } /// Register this connection with the IO event loop. pub fn register_socket(&self, reg: Token, event_loop: &mut EventLoop) -> io::Result<()> { + if self.registered.load(AtomicOrdering::SeqCst) { + return Ok(()); + } trace!(target: "network", "connection register; token={:?}", reg); if let Err(e) = event_loop.register(&self.socket, reg, self.interest, PollOpt::edge() /* | PollOpt::oneshot() */) { // TODO: oneshot is broken on windows trace!(target: "network", "Failed to register {:?}, {:?}", reg, e); } + self.registered.store(true, AtomicOrdering::SeqCst); Ok(()) } /// Update connection registration. Should be called at the end of the IO handler. pub fn update_socket(&self, reg: Token, event_loop: &mut EventLoop) -> io::Result<()> { trace!(target: "network", "connection reregister; token={:?}", reg); - event_loop.reregister( &self.socket, reg, self.interest, PollOpt::edge() /* | PollOpt::oneshot() */ ).or_else(|e| { // TODO: oneshot is broken on windows - trace!(target: "network", "Failed to reregister {:?}, {:?}", reg, e); + if !self.registered.load(AtomicOrdering::SeqCst) { + self.register_socket(reg, event_loop) + } else { + event_loop.reregister(&self.socket, reg, self.interest, PollOpt::edge() /* | PollOpt::oneshot() */ ).unwrap_or_else(|e| { // TODO: oneshot is broken on windows + trace!(target: "network", "Failed to reregister {:?}, {:?}", reg, e); + }); Ok(()) - }) + } } /// Delete connection registration. Should be called at the end of the IO handler. @@ -266,7 +287,7 @@ pub struct EncryptedConnection { } impl EncryptedConnection { - /// Create an encrypted connection out of the handshake. Consumes a handshake object. + /// Create an encrypted connection out of the handshake. pub fn new(handshake: &mut Handshake) -> Result { let shared = try!(crypto::ecdh::agree(handshake.ecdhe.secret(), &handshake.remote_ephemeral)); let mut nonce_material = H512::new(); @@ -320,7 +341,7 @@ impl EncryptedConnection { } /// Send a packet - pub fn send_packet(&mut self, payload: &[u8]) -> Result<(), UtilError> { + pub fn send_packet(&mut self, io: &IoContext, payload: &[u8]) -> Result<(), UtilError> where Message: Send + Clone { let mut header = RlpStream::new(); let len = payload.len() as usize; header.append_raw(&[(len >> 16) as u8, (len >> 8) as u8, len as u8], 1); @@ -342,7 +363,7 @@ impl EncryptedConnection { self.egress_mac.update(&packet[32..(32 + len + padding)]); EncryptedConnection::update_mac(&mut self.egress_mac, &mut self.mac_encoder, &[0u8; 0]); self.egress_mac.clone().finalize(&mut packet[(32 + len + padding)..]); - self.connection.send(packet); + self.connection.send(io, packet); Ok(()) } @@ -416,32 +437,30 @@ impl EncryptedConnection { /// Readable IO handler. Tracker receive status and returns decoded packet if avaialable. pub fn readable(&mut self, io: &IoContext) -> Result, UtilError> where Message: Send + Clone{ - io.clear_timer(self.connection.token).unwrap(); - match self.read_state { - EncryptedConnectionState::Header => { - if let Some(data) = try!(self.connection.readable()) { - try!(self.read_header(&data)); - try!(io.register_timer(self.connection.token, RECIEVE_PAYLOAD_TIMEOUT)); - } - Ok(None) - }, - EncryptedConnectionState::Payload => { - match try!(self.connection.readable()) { - Some(data) => { - self.read_state = EncryptedConnectionState::Header; - self.connection.expect(ENCRYPTED_HEADER_LEN); - Ok(Some(try!(self.read_payload(&data)))) - }, - None => Ok(None) - } + try!(io.clear_timer(self.connection.token)); + if let EncryptedConnectionState::Header = self.read_state { + if let Some(data) = try!(self.connection.readable()) { + try!(self.read_header(&data)); + try!(io.register_timer(self.connection.token, RECIEVE_PAYLOAD_TIMEOUT)); } + }; + if let EncryptedConnectionState::Payload = self.read_state { + match try!(self.connection.readable()) { + Some(data) => { + self.read_state = EncryptedConnectionState::Header; + self.connection.expect(ENCRYPTED_HEADER_LEN); + Ok(Some(try!(self.read_payload(&data)))) + }, + None => Ok(None) + } + } else { + Ok(None) } } /// Writable IO handler. Processes send queeue. pub fn writable(&mut self, io: &IoContext) -> Result<(), UtilError> where Message: Send + Clone { - io.clear_timer(self.connection.token).unwrap(); - try!(self.connection.writable()); + try!(self.connection.writable(io)); Ok(()) } } @@ -472,12 +491,14 @@ pub fn test_encryption() { mod tests { use super::*; use std::sync::*; + use std::sync::atomic::AtomicBool; use super::super::stats::*; use std::io::{Read, Write, Error, Cursor, ErrorKind}; use mio::{EventSet}; use std::collections::VecDeque; use bytes::*; use devtools::*; + use io::*; impl GenericSocket for TestSocket {} @@ -521,6 +542,7 @@ mod tests { rec_size: 0, interest: EventSet::hup() | EventSet::readable(), stats: Arc::::new(NetworkStats::new()), + registered: AtomicBool::new(false), } } } @@ -543,10 +565,15 @@ mod tests { rec_size: 0, interest: EventSet::hup() | EventSet::readable(), stats: Arc::::new(NetworkStats::new()), + registered: AtomicBool::new(false), } } } + fn test_io() -> IoContext { + IoContext::new(IoChannel::disconnected(), 0) + } + #[test] fn connection_expect() { let mut connection = TestConnection::new(); @@ -557,7 +584,7 @@ mod tests { #[test] fn connection_write_empty() { let mut connection = TestConnection::new(); - let status = connection.writable(); + let status = connection.writable(&test_io()); assert!(status.is_ok()); assert!(WriteStatus::Complete == status.unwrap()); } @@ -568,7 +595,7 @@ mod tests { let data = Cursor::new(vec![0; 10240]); connection.send_queue.push_back(data); - let status = connection.writable(); + let status = connection.writable(&test_io()); assert!(status.is_ok()); assert!(WriteStatus::Complete == status.unwrap()); assert_eq!(10240, connection.socket.write_buffer.len()); @@ -581,7 +608,7 @@ mod tests { let data = Cursor::new(vec![0; 10240]); connection.send_queue.push_back(data); - let status = connection.writable(); + let status = connection.writable(&test_io()); assert!(status.is_ok()); assert!(WriteStatus::Ongoing == status.unwrap()); @@ -594,7 +621,7 @@ mod tests { let data = Cursor::new(vec![0; 10240]); connection.send_queue.push_back(data); - let status = connection.writable(); + let status = connection.writable(&test_io()); assert!(!status.is_ok()); assert_eq!(1, connection.send_queue.len()); diff --git a/util/src/network/discovery.rs b/util/src/network/discovery.rs index b67110538..d4f895702 100644 --- a/util/src/network/discovery.rs +++ b/util/src/network/discovery.rs @@ -28,7 +28,7 @@ use crypto::*; use rlp::*; use network::node_table::*; use network::error::NetworkError; -use io::StreamToken; +use io::{StreamToken, IoContext}; use network::PROTOCOL_VERSION; @@ -283,7 +283,7 @@ impl Discovery { ret } - pub fn writable(&mut self) { + pub fn writable(&mut self, io: &IoContext) where Message: Send + Sync + Clone { while !self.send_queue.is_empty() { let data = self.send_queue.pop_front().unwrap(); match self.udp_socket.send_to(&data.payload, &data.address) { @@ -302,15 +302,17 @@ impl Discovery { } } } + io.update_registration(self.token).unwrap_or_else(|e| debug!("Error updating discovery registration: {:?}", e)); } fn send_to(&mut self, payload: Bytes, address: SocketAddr) { self.send_queue.push_back(Datagramm { payload: payload, address: address }); } - pub fn readable(&mut self) -> Option { + pub fn readable(&mut self, io: &IoContext) -> Option where Message: Send + Sync + Clone { let mut buf: [u8; MAX_DATAGRAM_SIZE] = unsafe { mem::uninitialized() }; - match self.udp_socket.recv_from(&mut buf) { + let writable = !self.send_queue.is_empty(); + let res = match self.udp_socket.recv_from(&mut buf) { Ok(Some((len, address))) => self.on_packet(&buf[0..len], address).unwrap_or_else(|e| { debug!("Error processing UDP packet: {:?}", e); None @@ -320,7 +322,12 @@ impl Discovery { debug!("Error reading UPD socket: {:?}", e); None } + }; + let new_writable = !self.send_queue.is_empty(); + if writable != new_writable { + io.update_registration(self.token).unwrap_or_else(|e| debug!("Error updating discovery registration: {:?}", e)); } + res } fn on_packet(&mut self, packet: &[u8], from: SocketAddr) -> Result, NetworkError> { diff --git a/util/src/network/handshake.rs b/util/src/network/handshake.rs index e02da3d4c..179309a6f 100644 --- a/util/src/network/handshake.rs +++ b/util/src/network/handshake.rs @@ -111,7 +111,7 @@ impl Handshake { self.originated = originated; io.register_timer(self.connection.token, HANDSHAKE_TIMEOUT).ok(); if originated { - try!(self.write_auth(host.secret(), host.id())); + try!(self.write_auth(io, host.secret(), host.id())); } else { self.state = HandshakeState::ReadingAuth; @@ -128,17 +128,16 @@ impl Handshake { /// Readable IO handler. Drives the state change. pub fn readable(&mut self, io: &IoContext, host: &HostInfo) -> Result<(), UtilError> where Message: Send + Clone { if !self.expired() { - io.clear_timer(self.connection.token).unwrap(); match self.state { HandshakeState::New => {} HandshakeState::ReadingAuth => { if let Some(data) = try!(self.connection.readable()) { - try!(self.read_auth(host.secret(), &data)); + try!(self.read_auth(io, host.secret(), &data)); }; }, HandshakeState::ReadingAuthEip8 => { if let Some(data) = try!(self.connection.readable()) { - try!(self.read_auth_eip8(host.secret(), &data)); + try!(self.read_auth_eip8(io, host.secret(), &data)); }; }, HandshakeState::ReadingAck => { @@ -151,10 +150,9 @@ impl Handshake { try!(self.read_ack_eip8(host.secret(), &data)); }; }, - HandshakeState::StartSession => {}, - } - if self.state != HandshakeState::StartSession { - try!(io.update_registration(self.connection.token)); + HandshakeState::StartSession => { + io.clear_timer(self.connection.token).ok(); + }, } } Ok(()) @@ -163,11 +161,7 @@ impl Handshake { /// Writabe IO handler. pub fn writable(&mut self, io: &IoContext) -> Result<(), UtilError> where Message: Send + Clone { if !self.expired() { - io.clear_timer(self.connection.token).unwrap(); - try!(self.connection.writable()); - if self.state != HandshakeState::StartSession { - io.update_registration(self.connection.token).unwrap(); - } + try!(self.connection.writable(io)); } Ok(()) } @@ -183,7 +177,7 @@ impl Handshake { } /// Parse, validate and confirm auth message - fn read_auth(&mut self, secret: &Secret, data: &[u8]) -> Result<(), UtilError> { + fn read_auth(&mut self, io: &IoContext, secret: &Secret, data: &[u8]) -> Result<(), UtilError> where Message: Send + Clone { trace!(target:"network", "Received handshake auth from {:?}", self.connection.remote_addr_str()); if data.len() != V4_AUTH_PACKET_SIZE { debug!(target:"net", "Wrong auth packet size"); @@ -197,7 +191,7 @@ impl Handshake { let (pubk, rest) = rest.split_at(64); let (nonce, _) = rest.split_at(32); try!(self.set_auth(secret, sig, pubk, nonce, PROTOCOL_VERSION)); - try!(self.write_ack()); + try!(self.write_ack(io)); } Err(_) => { // Try to interpret as EIP-8 packet @@ -214,7 +208,7 @@ impl Handshake { Ok(()) } - fn read_auth_eip8(&mut self, secret: &Secret, data: &[u8]) -> Result<(), UtilError> { + fn read_auth_eip8(&mut self, io: &IoContext, secret: &Secret, data: &[u8]) -> Result<(), UtilError> where Message: Send + Clone { trace!(target:"network", "Received EIP8 handshake auth from {:?}", self.connection.remote_addr_str()); self.auth_cipher.extend_from_slice(data); let auth = try!(ecies::decrypt(secret, &self.auth_cipher[0..2], &self.auth_cipher[2..])); @@ -224,13 +218,13 @@ impl Handshake { let remote_nonce: H256 = try!(rlp.val_at(2)); let remote_version: u64 = try!(rlp.val_at(3)); try!(self.set_auth(secret, &signature, &remote_public, &remote_nonce, remote_version)); - try!(self.write_ack_eip8()); + try!(self.write_ack_eip8(io)); Ok(()) } /// Parse and validate ack message fn read_ack(&mut self, secret: &Secret, data: &[u8]) -> Result<(), UtilError> { - trace!(target:"network", "Received handshake auth to {:?}", self.connection.remote_addr_str()); + trace!(target:"network", "Received handshake ack from {:?}", self.connection.remote_addr_str()); if data.len() != V4_ACK_PACKET_SIZE { debug!(target:"net", "Wrong ack packet size"); return Err(From::from(NetworkError::BadProtocol)); @@ -270,7 +264,7 @@ impl Handshake { } /// Sends auth message - fn write_auth(&mut self, secret: &Secret, public: &Public) -> Result<(), UtilError> { + fn write_auth(&mut self, io: &IoContext, secret: &Secret, public: &Public) -> Result<(), UtilError> where Message: Send + Clone { trace!(target:"network", "Sending handshake auth to {:?}", self.connection.remote_addr_str()); let mut data = [0u8; /*Signature::SIZE*/ 65 + /*H256::SIZE*/ 32 + /*Public::SIZE*/ 64 + /*H256::SIZE*/ 32 + 1]; //TODO: use associated constants let len = data.len(); @@ -290,14 +284,14 @@ impl Handshake { } let message = try!(crypto::ecies::encrypt(&self.id, &[], &data)); self.auth_cipher = message.clone(); - self.connection.send(message); + self.connection.send(io, message); self.connection.expect(V4_ACK_PACKET_SIZE); self.state = HandshakeState::ReadingAck; Ok(()) } /// Sends ack message - fn write_ack(&mut self) -> Result<(), UtilError> { + fn write_ack(&mut self, io: &IoContext) -> Result<(), UtilError> where Message: Send + Clone { trace!(target:"network", "Sending handshake ack to {:?}", self.connection.remote_addr_str()); let mut data = [0u8; 1 + /*Public::SIZE*/ 64 + /*H256::SIZE*/ 32]; //TODO: use associated constants let len = data.len(); @@ -310,13 +304,13 @@ impl Handshake { } let message = try!(crypto::ecies::encrypt(&self.id, &[], &data)); self.ack_cipher = message.clone(); - self.connection.send(message); + self.connection.send(io, message); self.state = HandshakeState::StartSession; Ok(()) } /// Sends EIP8 ack message - fn write_ack_eip8(&mut self) -> Result<(), UtilError> { + fn write_ack_eip8(&mut self, io: &IoContext) -> Result<(), UtilError> where Message: Send + Clone { trace!(target:"network", "Sending EIP8 handshake ack to {:?}", self.connection.remote_addr_str()); let mut rlp = RlpStream::new_list(3); rlp.append(self.ecdhe.public()); @@ -333,7 +327,7 @@ impl Handshake { let message = try!(crypto::ecies::encrypt(&self.id, &prefix, &encoded)); self.ack_cipher.extend_from_slice(&prefix); self.ack_cipher.extend_from_slice(&message); - self.connection.send(self.ack_cipher.clone()); + self.connection.send(io, self.ack_cipher.clone()); self.state = HandshakeState::StartSession; Ok(()) } @@ -347,6 +341,7 @@ mod test { use super::*; use crypto::*; use hash::*; + use io::*; use std::net::SocketAddr; use mio::tcp::TcpStream; use network::stats::NetworkStats; @@ -371,6 +366,10 @@ mod test { Handshake::new(0, to, socket, &nonce, Arc::new(NetworkStats::new())).unwrap() } + fn test_io() -> IoContext { + IoContext::new(IoChannel::disconnected(), 0) + } + #[test] fn test_handshake_auth_plain() { let mut h = create_handshake(None); @@ -387,7 +386,7 @@ mod test { a4592ee77e2bd94d0be3691f3b406f9bba9b591fc63facc016bfa8\ ".from_hex().unwrap(); - h.read_auth(&secret, &auth).unwrap(); + h.read_auth(&test_io(), &secret, &auth).unwrap(); assert_eq!(h.state, super::HandshakeState::StartSession); check_auth(&h, 4); } @@ -411,9 +410,9 @@ mod test { 3bf7678318e2d5b5340c9e488eefea198576344afbdf66db5f51204a6961a63ce072c8926c\ ".from_hex().unwrap(); - h.read_auth(&secret, &auth[0..super::V4_AUTH_PACKET_SIZE]).unwrap(); + h.read_auth(&test_io(), &secret, &auth[0..super::V4_AUTH_PACKET_SIZE]).unwrap(); assert_eq!(h.state, super::HandshakeState::ReadingAuthEip8); - h.read_auth_eip8(&secret, &auth[super::V4_AUTH_PACKET_SIZE..]).unwrap(); + h.read_auth_eip8(&test_io(), &secret, &auth[super::V4_AUTH_PACKET_SIZE..]).unwrap(); assert_eq!(h.state, super::HandshakeState::StartSession); check_auth(&h, 4); } @@ -438,9 +437,9 @@ mod test { d490\ ".from_hex().unwrap(); - h.read_auth(&secret, &auth[0..super::V4_AUTH_PACKET_SIZE]).unwrap(); + h.read_auth(&test_io(), &secret, &auth[0..super::V4_AUTH_PACKET_SIZE]).unwrap(); assert_eq!(h.state, super::HandshakeState::ReadingAuthEip8); - h.read_auth_eip8(&secret, &auth[super::V4_AUTH_PACKET_SIZE..]).unwrap(); + h.read_auth_eip8(&test_io(), &secret, &auth[super::V4_AUTH_PACKET_SIZE..]).unwrap(); assert_eq!(h.state, super::HandshakeState::StartSession); check_auth(&h, 56); let ack = h.ack_cipher.clone(); diff --git a/util/src/network/host.rs b/util/src/network/host.rs index fe139e383..46185482f 100644 --- a/util/src/network/host.rs +++ b/util/src/network/host.rs @@ -14,11 +14,11 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -use std::net::{SocketAddr}; -use std::collections::{HashMap}; -use std::str::{FromStr}; +use std::net::SocketAddr; +use std::collections::{HashMap, HashSet}; +use std::str::FromStr; use std::sync::*; -use std::sync::atomic::{AtomicUsize, Ordering as AtomicOrdering}; +use std::sync::atomic::{AtomicUsize, AtomicBool, Ordering as AtomicOrdering}; use std::ops::*; use std::cmp::min; use std::path::{Path, PathBuf}; @@ -35,12 +35,13 @@ use rlp::*; use network::session::{Session, SessionData}; use error::*; use io::*; -use network::{NetworkProtocolHandler, PROTOCOL_VERSION}; +use network::{NetworkProtocolHandler, NonReservedPeerMode, PROTOCOL_VERSION}; use network::node_table::*; use network::stats::NetworkStats; use network::error::{NetworkError, DisconnectReason}; use network::discovery::{Discovery, TableUpdates, NodeEntry}; use network::ip_utils::{map_external_address, select_public_address}; +use path::restrict_permissions_owner; type Slab = ::slab::Slab; @@ -49,7 +50,7 @@ const MAX_HANDSHAKES: usize = 80; const MAX_HANDSHAKES_PER_ROUND: usize = 32; const MAINTENANCE_TIMEOUT: u64 = 1000; -#[derive(Debug)] +#[derive(Debug, Clone)] /// Network service configuration pub struct NetworkConfiguration { /// Directory path to store network configuration. None means nothing will be saved @@ -64,14 +65,16 @@ pub struct NetworkConfiguration { pub nat_enabled: bool, /// Enable discovery pub discovery_enabled: bool, - /// Pin to boot nodes only - pub pin: bool, /// List of initial node addresses pub boot_nodes: Vec, /// Use provided node key instead of default pub use_secret: Option, /// Number of connected peers to maintain pub ideal_peers: u32, + /// List of reserved node addresses. + pub reserved_nodes: Vec, + /// The non-reserved peer mode. + pub non_reserved_mode: NonReservedPeerMode, } impl Default for NetworkConfiguration { @@ -90,10 +93,11 @@ impl NetworkConfiguration { udp_port: None, nat_enabled: true, discovery_enabled: true, - pin: false, boot_nodes: Vec::new(), use_secret: None, ideal_peers: 25, + reserved_nodes: Vec::new(), + non_reserved_mode: NonReservedPeerMode::Accept, } } @@ -187,13 +191,15 @@ pub struct NetworkContext<'s, Message> where Message: Send + Sync + Clone + 'sta sessions: Arc>>, session: Option, session_id: Option, + _reserved_peers: &'s HashSet, } impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone + 'static, { /// Create a new network IO access point. Takes references to all the data that can be updated within the IO handler. fn new(io: &'s IoContext>, protocol: ProtocolId, - session: Option, sessions: Arc>>) -> NetworkContext<'s, Message> { + session: Option, sessions: Arc>>, + reserved_peers: &'s HashSet) -> NetworkContext<'s, Message> { let id = session.as_ref().map(|s| s.lock().unwrap().token()); NetworkContext { io: io, @@ -201,6 +207,7 @@ impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone session_id: id, session: session, sessions: sessions, + _reserved_peers: reserved_peers, } } @@ -215,8 +222,7 @@ impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone pub fn send(&self, peer: PeerId, packet_id: PacketId, data: Vec) -> Result<(), UtilError> { let session = self.resolve_session(peer); if let Some(session) = session { - try!(session.lock().unwrap().deref_mut().send_packet(self.protocol, packet_id as u8, &data)); - try!(self.io.update_registration(peer)); + try!(session.lock().unwrap().send_packet(self.io, self.protocol, packet_id as u8, &data)); } else { trace!(target: "network", "Send: Peer no longer exist") } @@ -230,19 +236,31 @@ impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone } /// Send an IO message - pub fn message(&self, msg: Message) { - self.io.message(NetworkIoMessage::User(msg)); + pub fn message(&self, msg: Message) -> Result<(), UtilError> { + self.io.message(NetworkIoMessage::User(msg)) + } + + /// Get an IoChannel. + pub fn io_channel(&self) -> IoChannel> { + self.io.channel() } /// Disable current protocol capability for given peer. If no capabilities left peer gets disconnected. pub fn disable_peer(&self, peer: PeerId) { //TODO: remove capability, disconnect if no capabilities left - self.io.message(NetworkIoMessage::DisablePeer(peer)); + self.io.message(NetworkIoMessage::DisablePeer(peer)) + .unwrap_or_else(|e| warn!("Error sending network IO message: {:?}", e)); } /// Disconnect peer. Reconnect can be attempted later. pub fn disconnect_peer(&self, peer: PeerId) { - self.io.message(NetworkIoMessage::Disconnect(peer)); + self.io.message(NetworkIoMessage::Disconnect(peer)) + .unwrap_or_else(|e| warn!("Error sending network IO message: {:?}", e)); + } + + /// Check if the session is still active. + pub fn is_expired(&self) -> bool { + self.session.as_ref().map_or(false, |s| s.lock().unwrap().expired()) } /// Register a new IO timer. 'IoHandler::timeout' will be called with the token. @@ -251,7 +269,7 @@ impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone token: token, delay: ms, protocol: self.protocol, - }); + }).unwrap_or_else(|e| warn!("Error sending network IO message: {:?}", e)); Ok(()) } @@ -322,13 +340,14 @@ pub struct Host where Message: Send + Sync + Clone { timers: RwLock>, timer_counter: RwLock, stats: Arc, - pinned_nodes: Vec, + reserved_nodes: RwLock>, num_sessions: AtomicUsize, + stopping: AtomicBool, } impl Host where Message: Send + Sync + Clone { /// Create a new instance - pub fn new(config: NetworkConfiguration) -> Result, UtilError> { + pub fn new(config: NetworkConfiguration, stats: Arc) -> Result, UtilError> { let mut listen_address = match config.listen_address { None => SocketAddr::from_str("0.0.0.0:30304").unwrap(), Some(addr) => addr, @@ -354,6 +373,9 @@ impl Host where Message: Send + Sync + Clone { let udp_port = config.udp_port.unwrap_or(listen_address.port()); let local_endpoint = NodeEndpoint { address: listen_address, udp_port: udp_port }; + let boot_nodes = config.boot_nodes.clone(); + let reserved_nodes = config.reserved_nodes.clone(); + let mut host = Host:: { info: RwLock::new(HostInfo { keys: keys, @@ -372,20 +394,22 @@ impl Host where Message: Send + Sync + Clone { handlers: RwLock::new(HashMap::new()), timers: RwLock::new(HashMap::new()), timer_counter: RwLock::new(USER_TIMER), - stats: Arc::new(NetworkStats::default()), - pinned_nodes: Vec::new(), + stats: stats, + reserved_nodes: RwLock::new(HashSet::new()), num_sessions: AtomicUsize::new(0), + stopping: AtomicBool::new(false), }; - let boot_nodes = host.info.read().unwrap().config.boot_nodes.clone(); for n in boot_nodes { host.add_node(&n); } - Ok(host) - } - pub fn stats(&self) -> Arc { - self.stats.clone() + for n in reserved_nodes { + if let Err(e) = host.add_reserved_node(&n) { + debug!(target: "network", "Error parsing node id: {}: {:?}", n, e); + } + } + Ok(host) } pub fn add_node(&mut self, id: &str) { @@ -393,17 +417,67 @@ impl Host where Message: Send + Sync + Clone { Err(e) => { debug!(target: "network", "Could not add node {}: {:?}", id, e); }, Ok(n) => { let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id.clone() }; - self.pinned_nodes.push(n.id.clone()); + self.nodes.write().unwrap().add_node(n); - if let Some(ref mut discovery) = *self.discovery.lock().unwrap().deref_mut() { + if let Some(ref mut discovery) = *self.discovery.lock().unwrap() { discovery.add_node(entry); } } } } - pub fn client_version(&self) -> String { - self.info.read().unwrap().client_version.clone() + pub fn add_reserved_node(&self, id: &str) -> Result<(), UtilError> { + let n = try!(Node::from_str(id)); + + let entry = NodeEntry { endpoint: n.endpoint.clone(), id: n.id.clone() }; + self.reserved_nodes.write().unwrap().insert(n.id.clone()); + + if let Some(ref mut discovery) = *self.discovery.lock().unwrap() { + discovery.add_node(entry); + } + + Ok(()) + } + + pub fn set_non_reserved_mode(&self, mode: NonReservedPeerMode, io: &IoContext>) { + let mut info = self.info.write().unwrap(); + + if info.config.non_reserved_mode != mode { + info.config.non_reserved_mode = mode.clone(); + drop(info); + if let NonReservedPeerMode::Deny = mode { + // disconnect all non-reserved peers here. + let reserved: HashSet = self.reserved_nodes.read().unwrap().clone(); + let mut to_kill = Vec::new(); + for e in self.sessions.write().unwrap().iter_mut() { + let mut s = e.lock().unwrap(); + { + let id = s.id(); + if id.is_some() && reserved.contains(id.unwrap()) { + continue; + } + } + + s.disconnect(io, DisconnectReason::ClientQuit); + to_kill.push(s.token()); + } + for p in to_kill { + trace!(target: "network", "Disconnecting on reserved-only mode: {}", p); + self.kill_connection(p, io, false); + } + } + } + } + + pub fn remove_reserved_node(&self, id: &str) -> Result<(), UtilError> { + let n = try!(Node::from_str(id)); + self.reserved_nodes.write().unwrap().remove(&n.id); + + Ok(()) + } + + pub fn client_version() -> String { + version() } pub fn external_url(&self) -> Option { @@ -416,6 +490,22 @@ impl Host where Message: Send + Sync + Clone { r } + pub fn stop(&self, io: &IoContext>) -> Result<(), UtilError> { + self.stopping.store(true, AtomicOrdering::Release); + let mut to_kill = Vec::new(); + for e in self.sessions.write().unwrap().iter_mut() { + let mut s = e.lock().unwrap(); + s.disconnect(io, DisconnectReason::ClientQuit); + to_kill.push(s.token()); + } + for p in to_kill { + trace!(target: "network", "Disconnecting on shutdown: {}", p); + self.kill_connection(p, io, true); + } + try!(io.unregister_handler()); + Ok(()) + } + fn init_public_interface(&self, io: &IoContext>) -> Result<(), UtilError> { io.clear_timer(INIT_PUBLIC).unwrap(); if self.info.read().unwrap().public_endpoint.is_some() { @@ -448,7 +538,7 @@ impl Host where Message: Send + Sync + Clone { // Initialize discovery. let discovery = { let info = self.info.read().unwrap(); - if info.config.discovery_enabled && !info.config.pin { + if info.config.discovery_enabled && info.config.non_reserved_mode == NonReservedPeerMode::Accept { Some(Discovery::new(&info.keys, public_endpoint.address.clone(), public_endpoint, DISCOVERY)) } else { None } }; @@ -458,7 +548,7 @@ impl Host where Message: Send + Sync + Clone { for n in self.nodes.read().unwrap().unordered_entries() { discovery.add_node(n.clone()); } - *self.discovery.lock().unwrap().deref_mut() = Some(discovery); + *self.discovery.lock().unwrap() = Some(discovery); io.register_stream(DISCOVERY).expect("Error registering UDP listener"); io.register_timer(DISCOVERY_REFRESH, 7200).expect("Error registering discovery timer"); io.register_timer(DISCOVERY_ROUND, 300).expect("Error registering discovery timer"); @@ -494,7 +584,7 @@ impl Host where Message: Send + Sync + Clone { for e in self.sessions.write().unwrap().iter_mut() { let mut s = e.lock().unwrap(); if !s.keep_alive(io) { - s.disconnect(DisconnectReason::PingTimeout); + s.disconnect(io, DisconnectReason::PingTimeout); to_kill.push(s.token()); } } @@ -505,14 +595,26 @@ impl Host where Message: Send + Sync + Clone { } fn connect_peers(&self, io: &IoContext>) { - if self.info.read().unwrap().deref().capabilities.is_empty() { - return; - } - let ideal_peers = { self.info.read().unwrap().deref().config.ideal_peers }; - let pin = { self.info.read().unwrap().deref().config.pin }; + let (ideal_peers, mut pin) = { + let info = self.info.read().unwrap(); + if info.capabilities.is_empty() { + return; + } + let config = &info.config; + + (config.ideal_peers, config.non_reserved_mode == NonReservedPeerMode::Deny) + }; + let session_count = self.session_count(); - if session_count >= ideal_peers as usize { - return; + let reserved_nodes = self.reserved_nodes.read().unwrap(); + if session_count >= ideal_peers as usize + reserved_nodes.len() { + // check if all pinned nodes are connected. + if reserved_nodes.iter().all(|n| self.have_session(n) && self.connecting_to(n)) { + return; + } + + // if not, only attempt connect to reserved peers + pin = true; } let handshake_count = self.handshake_count(); @@ -522,12 +624,21 @@ impl Host where Message: Send + Sync + Clone { return; } - let nodes = if pin { self.pinned_nodes.clone() } else { self.nodes.read().unwrap().nodes() }; - for id in nodes.iter().filter(|ref id| !self.have_session(id) && !self.connecting_to(id)) + // iterate over all nodes, reserved ones coming first. + // if we are pinned to only reserved nodes, ignore all others. + let nodes = reserved_nodes.iter().cloned().chain(if !pin { + self.nodes.read().unwrap().nodes() + } else { + Vec::new() + }); + + let mut started: usize = 0; + for id in nodes.filter(|ref id| !self.have_session(id) && !self.connecting_to(id)) .take(min(MAX_HANDSHAKES_PER_ROUND, handshake_limit - handshake_count)) { self.connect_peer(&id, io); + started += 1; } - debug!(target: "network", "Connecting peers: {} sessions, {} pending", self.session_count(), self.handshake_count()); + debug!(target: "network", "Connecting peers: {} sessions, {} pending, {} started", self.session_count(), self.handshake_count(), started); } #[cfg_attr(feature="dev", allow(single_match))] @@ -605,7 +716,6 @@ impl Host where Message: Send + Sync + Clone { debug!(target: "network", "Can't accept connection: {:?}", e); } } - io.update_registration(TCP_ACCEPT).expect("Error registering TCP listener"); } fn session_writable(&self, token: StreamToken, io: &IoContext>) { @@ -616,9 +726,7 @@ impl Host where Message: Send + Sync + Clone { trace!(target: "network", "Session write error: {}: {:?}", token, e); } if s.done() { - io.deregister_stream(token).expect("Error deregistering stream"); - } else { - io.update_registration(token).unwrap_or_else(|e| debug!(target: "network", "Session registration error: {:?}", e)); + io.deregister_stream(token).unwrap_or_else(|e| debug!("Error deregistering stream: {:?}", e)); } } } @@ -628,78 +736,90 @@ impl Host where Message: Send + Sync + Clone { self.kill_connection(token, io, true); } + #[cfg_attr(feature="dev", allow(collapsible_if))] fn session_readable(&self, token: StreamToken, io: &IoContext>) { let mut ready_data: Vec = Vec::new(); - let mut packet_data: Option<(ProtocolId, PacketId, Vec)> = None; + let mut packet_data: Vec<(ProtocolId, PacketId, Vec)> = Vec::new(); let mut kill = false; let session = { self.sessions.read().unwrap().get(token).cloned() }; if let Some(session) = session.clone() { let mut s = session.lock().unwrap(); - match s.readable(io, &self.info.read().unwrap()) { - Err(e) => { - trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e); - match e { - UtilError::Network(NetworkError::Disconnect(DisconnectReason::UselessPeer)) | - UtilError::Network(NetworkError::Disconnect(DisconnectReason::IncompatibleProtocol)) => { + loop { + match s.readable(io, &self.info.read().unwrap()) { + Err(e) => { + trace!(target: "network", "Session read error: {}:{:?} ({:?}) {:?}", token, s.id(), s.remote_addr(), e); + if let UtilError::Network(NetworkError::Disconnect(DisconnectReason::IncompatibleProtocol)) = e { if let Some(id) = s.id() { self.nodes.write().unwrap().mark_as_useless(id); } } - _ => (), - } - kill = true; - }, - Ok(SessionData::Ready) => { - if !s.info.originated { - let session_count = self.session_count(); - let ideal_peers = { self.info.read().unwrap().deref().config.ideal_peers }; - if session_count >= ideal_peers as usize { - s.disconnect(DisconnectReason::TooManyPeers); - return; - } - // Add it no node table - if let Ok(address) = s.remote_addr() { - let entry = NodeEntry { id: s.id().unwrap().clone(), endpoint: NodeEndpoint { address: address, udp_port: address.port() } }; - self.nodes.write().unwrap().add_node(Node::new(entry.id.clone(), entry.endpoint.clone())); - let mut discovery = self.discovery.lock().unwrap(); - if let Some(ref mut discovery) = *discovery.deref_mut() { - discovery.add_node(entry); + kill = true; + break; + }, + Ok(SessionData::Ready) => { + self.num_sessions.fetch_add(1, AtomicOrdering::SeqCst); + if !s.info.originated { + let session_count = self.session_count(); + let reserved_nodes = self.reserved_nodes.read().unwrap(); + let (ideal_peers, reserved_only) = { + let info = self.info.read().unwrap(); + (info.config.ideal_peers, info.config.non_reserved_mode == NonReservedPeerMode::Deny) + }; + + if session_count >= ideal_peers as usize || reserved_only { + // only proceed if the connecting peer is reserved. + if !reserved_nodes.contains(s.id().unwrap()) { + s.disconnect(io, DisconnectReason::TooManyPeers); + return; + } + } + + // Add it no node table + if let Ok(address) = s.remote_addr() { + let entry = NodeEntry { id: s.id().unwrap().clone(), endpoint: NodeEndpoint { address: address, udp_port: address.port() } }; + self.nodes.write().unwrap().add_node(Node::new(entry.id.clone(), entry.endpoint.clone())); + let mut discovery = self.discovery.lock().unwrap(); + if let Some(ref mut discovery) = *discovery.deref_mut() { + discovery.add_node(entry); + } } } - } - self.num_sessions.fetch_add(1, AtomicOrdering::SeqCst); - for (p, _) in self.handlers.read().unwrap().iter() { - if s.have_capability(p) { - ready_data.push(p); + for (p, _) in self.handlers.read().unwrap().iter() { + if s.have_capability(p) { + ready_data.push(p); + } } - } - }, - Ok(SessionData::Packet { - data, - protocol, - packet_id, - }) => { - match self.handlers.read().unwrap().get(protocol) { - None => { warn!(target: "network", "No handler found for protocol: {:?}", protocol) }, - Some(_) => packet_data = Some((protocol, packet_id, data)), - } - }, - Ok(SessionData::None) => {}, - } + }, + Ok(SessionData::Packet { + data, + protocol, + packet_id, + }) => { + match self.handlers.read().unwrap().get(protocol) { + None => { warn!(target: "network", "No handler found for protocol: {:?}", protocol) }, + Some(_) => packet_data.push((protocol, packet_id, data)), + } + }, + Ok(SessionData::Continue) => (), + Ok(SessionData::None) => break, + } + } } if kill { self.kill_connection(token, io, true); } + let handlers = self.handlers.read().unwrap(); for p in ready_data { - let h = self.handlers.read().unwrap().get(p).unwrap().clone(); + let h = handlers.get(p).unwrap().clone(); self.stats.inc_sessions(); - h.connected(&NetworkContext::new(io, p, session.clone(), self.sessions.clone()), &token); + let reserved = self.reserved_nodes.read().unwrap(); + h.connected(&NetworkContext::new(io, p, session.clone(), self.sessions.clone(), &reserved), &token); } - if let Some((p, packet_id, data)) = packet_data { - let h = self.handlers.read().unwrap().get(p).unwrap().clone(); - h.read(&NetworkContext::new(io, p, session.clone(), self.sessions.clone()), &token, packet_id, &data[1..]); + for (p, packet_id, data) in packet_data { + let h = handlers.get(p).unwrap().clone(); + let reserved = self.reserved_nodes.read().unwrap(); + h.read(&NetworkContext::new(io, p, session.clone(), self.sessions.clone(), &reserved), &token, packet_id, &data[1..]); } - io.update_registration(token).unwrap_or_else(|e| debug!(target: "network", "Token registration error: {:?}", e)); } fn connection_timeout(&self, token: StreamToken, io: &IoContext>) { @@ -719,9 +839,9 @@ impl Host where Message: Send + Sync + Clone { let mut s = session.lock().unwrap(); if !s.expired() { if s.is_ready() { + self.num_sessions.fetch_sub(1, AtomicOrdering::SeqCst); for (p, _) in self.handlers.read().unwrap().iter() { if s.have_capability(p) { - self.num_sessions.fetch_sub(1, AtomicOrdering::SeqCst); to_disconnect.push(p); } } @@ -739,12 +859,11 @@ impl Host where Message: Send + Sync + Clone { } for p in to_disconnect { let h = self.handlers.read().unwrap().get(p).unwrap().clone(); - h.disconnected(&NetworkContext::new(io, p, expired_session.clone(), self.sessions.clone()), &token); + let reserved = self.reserved_nodes.read().unwrap(); + h.disconnected(&NetworkContext::new(io, p, expired_session.clone(), self.sessions.clone(), &reserved), &token); } if deregister { - io.deregister_stream(token).expect("Error deregistering stream"); - } else if expired_session.is_some() { - io.update_registration(token).unwrap_or_else(|e| debug!(target: "network", "Connection registration error: {:?}", e)); + io.deregister_stream(token).unwrap_or_else(|e| debug!("Error deregistering stream: {:?}", e)); } } @@ -786,14 +905,16 @@ impl IoHandler> for Host where Messa } fn stream_readable(&self, io: &IoContext>, stream: StreamToken) { + if self.stopping.load(AtomicOrdering::Acquire) { + return; + } match stream { FIRST_SESSION ... LAST_SESSION => self.session_readable(stream, io), DISCOVERY => { - let node_changes = { self.discovery.lock().unwrap().as_mut().unwrap().readable() }; + let node_changes = { self.discovery.lock().unwrap().as_mut().unwrap().readable(io) }; if let Some(node_changes) = node_changes { self.update_nodes(io, node_changes); } - io.update_registration(DISCOVERY).expect("Error updating discovery registration"); }, TCP_ACCEPT => self.accept(io), _ => panic!("Received unknown readable token"), @@ -801,17 +922,22 @@ impl IoHandler> for Host where Messa } fn stream_writable(&self, io: &IoContext>, stream: StreamToken) { + if self.stopping.load(AtomicOrdering::Acquire) { + return; + } match stream { FIRST_SESSION ... LAST_SESSION => self.session_writable(stream, io), DISCOVERY => { - self.discovery.lock().unwrap().as_mut().unwrap().writable(); - io.update_registration(DISCOVERY).expect("Error updating discovery registration"); + self.discovery.lock().unwrap().as_mut().unwrap().writable(io); } _ => panic!("Received unknown writable token"), } } fn timeout(&self, io: &IoContext>, token: TimerToken) { + if self.stopping.load(AtomicOrdering::Acquire) { + return; + } match token { IDLE => self.maintain_network(io), INIT_PUBLIC => self.init_public_interface(io).unwrap_or_else(|e| @@ -819,22 +945,26 @@ impl IoHandler> for Host where Messa FIRST_SESSION ... LAST_SESSION => self.connection_timeout(token, io), DISCOVERY_REFRESH => { self.discovery.lock().unwrap().as_mut().unwrap().refresh(); - io.update_registration(DISCOVERY).expect("Error updating discovery registration"); + io.update_registration(DISCOVERY).unwrap_or_else(|e| debug!("Error updating discovery registration: {:?}", e)); }, DISCOVERY_ROUND => { let node_changes = { self.discovery.lock().unwrap().as_mut().unwrap().round() }; if let Some(node_changes) = node_changes { self.update_nodes(io, node_changes); } - io.update_registration(DISCOVERY).expect("Error updating discovery registration"); + io.update_registration(DISCOVERY).unwrap_or_else(|e| debug!("Error updating discovery registration: {:?}", e)); }, NODE_TABLE => { + trace!(target: "network", "Refreshing node table"); self.nodes.write().unwrap().clear_useless(); }, _ => match self.timers.read().unwrap().get(&token).cloned() { Some(timer) => match self.handlers.read().unwrap().get(timer.protocol).cloned() { - None => { warn!(target: "network", "No handler found for protocol: {:?}", timer.protocol) }, - Some(h) => { h.timeout(&NetworkContext::new(io, timer.protocol, None, self.sessions.clone()), timer.token); } + None => { warn!(target: "network", "No handler found for protocol: {:?}", timer.protocol) }, + Some(h) => { + let reserved = self.reserved_nodes.read().unwrap(); + h.timeout(&NetworkContext::new(io, timer.protocol, None, self.sessions.clone(), &reserved), timer.token); + } }, None => { warn!("Unknown timer token: {}", token); } // timer is not registerd through us } @@ -842,6 +972,9 @@ impl IoHandler> for Host where Messa } fn message(&self, io: &IoContext>, message: &NetworkIoMessage) { + if self.stopping.load(AtomicOrdering::Acquire) { + return; + } match *message { NetworkIoMessage::AddHandler { ref handler, @@ -849,7 +982,8 @@ impl IoHandler> for Host where Messa ref versions } => { let h = handler.clone(); - h.initialize(&NetworkContext::new(io, protocol, None, self.sessions.clone())); + let reserved = self.reserved_nodes.read().unwrap(); + h.initialize(&NetworkContext::new(io, protocol, None, self.sessions.clone(), &reserved)); self.handlers.write().unwrap().insert(protocol, h); let mut info = self.info.write().unwrap(); for v in versions { @@ -863,18 +997,18 @@ impl IoHandler> for Host where Messa } => { let handler_token = { let mut timer_counter = self.timer_counter.write().unwrap(); - let counter = timer_counter.deref_mut(); + let counter = &mut *timer_counter; let handler_token = *counter; *counter += 1; handler_token }; self.timers.write().unwrap().insert(handler_token, ProtocolTimer { protocol: protocol, token: *token }); - io.register_timer(handler_token, *delay).expect("Error registering timer"); + io.register_timer(handler_token, *delay).unwrap_or_else(|e| debug!("Error registering timer {}: {:?}", token, e)); }, NetworkIoMessage::Disconnect(ref peer) => { let session = { self.sessions.read().unwrap().get(*peer).cloned() }; if let Some(session) = session { - session.lock().unwrap().disconnect(DisconnectReason::DisconnectRequested); + session.lock().unwrap().disconnect(io, DisconnectReason::DisconnectRequested); } trace!(target: "network", "Disconnect requested {}", peer); self.kill_connection(*peer, io, false); @@ -882,7 +1016,7 @@ impl IoHandler> for Host where Messa NetworkIoMessage::DisablePeer(ref peer) => { let session = { self.sessions.read().unwrap().get(*peer).cloned() }; if let Some(session) = session { - session.lock().unwrap().disconnect(DisconnectReason::DisconnectRequested); + session.lock().unwrap().disconnect(io, DisconnectReason::DisconnectRequested); if let Some(id) = session.lock().unwrap().id() { self.nodes.write().unwrap().mark_as_useless(id) } @@ -891,8 +1025,9 @@ impl IoHandler> for Host where Messa self.kill_connection(*peer, io, false); }, NetworkIoMessage::User(ref message) => { + let reserved = self.reserved_nodes.read().unwrap(); for (p, h) in self.handlers.read().unwrap().iter() { - h.message(&NetworkContext::new(io, p, None, self.sessions.clone()), &message); + h.message(&NetworkContext::new(io, p, None, self.sessions.clone(), &reserved), &message); } } } @@ -907,7 +1042,7 @@ impl IoHandler> for Host where Messa } } DISCOVERY => self.discovery.lock().unwrap().as_ref().unwrap().register_socket(event_loop).expect("Error registering discovery socket"), - TCP_ACCEPT => event_loop.register(self.tcp_listener.lock().unwrap().deref(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error registering stream"), + TCP_ACCEPT => event_loop.register(&*self.tcp_listener.lock().unwrap(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error registering stream"), _ => warn!("Unexpected stream registration") } } @@ -935,7 +1070,7 @@ impl IoHandler> for Host where Messa } } DISCOVERY => self.discovery.lock().unwrap().as_ref().unwrap().update_registration(event_loop).expect("Error reregistering discovery socket"), - TCP_ACCEPT => event_loop.reregister(self.tcp_listener.lock().unwrap().deref(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error reregistering stream"), + TCP_ACCEPT => event_loop.reregister(&*self.tcp_listener.lock().unwrap(), Token(TCP_ACCEPT), EventSet::all(), PollOpt::edge()).expect("Error reregistering stream"), _ => warn!("Unexpected stream update") } } @@ -948,13 +1083,17 @@ fn save_key(path: &Path, key: &Secret) { return; }; path_buf.push("key"); - let mut file = match fs::File::create(path_buf.as_path()) { + let path = path_buf.as_path(); + let mut file = match fs::File::create(&path) { Ok(file) => file, Err(e) => { warn!("Error creating key file: {:?}", e); return; } }; + if let Err(e) = restrict_permissions_owner(&path) { + warn!(target: "network", "Failed to modify permissions of the file (chmod: {})", e); + } if let Err(e) = file.write(&key.hex().into_bytes()) { warn!("Error writing key file: {:?}", e); } @@ -1003,6 +1142,6 @@ fn host_client_url() { let mut config = NetworkConfiguration::new(); let key = h256_from_hex("6f7b0d801bc7b5ce7bbd930b84fd0369b3eb25d09be58d64ba811091046f3aa2"); config.use_secret = Some(key); - let host: Host = Host::new(config).unwrap(); + let host: Host = Host::new(config, Arc::new(NetworkStats::new())).unwrap(); assert!(host.local_url().starts_with("enode://101b3ef5a4ea7a1c7928e24c4c75fd053c235d7b80c22ae5c03d145d0ac7396e2a4ffff9adee3133a7b05044a5cee08115fd65145e5165d646bde371010d803c@")); } diff --git a/util/src/network/mod.rs b/util/src/network/mod.rs index 29f3d166c..d59ab63b1 100644 --- a/util/src/network/mod.rs +++ b/util/src/network/mod.rs @@ -14,8 +14,8 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -//! Network and general IO module. -//! +//! Network and general IO module. +//! //! Example usage for craeting a network service and adding an IO handler: //! //! ```rust @@ -56,8 +56,9 @@ //! } //! //! fn main () { -//! let mut service = NetworkService::::start(NetworkConfiguration::new_local()).expect("Error creating network service"); +//! let mut service = NetworkService::::new(NetworkConfiguration::new_local()).expect("Error creating network service"); //! service.register_protocol(Arc::new(MyHandler), "myproto", &[1u8]); +//! service.start().expect("Error starting service"); //! //! // Wait for quit condition //! // ... @@ -111,3 +112,22 @@ pub trait NetworkProtocolHandler: Sync + Send where Message: Send + Syn fn message(&self, _io: &NetworkContext, _message: &Message) {} } +/// Non-reserved peer modes. +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum NonReservedPeerMode { + /// Accept them. This is the default. + Accept, + /// Deny them. + Deny, +} + +impl NonReservedPeerMode { + /// Attempt to parse the peer mode from a string. + pub fn parse(s: &str) -> Option { + match s { + "accept" => Some(NonReservedPeerMode::Accept), + "deny" => Some(NonReservedPeerMode::Deny), + _ => None, + } + } +} \ No newline at end of file diff --git a/util/src/network/service.rs b/util/src/network/service.rs index 49957f7e7..353a24bbe 100644 --- a/util/src/network/service.rs +++ b/util/src/network/service.rs @@ -18,9 +18,9 @@ use std::sync::*; use error::*; use panics::*; use network::{NetworkProtocolHandler, NetworkConfiguration}; -use network::error::{NetworkError}; +use network::error::NetworkError; use network::host::{Host, NetworkIoMessage, ProtocolId}; -use network::stats::{NetworkStats}; +use network::stats::NetworkStats; use io::*; /// IO Service with networking @@ -28,33 +28,33 @@ use io::*; pub struct NetworkService where Message: Send + Sync + Clone + 'static { io_service: IoService>, host_info: String, - host: Arc>, + host: RwLock>>>, stats: Arc, - panic_handler: Arc + panic_handler: Arc, + config: NetworkConfiguration, } impl NetworkService where Message: Send + Sync + Clone + 'static { /// Starts IO event loop - pub fn start(config: NetworkConfiguration) -> Result, UtilError> { + pub fn new(config: NetworkConfiguration) -> Result, UtilError> { let panic_handler = PanicHandler::new_in_arc(); - let mut io_service = try!(IoService::>::start()); + let io_service = try!(IoService::>::start()); panic_handler.forward_from(&io_service); - let host = Arc::new(try!(Host::new(config))); - let stats = host.stats().clone(); - let host_info = host.client_version(); - try!(io_service.register_handler(host.clone())); + let stats = Arc::new(NetworkStats::new()); + let host_info = Host::::client_version(); Ok(NetworkService { io_service: io_service, host_info: host_info, stats: stats, panic_handler: panic_handler, - host: host, + host: RwLock::new(None), + config: config, }) } /// Regiter a new protocol handler with the event loop. - pub fn register_protocol(&mut self, handler: Arc+Send + Sync>, protocol: ProtocolId, versions: &[u8]) -> Result<(), NetworkError> { + pub fn register_protocol(&self, handler: Arc+Send + Sync>, protocol: ProtocolId, versions: &[u8]) -> Result<(), NetworkError> { try!(self.io_service.send_message(NetworkIoMessage::AddHandler { handler: handler, protocol: protocol, @@ -69,8 +69,8 @@ impl NetworkService where Message: Send + Sync + Clone + 'stat } /// Returns underlying io service. - pub fn io(&mut self) -> &mut IoService> { - &mut self.io_service + pub fn io(&self) -> &IoService> { + &self.io_service } /// Returns network statistics. @@ -80,12 +80,65 @@ impl NetworkService where Message: Send + Sync + Clone + 'stat /// Returns external url if available. pub fn external_url(&self) -> Option { - self.host.external_url() + let host = self.host.read().unwrap(); + host.as_ref().and_then(|h| h.external_url()) } /// Returns external url if available. - pub fn local_url(&self) -> String { - self.host.local_url() + pub fn local_url(&self) -> Option { + let host = self.host.read().unwrap(); + host.as_ref().map(|h| h.local_url()) + } + + /// Start network IO + pub fn start(&self) -> Result<(), UtilError> { + let mut host = self.host.write().unwrap(); + if host.is_none() { + let h = Arc::new(try!(Host::new(self.config.clone(), self.stats.clone()))); + try!(self.io_service.register_handler(h.clone())); + *host = Some(h); + } + Ok(()) + } + + /// Stop network IO + pub fn stop(&self) -> Result<(), UtilError> { + let mut host = self.host.write().unwrap(); + if let Some(ref host) = *host { + let io = IoContext::new(self.io_service.channel(), 0); //TODO: take token id from host + try!(host.stop(&io)); + } + *host = None; + Ok(()) + } + + /// Try to add a reserved peer. + pub fn add_reserved_peer(&self, peer: &str) -> Result<(), UtilError> { + let host = self.host.read().unwrap(); + if let Some(ref host) = *host { + host.add_reserved_node(peer) + } else { + Ok(()) + } + } + + /// Try to remove a reserved peer. + pub fn remove_reserved_peer(&self, peer: &str) -> Result<(), UtilError> { + let host = self.host.read().unwrap(); + if let Some(ref host) = *host { + host.remove_reserved_node(peer) + } else { + Ok(()) + } + } + + /// Set the non-reserved peer mode. + pub fn set_non_reserved_mode(&self, mode: ::network::NonReservedPeerMode) { + let host = self.host.read().unwrap(); + if let Some(ref host) = *host { + let io_ctxt = IoContext::new(self.io_service.channel(), 0); + host.set_non_reserved_mode(mode, &io_ctxt); + } } } diff --git a/util/src/network/session.rs b/util/src/network/session.rs index 7b7f16c18..c19dfbcf8 100644 --- a/util/src/network/session.rs +++ b/util/src/network/session.rs @@ -68,6 +68,8 @@ pub enum SessionData { /// Zero based packet ID packet_id: u8, }, + /// Session has more data to be read + Continue, } /// Shared session information @@ -145,7 +147,7 @@ impl Session { }) } - fn complete_handshake(&mut self, host: &HostInfo) -> Result<(), UtilError> { + fn complete_handshake(&mut self, io: &IoContext, host: &HostInfo) -> Result<(), UtilError> where Message: Send + Sync + Clone { let connection = if let State::Handshake(ref mut h) = self.state { self.info.id = Some(h.id.clone()); try!(EncryptedConnection::new(h)) @@ -153,8 +155,8 @@ impl Session { panic!("Unexpected state"); }; self.state = State::Session(connection); - try!(self.write_hello(host)); - try!(self.send_ping()); + try!(self.write_hello(io, host)); + try!(self.send_ping(io)); Ok(()) } @@ -220,10 +222,11 @@ impl Session { } } if let Some(data) = packet_data { - return Ok(try!(self.read_packet(data, host))); + return Ok(try!(self.read_packet(io, data, host))); } if create_session { - try!(self.complete_handshake(host)); + try!(self.complete_handshake(io, host)); + io.update_registration(self.token()).unwrap_or_else(|e| debug!(target: "network", "Token registration error: {:?}", e)); } Ok(SessionData::None) } @@ -263,7 +266,8 @@ impl Session { } /// Send a protocol packet to peer. - pub fn send_packet(&mut self, protocol: &str, packet_id: u8, data: &[u8]) -> Result<(), UtilError> { + pub fn send_packet(&mut self, io: &IoContext, protocol: &str, packet_id: u8, data: &[u8]) -> Result<(), UtilError> + where Message: Send + Sync + Clone { if self.info.capabilities.is_empty() || !self.had_hello { debug!(target: "network", "Sending to unconfirmed session {}, protocol: {}, packet: {}", self.token(), protocol, packet_id); return Err(From::from(NetworkError::BadProtocol)); @@ -283,7 +287,7 @@ impl Session { let mut rlp = RlpStream::new(); rlp.append(&(pid as u32)); rlp.append_raw(data, 1); - self.send(rlp) + self.send(io, rlp) } /// Keep this session alive. Returns false if ping timeout happened @@ -298,10 +302,9 @@ impl Session { }; if !timed_out && time::precise_time_ns() - self.ping_time_ns > PING_INTERVAL_SEC * 1000_000_000 { - if let Err(e) = self.send_ping() { + if let Err(e) = self.send_ping(io) { debug!("Error sending ping message: {:?}", e); } - io.update_registration(self.token()).unwrap_or_else(|e| debug!(target: "network", "Session registration error: {:?}", e)); } !timed_out } @@ -310,7 +313,8 @@ impl Session { self.connection().token() } - fn read_packet(&mut self, packet: Packet, host: &HostInfo) -> Result { + fn read_packet(&mut self, io: &IoContext, packet: Packet, host: &HostInfo) -> Result + where Message: Send + Sync + Clone { if packet.data.len() < 2 { return Err(From::from(NetworkError::BadProtocol)); } @@ -321,22 +325,25 @@ impl Session { match packet_id { PACKET_HELLO => { let rlp = UntrustedRlp::new(&packet.data[1..]); //TODO: validate rlp expected size - try!(self.read_hello(&rlp, host)); + try!(self.read_hello(io, &rlp, host)); Ok(SessionData::Ready) }, PACKET_DISCONNECT => { let rlp = UntrustedRlp::new(&packet.data[1..]); let reason: u8 = try!(rlp.val_at(0)); + if self.had_hello { + debug!("Disconnected: {}: {:?}", self.token(), DisconnectReason::from_u8(reason)); + } Err(From::from(NetworkError::Disconnect(DisconnectReason::from_u8(reason)))) } PACKET_PING => { - try!(self.send_pong()); - Ok(SessionData::None) + try!(self.send_pong(io)); + Ok(SessionData::Continue) }, PACKET_PONG => { self.pong_time_ns = Some(time::precise_time_ns()); self.info.ping_ms = Some((self.pong_time_ns.unwrap() - self.ping_time_ns) / 1000_000); - Ok(SessionData::None) + Ok(SessionData::Continue) }, PACKET_GET_PEERS => Ok(SessionData::None), //TODO; PACKET_PEERS => Ok(SessionData::None), @@ -346,7 +353,7 @@ impl Session { i += 1; if i == self.info.capabilities.len() { debug!(target: "network", "Unknown packet: {:?}", packet_id); - return Ok(SessionData::None) + return Ok(SessionData::Continue) } } @@ -357,12 +364,12 @@ impl Session { }, _ => { debug!(target: "network", "Unknown packet: {:?}", packet_id); - Ok(SessionData::None) + Ok(SessionData::Continue) } } } - fn write_hello(&mut self, host: &HostInfo) -> Result<(), UtilError> { + fn write_hello(&mut self, io: &IoContext, host: &HostInfo) -> Result<(), UtilError> where Message: Send + Sync + Clone { let mut rlp = RlpStream::new(); rlp.append_raw(&[PACKET_HELLO as u8], 0); rlp.begin_list(5) @@ -371,10 +378,11 @@ impl Session { .append(&host.capabilities) .append(&host.local_endpoint.address.port()) .append(host.id()); - self.send(rlp) + self.send(io, rlp) } - fn read_hello(&mut self, rlp: &UntrustedRlp, host: &HostInfo) -> Result<(), UtilError> { + fn read_hello(&mut self, io: &IoContext, rlp: &UntrustedRlp, host: &HostInfo) -> Result<(), UtilError> + where Message: Send + Sync + Clone { let protocol = try!(rlp.val_at::(0)); let client_version = try!(rlp.val_at::(1)); let peer_caps = try!(rlp.val_at::>(2)); @@ -417,36 +425,36 @@ impl Session { self.info.capabilities = caps; if self.info.capabilities.is_empty() { trace!(target: "network", "No common capabilities with peer."); - return Err(From::from(self.disconnect(DisconnectReason::UselessPeer))); + return Err(From::from(self.disconnect(io, DisconnectReason::UselessPeer))); } if protocol != host.protocol_version { trace!(target: "network", "Peer protocol version mismatch: {}", protocol); - return Err(From::from(self.disconnect(DisconnectReason::UselessPeer))); + return Err(From::from(self.disconnect(io, DisconnectReason::UselessPeer))); } self.had_hello = true; Ok(()) } /// Senf ping packet - pub fn send_ping(&mut self) -> Result<(), UtilError> { - try!(self.send(try!(Session::prepare(PACKET_PING)))); + pub fn send_ping(&mut self, io: &IoContext) -> Result<(), UtilError> where Message: Send + Sync + Clone { + try!(self.send(io, try!(Session::prepare(PACKET_PING)))); self.ping_time_ns = time::precise_time_ns(); self.pong_time_ns = None; Ok(()) } - fn send_pong(&mut self) -> Result<(), UtilError> { - self.send(try!(Session::prepare(PACKET_PONG))) + fn send_pong(&mut self, io: &IoContext) -> Result<(), UtilError> where Message: Send + Sync + Clone { + self.send(io, try!(Session::prepare(PACKET_PONG))) } /// Disconnect this session - pub fn disconnect(&mut self, reason: DisconnectReason) -> NetworkError { + pub fn disconnect(&mut self, io: &IoContext, reason: DisconnectReason) -> NetworkError where Message: Send + Sync + Clone { if let State::Session(_) = self.state { let mut rlp = RlpStream::new(); rlp.append(&(PACKET_DISCONNECT as u32)); rlp.begin_list(1); rlp.append(&(reason as u32)); - self.send(rlp).ok(); + self.send(io, rlp).ok(); } NetworkError::Disconnect(reason) } @@ -458,13 +466,13 @@ impl Session { Ok(rlp) } - fn send(&mut self, rlp: RlpStream) -> Result<(), UtilError> { + fn send(&mut self, io: &IoContext, rlp: RlpStream) -> Result<(), UtilError> where Message: Send + Sync + Clone { match self.state { State::Handshake(_) => { warn!(target:"network", "Unexpected send request"); }, State::Session(ref mut s) => { - try!(s.send_packet(&rlp.out())) + try!(s.send_packet(io, &rlp.out())) }, } Ok(()) diff --git a/util/src/network/stats.rs b/util/src/network/stats.rs index 30e751a81..cc3b845da 100644 --- a/util/src/network/stats.rs +++ b/util/src/network/stats.rs @@ -65,7 +65,7 @@ impl NetworkStats { self.sessions.load(Ordering::Relaxed) } - #[cfg(test)] + /// Create a new empty instance. pub fn new() -> NetworkStats { NetworkStats { recv: AtomicUsize::new(0), diff --git a/util/src/network/tests.rs b/util/src/network/tests.rs index b43da9320..861edc144 100644 --- a/util/src/network/tests.rs +++ b/util/src/network/tests.rs @@ -97,7 +97,8 @@ impl NetworkProtocolHandler for TestProtocol { #[test] fn net_service() { - let mut service = NetworkService::::start(NetworkConfiguration::new_local()).expect("Error creating network service"); + let service = NetworkService::::new(NetworkConfiguration::new_local()).expect("Error creating network service"); + service.start().unwrap(); service.register_protocol(Arc::new(TestProtocol::new(false)), "myproto", &[1u8]).unwrap(); } @@ -108,12 +109,14 @@ fn net_connect() { let mut config1 = NetworkConfiguration::new_local(); config1.use_secret = Some(key1.secret().clone()); config1.boot_nodes = vec![ ]; - let mut service1 = NetworkService::::start(config1).unwrap(); + let mut service1 = NetworkService::::new(config1).unwrap(); + service1.start().unwrap(); let handler1 = TestProtocol::register(&mut service1, false); let mut config2 = NetworkConfiguration::new_local(); - info!("net_connect: local URL: {}", service1.local_url()); - config2.boot_nodes = vec![ service1.local_url() ]; - let mut service2 = NetworkService::::start(config2).unwrap(); + info!("net_connect: local URL: {}", service1.local_url().unwrap()); + config2.boot_nodes = vec![ service1.local_url().unwrap() ]; + let mut service2 = NetworkService::::new(config2).unwrap(); + service2.start().unwrap(); let handler2 = TestProtocol::register(&mut service2, false); while !handler1.got_packet() && !handler2.got_packet() && (service1.stats().sessions() == 0 || service2.stats().sessions() == 0) { thread::sleep(Duration::from_millis(50)); @@ -122,17 +125,28 @@ fn net_connect() { assert!(service2.stats().sessions() >= 1); } +#[test] +fn net_start_stop() { + let config = NetworkConfiguration::new_local(); + let service = NetworkService::::new(config).unwrap(); + service.start().unwrap(); + service.stop().unwrap(); + service.start().unwrap(); +} + #[test] fn net_disconnect() { let key1 = KeyPair::create().unwrap(); let mut config1 = NetworkConfiguration::new_local(); config1.use_secret = Some(key1.secret().clone()); config1.boot_nodes = vec![ ]; - let mut service1 = NetworkService::::start(config1).unwrap(); + let mut service1 = NetworkService::::new(config1).unwrap(); + service1.start().unwrap(); let handler1 = TestProtocol::register(&mut service1, false); let mut config2 = NetworkConfiguration::new_local(); - config2.boot_nodes = vec![ service1.local_url() ]; - let mut service2 = NetworkService::::start(config2).unwrap(); + config2.boot_nodes = vec![ service1.local_url().unwrap() ]; + let mut service2 = NetworkService::::new(config2).unwrap(); + service2.start().unwrap(); let handler2 = TestProtocol::register(&mut service2, true); while !(handler1.got_disconnect() && handler2.got_disconnect()) { thread::sleep(Duration::from_millis(50)); @@ -144,7 +158,8 @@ fn net_disconnect() { #[test] fn net_timeout() { let config = NetworkConfiguration::new_local(); - let mut service = NetworkService::::start(config).unwrap(); + let mut service = NetworkService::::new(config).unwrap(); + service.start().unwrap(); let handler = TestProtocol::register(&mut service, false); while !handler.got_timeout() { thread::sleep(Duration::from_millis(50)); diff --git a/util/src/overlaydb.rs b/util/src/overlaydb.rs index ce4e894c8..b1ea44dac 100644 --- a/util/src/overlaydb.rs +++ b/util/src/overlaydb.rs @@ -92,7 +92,7 @@ impl OverlayDB { /// /// Returns either an error or the number of items changed in the backing database. /// - /// Will return an error if the number of `kill()`s ever exceeds the number of + /// Will return an error if the number of `remove()`s ever exceeds the number of /// `insert()`s for any key. This will leave the database in an undeterminate /// state. Don't ever let it happen. /// @@ -104,15 +104,15 @@ impl OverlayDB { /// fn main() { /// let mut m = OverlayDB::new_temp(); /// let key = m.insert(b"foo"); // insert item. - /// assert!(m.exists(&key)); // key exists (in memory). + /// assert!(m.contains(&key)); // key exists (in memory). /// assert_eq!(m.commit().unwrap(), 1); // 1 item changed. - /// assert!(m.exists(&key)); // key still exists (in backing). - /// m.kill(&key); // delete item. - /// assert!(!m.exists(&key)); // key "doesn't exist" (though still does in backing). - /// m.kill(&key); // oh dear... more kills than inserts for the key... + /// assert!(m.contains(&key)); // key still exists (in backing). + /// m.remove(&key); // delete item. + /// assert!(!m.contains(&key)); // key "doesn't exist" (though still does in backing). + /// m.remove(&key); // oh dear... more removes than inserts for the key... /// //m.commit().unwrap(); // this commit/unwrap would cause a panic. - /// m.revert(); // revert both kills. - /// assert!(m.exists(&key)); // key now still exists. + /// m.revert(); // revert both removes. + /// assert!(m.contains(&key)); // key now still exists. /// } /// ``` pub fn commit(&mut self) -> Result { @@ -224,7 +224,7 @@ impl HashDB for OverlayDB { } ret } - fn lookup(&self, key: &H256) -> Option<&[u8]> { + fn get(&self, key: &H256) -> Option<&[u8]> { // return ok if positive; if negative, check backing - might be enough references there to make // it positive again. let k = self.overlay.raw(key); @@ -249,7 +249,7 @@ impl HashDB for OverlayDB { } } } - fn exists(&self, key: &H256) -> bool { + fn contains(&self, key: &H256) -> bool { // return ok if positive; if negative, check backing - might be enough references there to make // it positive again. let k = self.overlay.raw(key); @@ -271,7 +271,7 @@ impl HashDB for OverlayDB { } fn insert(&mut self, value: &[u8]) -> H256 { self.overlay.insert(value) } fn emplace(&mut self, key: H256, value: Bytes) { self.overlay.emplace(key, value); } - fn kill(&mut self, key: &H256) { self.overlay.kill(key); } + fn remove(&mut self, key: &H256) { self.overlay.remove(key); } } #[test] diff --git a/util/src/path.rs b/util/src/path.rs index 899650149..023269a69 100644 --- a/util/src/path.rs +++ b/util/src/path.rs @@ -15,6 +15,7 @@ // along with Parity. If not, see . //! Path utilities +use std::path::Path; /// Default ethereum paths pub mod ethereum { @@ -62,3 +63,21 @@ pub mod ethereum { pth } } + +/// Restricts the permissions of given path only to the owner. +#[cfg(not(windows))] +pub fn restrict_permissions_owner(file_path: &Path) -> Result<(), i32> { + let cstr = ::std::ffi::CString::new(file_path.to_str().unwrap()).unwrap(); + match unsafe { ::libc::chmod(cstr.as_ptr(), ::libc::S_IWUSR | ::libc::S_IRUSR) } { + 0 => Ok(()), + x => Err(x), + } +} + +/// Restricts the permissions of given path only to the owner. +#[cfg(windows)] +pub fn restrict_permissions_owner(_file_path: &Path) -> Result<(), i32> { + //TODO: implement me + Ok(()) +} + diff --git a/util/src/rlp/bytes.rs b/util/src/rlp/bytes.rs index 1145ba27e..d252af828 100644 --- a/util/src/rlp/bytes.rs +++ b/util/src/rlp/bytes.rs @@ -258,14 +258,7 @@ impl FromBytes for T where T: FixedHash { Ordering::Equal => () }; - unsafe { - use std::{mem, ptr}; - - let mut res: T = mem::uninitialized(); - ptr::copy(bytes.as_ptr(), res.as_slice_mut().as_mut_ptr(), T::len()); - - Ok(res) - } + Ok(T::from_slice(bytes)) } } diff --git a/util/src/rlp/tests.rs b/util/src/rlp/tests.rs index a92dd5c4a..3df2f2d97 100644 --- a/util/src/rlp/tests.rs +++ b/util/src/rlp/tests.rs @@ -429,3 +429,10 @@ fn test_rlp_nested_empty_list_encode() { assert_eq!(stream.drain()[..], [0xc2u8, 0xc0u8, 40u8][..]); } +#[test] +fn test_rlp_list_length_overflow() { + let data: Vec = vec![0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00]; + let rlp = UntrustedRlp::new(&data); + let as_val: Result = rlp.val_at(0); + assert_eq!(Err(DecoderError::RlpIsTooShort), as_val); +} diff --git a/util/src/rlp/untrusted_rlp.rs b/util/src/rlp/untrusted_rlp.rs index 6109a643b..8e9b6d70e 100644 --- a/util/src/rlp/untrusted_rlp.rs +++ b/util/src/rlp/untrusted_rlp.rs @@ -334,9 +334,9 @@ impl<'a> BasicDecoder<'a> { /// Return first item info. fn payload_info(bytes: &[u8]) -> Result { let item = try!(PayloadInfo::from(bytes)); - match item.header_len + item.value_len <= bytes.len() { - true => Ok(item), - false => Err(DecoderError::RlpIsTooShort), + match item.header_len.checked_add(item.value_len) { + Some(x) if x <= bytes.len() => Ok(item), + _ => Err(DecoderError::RlpIsTooShort), } } } diff --git a/util/src/timer.rs b/util/src/timer.rs new file mode 100644 index 000000000..5d95ff7de --- /dev/null +++ b/util/src/timer.rs @@ -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 . + +//! Performance timer with logging +use time::precise_time_ns; + +/// Performance timer with logging. Starts measuring time in the constructor, prints +/// elapsed time in the destructor or when `stop` is called. +pub struct PerfTimer { + name: &'static str, + start: u64, + stopped: bool, +} + +impl PerfTimer { + /// Create an instance with given name. + pub fn new(name: &'static str) -> PerfTimer { + PerfTimer { + name: name, + start: precise_time_ns(), + stopped: false, + } + } + + /// Stop the timer and print elapsed time on trace level with `perf` target. + pub fn stop(&mut self) { + if !self.stopped { + trace!(target: "perf", "{}: {:.2}ms", self.name, (precise_time_ns() - self.start) as f32 / 1000_000.0); + self.stopped = true; + } + } +} + +impl Drop for PerfTimer { + fn drop(&mut self) { + self.stop() + } +} diff --git a/util/src/trie/triedb.rs b/util/src/trie/triedb.rs index fccd5da90..9cd3a8c41 100644 --- a/util/src/trie/triedb.rs +++ b/util/src/trie/triedb.rs @@ -133,7 +133,7 @@ impl<'db> TrieDB<'db> { /// Get the data of the root node. fn root_data(&self) -> &[u8] { - self.db.lookup(&self.root).expect("Trie root not found!") + self.db.get(&self.root).expect("Trie root not found!") } /// Get the root node as a `Node`. @@ -184,7 +184,7 @@ impl<'db> TrieDB<'db> { /// Return optional data for a key given as a `NibbleSlice`. Returns `None` if no data exists. fn do_lookup<'a, 'key>(&'a self, key: &NibbleSlice<'key>) -> Option<&'a [u8]> where 'a: 'key { - let root_rlp = self.db.lookup(&self.root).expect("Trie root not found!"); + let root_rlp = self.db.get(&self.root).expect("Trie root not found!"); self.get_from_node(&root_rlp, key) } @@ -213,7 +213,7 @@ impl<'db> TrieDB<'db> { // check if its sha3 + len let r = Rlp::new(node); match r.is_data() && r.size() == 32 { - true => self.db.lookup(&r.as_val::()).unwrap_or_else(|| panic!("Not found! {:?}", r.as_val::())), + true => self.db.get(&r.as_val::()).unwrap_or_else(|| panic!("Not found! {:?}", r.as_val::())), false => node } } @@ -349,7 +349,7 @@ impl<'db> Trie for TrieDB<'db> { impl<'db> fmt::Debug for TrieDB<'db> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(writeln!(f, "c={:?} [", self.hash_count)); - let root_rlp = self.db.lookup(&self.root).expect("Trie root not found!"); + let root_rlp = self.db.get(&self.root).expect("Trie root not found!"); try!(self.fmt_all(Node::decoded(root_rlp), f, 0)); writeln!(f, "]") } diff --git a/util/src/trie/triedbmut.rs b/util/src/trie/triedbmut.rs index afabd6437..65d5bbd2b 100644 --- a/util/src/trie/triedbmut.rs +++ b/util/src/trie/triedbmut.rs @@ -87,7 +87,7 @@ impl<'db> TrieDBMut<'db> { /// Create a new trie with the backing database `db` and `root`. /// Returns an error if `root` does not exist. pub fn from_existing(db: &'db mut HashDB, root: &'db mut H256) -> Result { - if !db.exists(root) { + if !db.contains(root) { Err(TrieError::InvalidStateRoot) } else { Ok(TrieDBMut { @@ -143,7 +143,7 @@ impl<'db> TrieDBMut<'db> { /// Set the trie to a new root node's RLP, inserting the new RLP into the backing database /// and removing the old. fn set_root_rlp(&mut self, root_data: &[u8]) { - self.db.kill(&self.root); + self.db.remove(&self.root); *self.root = self.db.insert(root_data); self.hash_count += 1; trace!("set_root_rlp {:?} {:?}", root_data.pretty(), self.root); @@ -174,7 +174,7 @@ impl<'db> TrieDBMut<'db> { /// Get the root node's RLP. fn root_node(&self) -> Node { - Node::decoded(self.db.lookup(&self.root).expect("Trie root not found!")) + Node::decoded(self.db.get(&self.root).expect("Trie root not found!")) } /// Get the root node as a `Node`. @@ -225,7 +225,7 @@ impl<'db> TrieDBMut<'db> { /// Return optional data for a key given as a `NibbleSlice`. Returns `None` if no data exists. fn do_lookup<'a, 'key>(&'a self, key: &NibbleSlice<'key>) -> Option<&'a [u8]> where 'a: 'key { - let root_rlp = self.db.lookup(&self.root).expect("Trie root not found!"); + let root_rlp = self.db.get(&self.root).expect("Trie root not found!"); self.get_from_node(&root_rlp, key) } @@ -254,7 +254,7 @@ impl<'db> TrieDBMut<'db> { // check if its sha3 + len let r = Rlp::new(node); match r.is_data() && r.size() == 32 { - true => self.db.lookup(&r.as_val::()).expect("Not found!"), + true => self.db.get(&r.as_val::()).expect("Not found!"), false => node } } @@ -266,7 +266,7 @@ impl<'db> TrieDBMut<'db> { trace!("ADD: {:?} {:?}", key, value.pretty()); // determine what the new root is, insert new nodes and remove old as necessary. let mut todo: Journal = Journal::new(); - let root_rlp = self.augmented(self.db.lookup(&self.root).expect("Trie root not found!"), key, value, &mut todo); + let root_rlp = self.augmented(self.db.get(&self.root).expect("Trie root not found!"), key, value, &mut todo); self.apply(todo); self.set_root_rlp(&root_rlp); trace!("/"); @@ -279,7 +279,7 @@ impl<'db> TrieDBMut<'db> { trace!("DELETE: {:?}", key); // determine what the new root is, insert new nodes and remove old as necessary. let mut todo: Journal = Journal::new(); - match self.cleared_from_slice(self.db.lookup(&self.root).expect("Trie root not found!"), key, &mut todo) { + match self.cleared_from_slice(self.db.get(&self.root).expect("Trie root not found!"), key, &mut todo) { Some(root_rlp) => { self.apply(todo); self.set_root_rlp(&root_rlp); @@ -335,7 +335,7 @@ impl<'db> TrieDBMut<'db> { } else if rlp.is_data() && rlp.size() == 32 { let h = rlp.as_val(); - let r = self.db.lookup(&h).unwrap_or_else(||{ + let r = self.db.get(&h).unwrap_or_else(||{ println!("Node not found! rlp={:?}, node_hash={:?}", rlp.as_raw().pretty(), h); println!("Journal: {:?}", journal); panic!(); @@ -670,7 +670,7 @@ impl<'db> TrieMut for TrieDBMut<'db> { impl<'db> fmt::Debug for TrieDBMut<'db> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { try!(writeln!(f, "c={:?} [", self.hash_count)); - let root_rlp = self.db.lookup(&self.root).expect("Trie root not found!"); + let root_rlp = self.db.get(&self.root).expect("Trie root not found!"); try!(self.fmt_all(Node::decoded(root_rlp), f, 0)); writeln!(f, "]") }