From a67810615ada4919081f98bebed6ab051dc867a9 Mon Sep 17 00:00:00 2001 From: Michael Shaw Date: Tue, 21 Feb 2023 14:08:07 -0500 Subject: [PATCH] conflicts resolved no testing update tests, helper methods, etc for changed interfaces linted and some tests updated... statediff tests failing on filesystem call locally undo changes to go.mod from rebase changed ref and repo to try old stack-orch with miner.etherbase arg turn off new tests yml for old tests with hack for old stack-orchestrator --- .github/workflows/checks.yml | 15 + .github/workflows/manual_binary_publish.yaml | 21 + .github/workflows/manual_publish.yaml | 21 + .github/workflows/old_tests.yml | 145 + .github/workflows/on-pr.yml | 7 + .github/workflows/publish.yaml | 50 + .github/workflows/tests.yml | 143 + .gitignore | 15 + .gitmodules | 2 +- Dockerfile.amd64 | 7 + Jenkinsfile | 50 + Makefile | 33 +- cmd/geth/config.go | 116 +- cmd/geth/main.go | 26 + cmd/utils/flags.go | 139 + consensus/ethash/consensus.go | 9 +- core/blockchain.go | 40 +- core/rawdb/accessors_chain.go | 28 + core/types/receipt.go | 4 + core/types/transaction.go | 10 +- docker-compose-cicd.yml | 54 + docker-compose.yml | 27 + eth/backend.go | 1 + eth/ethconfig/config.go | 4 + eth/protocols/snap/sync.go | 1 + go.mod | 56 +- go.sum | 432 ++- metrics/prometheus/collector.go | 3 + metrics/prometheus/collector_test.go | 3 + metrics/timer.go | 25 +- mobile/android_test.go | 262 ++ params/config.go | 15 +- params/version.go | 8 +- rpc/http.go | 2 +- scripts/run_unit_test.sh | 25 + statediff/README.md | 320 ++ statediff/api.go | 213 ++ statediff/builder.go | 934 ++++++ statediff/builder_test.go | 2600 +++++++++++++++++ statediff/config.go | 89 + statediff/docs/KnownGaps.md | 17 + statediff/docs/README.md | 3 + statediff/docs/database.md | 21 + statediff/docs/diagrams/KnownGapsProcess.png | Bin 0 -> 33340 bytes statediff/helpers.go | 63 + statediff/indexer/constructor.go | 81 + statediff/indexer/database/dump/batch_tx.go | 97 + statediff/indexer/database/dump/config.go | 79 + statediff/indexer/database/dump/indexer.go | 535 ++++ statediff/indexer/database/file/batch_tx.go | 29 + statediff/indexer/database/file/config.go | 84 + .../database/file/csv_indexer_legacy_test.go | 118 + .../indexer/database/file/csv_indexer_test.go | 255 ++ statediff/indexer/database/file/csv_writer.go | 457 +++ statediff/indexer/database/file/helpers.go | 60 + statediff/indexer/database/file/indexer.go | 573 ++++ statediff/indexer/database/file/interfaces.go | 60 + .../file/mainnet_tests/indexer_test.go | 112 + .../database/file/sql_indexer_legacy_test.go | 101 + .../indexer/database/file/sql_indexer_test.go | 253 ++ statediff/indexer/database/file/sql_writer.go | 431 +++ .../indexer/database/file/types/schema.go | 186 ++ .../indexer/database/file/types/table.go | 104 + statediff/indexer/database/metrics/metrics.go | 263 ++ statediff/indexer/database/sql/batch_tx.go | 144 + statediff/indexer/database/sql/indexer.go | 671 +++++ .../database/sql/indexer_shared_test.go | 28 + statediff/indexer/database/sql/interfaces.go | 77 + statediff/indexer/database/sql/lazy_tx.go | 55 + .../sql/mainnet_tests/indexer_test.go | 95 + .../database/sql/pgx_indexer_legacy_test.go | 52 + .../indexer/database/sql/pgx_indexer_test.go | 227 ++ .../indexer/database/sql/postgres/config.go | 102 + .../indexer/database/sql/postgres/database.go | 123 + .../indexer/database/sql/postgres/errors.go | 38 + .../database/sql/postgres/log_adapter.go | 61 + .../indexer/database/sql/postgres/pgx.go | 241 ++ .../indexer/database/sql/postgres/pgx_test.go | 121 + .../sql/postgres/postgres_suite_test.go | 33 + .../indexer/database/sql/postgres/sqlx.go | 188 ++ .../database/sql/postgres/sqlx_test.go | 119 + .../database/sql/postgres/test_helpers.go | 44 + .../database/sql/sqlx_indexer_legacy_test.go | 52 + .../indexer/database/sql/sqlx_indexer_test.go | 227 ++ statediff/indexer/database/sql/writer.go | 203 ++ statediff/indexer/interfaces/interfaces.go | 55 + .../ipld/eip2930_test_data/eth-block-12252078 | Bin 0 -> 50536 bytes .../ipld/eip2930_test_data/eth-block-12365585 | Bin 0 -> 60035 bytes .../ipld/eip2930_test_data/eth-block-12365586 | Bin 0 -> 38164 bytes .../eip2930_test_data/eth-receipts-12252078 | Bin 0 -> 132368 bytes .../eip2930_test_data/eth-receipts-12365585 | Bin 0 -> 127320 bytes .../eip2930_test_data/eth-receipts-12365586 | Bin 0 -> 111330 bytes statediff/indexer/ipld/eth_account.go | 175 ++ statediff/indexer/ipld/eth_account_test.go | 295 ++ statediff/indexer/ipld/eth_header.go | 293 ++ statediff/indexer/ipld/eth_header_test.go | 583 ++++ statediff/indexer/ipld/eth_log.go | 158 + statediff/indexer/ipld/eth_log_trie.go | 144 + statediff/indexer/ipld/eth_parser.go | 302 ++ statediff/indexer/ipld/eth_parser_test.go | 108 + statediff/indexer/ipld/eth_receipt.go | 205 ++ statediff/indexer/ipld/eth_receipt_trie.go | 174 ++ statediff/indexer/ipld/eth_state.go | 126 + statediff/indexer/ipld/eth_state_test.go | 321 ++ statediff/indexer/ipld/eth_storage.go | 112 + statediff/indexer/ipld/eth_storage_test.go | 132 + statediff/indexer/ipld/eth_tx.go | 236 ++ statediff/indexer/ipld/eth_tx_test.go | 391 +++ statediff/indexer/ipld/eth_tx_trie.go | 146 + statediff/indexer/ipld/eth_tx_trie_test.go | 503 ++++ statediff/indexer/ipld/shared.go | 212 ++ .../error-tx-eth-block-body-json-999999 | 1 + .../ipld/test_data/eth-block-body-json-0 | 1 + .../test_data/eth-block-body-json-4139497 | 1 + .../ipld/test_data/eth-block-body-json-997522 | 1 + .../ipld/test_data/eth-block-body-json-999998 | 1 + .../ipld/test_data/eth-block-body-json-999999 | 1 + .../ipld/test_data/eth-block-body-rlp-997522 | Bin 0 -> 1728 bytes .../ipld/test_data/eth-block-body-rlp-999999 | Bin 0 -> 1768 bytes .../test_data/eth-block-header-rlp-999996 | Bin 0 -> 540 bytes .../test_data/eth-block-header-rlp-999997 | Bin 0 -> 539 bytes .../test_data/eth-block-header-rlp-999999 | Bin 0 -> 539 bytes .../ipld/test_data/eth-state-trie-rlp-0e8b34 | Bin 0 -> 115 bytes .../ipld/test_data/eth-state-trie-rlp-56864f | 1 + .../ipld/test_data/eth-state-trie-rlp-6fc2d7 | 5 + .../ipld/test_data/eth-state-trie-rlp-727994 | Bin 0 -> 117 bytes .../ipld/test_data/eth-state-trie-rlp-c9070d | Bin 0 -> 116 bytes .../ipld/test_data/eth-state-trie-rlp-d5be90 | Bin 0 -> 500 bytes .../ipld/test_data/eth-state-trie-rlp-d7f897 | Bin 0 -> 532 bytes .../ipld/test_data/eth-state-trie-rlp-eb2f5f | Bin 0 -> 37 bytes .../test_data/eth-storage-trie-rlp-000dd0 | Bin 0 -> 83 bytes .../test_data/eth-storage-trie-rlp-113049 | 1 + .../test_data/eth-storage-trie-rlp-9d1860 | 1 + .../test_data/eth-storage-trie-rlp-ffbcad | Bin 0 -> 44 bytes .../test_data/eth-storage-trie-rlp-ffc25c | 1 + .../ipld/test_data/eth-uncle-json-997522-0 | 1 + .../ipld/test_data/eth-uncle-json-997522-1 | 1 + statediff/indexer/ipld/test_data/tx_data | Bin 0 -> 607 bytes statediff/indexer/ipld/trie_node.go | 457 +++ .../indexer/mainnet_data/block_12579670.rlp | Bin 0 -> 4454 bytes .../indexer/mainnet_data/block_12600011.rlp | Bin 0 -> 5883 bytes .../indexer/mainnet_data/block_12619985.rlp | Bin 0 -> 4041 bytes .../indexer/mainnet_data/block_12625121.rlp | Bin 0 -> 16079 bytes .../indexer/mainnet_data/block_12655432.rlp | Bin 0 -> 4044 bytes .../indexer/mainnet_data/block_12914664.rlp | Bin 0 -> 37150 bytes .../mainnet_data/receipts_12579670.rlp | Bin 0 -> 849935 bytes .../mainnet_data/receipts_12600011.rlp | Bin 0 -> 690821 bytes .../mainnet_data/receipts_12619985.rlp | Bin 0 -> 571436 bytes .../mainnet_data/receipts_12625121.rlp | Bin 0 -> 706015 bytes .../mainnet_data/receipts_12655432.rlp | Bin 0 -> 850429 bytes .../mainnet_data/receipts_12914664.rlp | Bin 0 -> 89259 bytes statediff/indexer/mocks/test_data.go | 608 ++++ statediff/indexer/models/batch.go | 126 + statediff/indexer/models/models.go | 169 ++ statediff/indexer/node/node.go | 25 + statediff/indexer/shared/constants.go | 23 + statediff/indexer/shared/db_kind.go | 46 + statediff/indexer/shared/functions.go | 57 + statediff/indexer/shared/reward.go | 76 + statediff/indexer/test/test.go | 1274 ++++++++ statediff/indexer/test/test_init.go | 248 ++ statediff/indexer/test/test_legacy.go | 96 + statediff/indexer/test/test_mainnet.go | 53 + .../indexer/test/test_watched_addresses.go | 258 ++ .../test_helpers/mainnet_test_helpers.go | 248 ++ .../indexer/test_helpers/test_helpers.go | 131 + statediff/mainnet_tests/block0_rlp | Bin 0 -> 540 bytes statediff/mainnet_tests/block1_rlp | Bin 0 -> 537 bytes statediff/mainnet_tests/block2_rlp | Bin 0 -> 544 bytes statediff/mainnet_tests/block3_rlp | Bin 0 -> 1079 bytes statediff/mainnet_tests/builder_test.go | 692 +++++ statediff/metrics.go | 108 + statediff/metrics_helpers.go | 89 + statediff/payload.go | 57 + statediff/service.go | 1067 +++++++ statediff/service_test.go | 439 +++ statediff/test_helpers/constant.go | 33 + statediff/test_helpers/helpers.go | 142 + statediff/test_helpers/mocks/backend.go | 260 ++ statediff/test_helpers/mocks/blockchain.go | 157 + statediff/test_helpers/mocks/builder.go | 67 + statediff/test_helpers/mocks/indexer.go | 70 + statediff/test_helpers/mocks/service.go | 449 +++ statediff/test_helpers/mocks/service_test.go | 540 ++++ statediff/test_helpers/test_data.go | 73 + statediff/trie_helpers/helpers.go | 129 + statediff/types/types.go | 120 + .../concurrent_iterator/README.md | 57 +- trie/concurrent_iterator/fixture/chaindata.go | 27 + .../fixture/chaindata/.gitignore | 6 + .../fixture/chaindata/000002.ldb | Bin 0 -> 5765300 bytes .../chaindata/ancient/bodies.0000.cdat | Bin 0 -> 57296 bytes .../fixture/chaindata/ancient/bodies.cidx | Bin 0 -> 67206 bytes .../fixture/chaindata/ancient/diffs.0000.rdat | Bin 0 -> 33408 bytes .../fixture/chaindata/ancient/diffs.ridx | Bin 0 -> 67206 bytes .../chaindata/ancient/hashes.0000.rdat | Bin 0 -> 358400 bytes .../fixture/chaindata/ancient/hashes.ridx | Bin 0 -> 67206 bytes .../chaindata/ancient/headers.0000.cdat | Bin 0 -> 3371499 bytes .../fixture/chaindata/ancient/headers.cidx | Bin 0 -> 67206 bytes .../chaindata/ancient/receipts.0000.cdat | Bin 0 -> 33943 bytes .../fixture/chaindata/ancient/receipts.cidx | Bin 0 -> 67206 bytes trie/concurrent_iterator/fixture/paths.go | 616 ++++ trie/concurrent_iterator/iterator.go | 164 ++ trie/concurrent_iterator/iterator_test.go | 101 + trie/concurrent_iterator/tracker/tracker.go | 243 ++ trie/concurrent_iterator/util.go | 50 + trie/encoding.go | 14 +- trie/encoding_test.go | 6 +- trie/iterator.go | 6 +- trie/sync.go | 10 +- 210 files changed, 27141 insertions(+), 72 deletions(-) create mode 100644 .github/workflows/checks.yml create mode 100644 .github/workflows/manual_binary_publish.yaml create mode 100644 .github/workflows/manual_publish.yaml create mode 100644 .github/workflows/old_tests.yml create mode 100644 .github/workflows/on-pr.yml create mode 100644 .github/workflows/publish.yaml create mode 100644 .github/workflows/tests.yml create mode 100644 Dockerfile.amd64 create mode 100644 Jenkinsfile create mode 100644 docker-compose-cicd.yml create mode 100644 docker-compose.yml create mode 100644 mobile/android_test.go create mode 100755 scripts/run_unit_test.sh create mode 100644 statediff/README.md create mode 100644 statediff/api.go create mode 100644 statediff/builder.go create mode 100644 statediff/builder_test.go create mode 100644 statediff/config.go create mode 100644 statediff/docs/KnownGaps.md create mode 100644 statediff/docs/README.md create mode 100644 statediff/docs/database.md create mode 100644 statediff/docs/diagrams/KnownGapsProcess.png create mode 100644 statediff/helpers.go create mode 100644 statediff/indexer/constructor.go create mode 100644 statediff/indexer/database/dump/batch_tx.go create mode 100644 statediff/indexer/database/dump/config.go create mode 100644 statediff/indexer/database/dump/indexer.go create mode 100644 statediff/indexer/database/file/batch_tx.go create mode 100644 statediff/indexer/database/file/config.go create mode 100644 statediff/indexer/database/file/csv_indexer_legacy_test.go create mode 100644 statediff/indexer/database/file/csv_indexer_test.go create mode 100644 statediff/indexer/database/file/csv_writer.go create mode 100644 statediff/indexer/database/file/helpers.go create mode 100644 statediff/indexer/database/file/indexer.go create mode 100644 statediff/indexer/database/file/interfaces.go create mode 100644 statediff/indexer/database/file/mainnet_tests/indexer_test.go create mode 100644 statediff/indexer/database/file/sql_indexer_legacy_test.go create mode 100644 statediff/indexer/database/file/sql_indexer_test.go create mode 100644 statediff/indexer/database/file/sql_writer.go create mode 100644 statediff/indexer/database/file/types/schema.go create mode 100644 statediff/indexer/database/file/types/table.go create mode 100644 statediff/indexer/database/metrics/metrics.go create mode 100644 statediff/indexer/database/sql/batch_tx.go create mode 100644 statediff/indexer/database/sql/indexer.go create mode 100644 statediff/indexer/database/sql/indexer_shared_test.go create mode 100644 statediff/indexer/database/sql/interfaces.go create mode 100644 statediff/indexer/database/sql/lazy_tx.go create mode 100644 statediff/indexer/database/sql/mainnet_tests/indexer_test.go create mode 100644 statediff/indexer/database/sql/pgx_indexer_legacy_test.go create mode 100644 statediff/indexer/database/sql/pgx_indexer_test.go create mode 100644 statediff/indexer/database/sql/postgres/config.go create mode 100644 statediff/indexer/database/sql/postgres/database.go create mode 100644 statediff/indexer/database/sql/postgres/errors.go create mode 100644 statediff/indexer/database/sql/postgres/log_adapter.go create mode 100644 statediff/indexer/database/sql/postgres/pgx.go create mode 100644 statediff/indexer/database/sql/postgres/pgx_test.go create mode 100644 statediff/indexer/database/sql/postgres/postgres_suite_test.go create mode 100644 statediff/indexer/database/sql/postgres/sqlx.go create mode 100644 statediff/indexer/database/sql/postgres/sqlx_test.go create mode 100644 statediff/indexer/database/sql/postgres/test_helpers.go create mode 100644 statediff/indexer/database/sql/sqlx_indexer_legacy_test.go create mode 100644 statediff/indexer/database/sql/sqlx_indexer_test.go create mode 100644 statediff/indexer/database/sql/writer.go create mode 100644 statediff/indexer/interfaces/interfaces.go create mode 100644 statediff/indexer/ipld/eip2930_test_data/eth-block-12252078 create mode 100644 statediff/indexer/ipld/eip2930_test_data/eth-block-12365585 create mode 100644 statediff/indexer/ipld/eip2930_test_data/eth-block-12365586 create mode 100644 statediff/indexer/ipld/eip2930_test_data/eth-receipts-12252078 create mode 100644 statediff/indexer/ipld/eip2930_test_data/eth-receipts-12365585 create mode 100644 statediff/indexer/ipld/eip2930_test_data/eth-receipts-12365586 create mode 100644 statediff/indexer/ipld/eth_account.go create mode 100644 statediff/indexer/ipld/eth_account_test.go create mode 100644 statediff/indexer/ipld/eth_header.go create mode 100644 statediff/indexer/ipld/eth_header_test.go create mode 100644 statediff/indexer/ipld/eth_log.go create mode 100644 statediff/indexer/ipld/eth_log_trie.go create mode 100644 statediff/indexer/ipld/eth_parser.go create mode 100644 statediff/indexer/ipld/eth_parser_test.go create mode 100644 statediff/indexer/ipld/eth_receipt.go create mode 100644 statediff/indexer/ipld/eth_receipt_trie.go create mode 100644 statediff/indexer/ipld/eth_state.go create mode 100644 statediff/indexer/ipld/eth_state_test.go create mode 100644 statediff/indexer/ipld/eth_storage.go create mode 100644 statediff/indexer/ipld/eth_storage_test.go create mode 100644 statediff/indexer/ipld/eth_tx.go create mode 100644 statediff/indexer/ipld/eth_tx_test.go create mode 100644 statediff/indexer/ipld/eth_tx_trie.go create mode 100644 statediff/indexer/ipld/eth_tx_trie_test.go create mode 100644 statediff/indexer/ipld/shared.go create mode 100644 statediff/indexer/ipld/test_data/error-tx-eth-block-body-json-999999 create mode 100644 statediff/indexer/ipld/test_data/eth-block-body-json-0 create mode 100644 statediff/indexer/ipld/test_data/eth-block-body-json-4139497 create mode 100644 statediff/indexer/ipld/test_data/eth-block-body-json-997522 create mode 100644 statediff/indexer/ipld/test_data/eth-block-body-json-999998 create mode 100644 statediff/indexer/ipld/test_data/eth-block-body-json-999999 create mode 100644 statediff/indexer/ipld/test_data/eth-block-body-rlp-997522 create mode 100644 statediff/indexer/ipld/test_data/eth-block-body-rlp-999999 create mode 100644 statediff/indexer/ipld/test_data/eth-block-header-rlp-999996 create mode 100644 statediff/indexer/ipld/test_data/eth-block-header-rlp-999997 create mode 100644 statediff/indexer/ipld/test_data/eth-block-header-rlp-999999 create mode 100644 statediff/indexer/ipld/test_data/eth-state-trie-rlp-0e8b34 create mode 100644 statediff/indexer/ipld/test_data/eth-state-trie-rlp-56864f create mode 100644 statediff/indexer/ipld/test_data/eth-state-trie-rlp-6fc2d7 create mode 100644 statediff/indexer/ipld/test_data/eth-state-trie-rlp-727994 create mode 100644 statediff/indexer/ipld/test_data/eth-state-trie-rlp-c9070d create mode 100644 statediff/indexer/ipld/test_data/eth-state-trie-rlp-d5be90 create mode 100644 statediff/indexer/ipld/test_data/eth-state-trie-rlp-d7f897 create mode 100644 statediff/indexer/ipld/test_data/eth-state-trie-rlp-eb2f5f create mode 100644 statediff/indexer/ipld/test_data/eth-storage-trie-rlp-000dd0 create mode 100644 statediff/indexer/ipld/test_data/eth-storage-trie-rlp-113049 create mode 100644 statediff/indexer/ipld/test_data/eth-storage-trie-rlp-9d1860 create mode 100644 statediff/indexer/ipld/test_data/eth-storage-trie-rlp-ffbcad create mode 100644 statediff/indexer/ipld/test_data/eth-storage-trie-rlp-ffc25c create mode 100644 statediff/indexer/ipld/test_data/eth-uncle-json-997522-0 create mode 100644 statediff/indexer/ipld/test_data/eth-uncle-json-997522-1 create mode 100644 statediff/indexer/ipld/test_data/tx_data create mode 100644 statediff/indexer/ipld/trie_node.go create mode 100644 statediff/indexer/mainnet_data/block_12579670.rlp create mode 100644 statediff/indexer/mainnet_data/block_12600011.rlp create mode 100644 statediff/indexer/mainnet_data/block_12619985.rlp create mode 100644 statediff/indexer/mainnet_data/block_12625121.rlp create mode 100644 statediff/indexer/mainnet_data/block_12655432.rlp create mode 100644 statediff/indexer/mainnet_data/block_12914664.rlp create mode 100644 statediff/indexer/mainnet_data/receipts_12579670.rlp create mode 100644 statediff/indexer/mainnet_data/receipts_12600011.rlp create mode 100644 statediff/indexer/mainnet_data/receipts_12619985.rlp create mode 100644 statediff/indexer/mainnet_data/receipts_12625121.rlp create mode 100644 statediff/indexer/mainnet_data/receipts_12655432.rlp create mode 100644 statediff/indexer/mainnet_data/receipts_12914664.rlp create mode 100644 statediff/indexer/mocks/test_data.go create mode 100644 statediff/indexer/models/batch.go create mode 100644 statediff/indexer/models/models.go create mode 100644 statediff/indexer/node/node.go create mode 100644 statediff/indexer/shared/constants.go create mode 100644 statediff/indexer/shared/db_kind.go create mode 100644 statediff/indexer/shared/functions.go create mode 100644 statediff/indexer/shared/reward.go create mode 100644 statediff/indexer/test/test.go create mode 100644 statediff/indexer/test/test_init.go create mode 100644 statediff/indexer/test/test_legacy.go create mode 100644 statediff/indexer/test/test_mainnet.go create mode 100644 statediff/indexer/test/test_watched_addresses.go create mode 100644 statediff/indexer/test_helpers/mainnet_test_helpers.go create mode 100644 statediff/indexer/test_helpers/test_helpers.go create mode 100644 statediff/mainnet_tests/block0_rlp create mode 100644 statediff/mainnet_tests/block1_rlp create mode 100644 statediff/mainnet_tests/block2_rlp create mode 100644 statediff/mainnet_tests/block3_rlp create mode 100644 statediff/mainnet_tests/builder_test.go create mode 100644 statediff/metrics.go create mode 100644 statediff/metrics_helpers.go create mode 100644 statediff/payload.go create mode 100644 statediff/service.go create mode 100644 statediff/service_test.go create mode 100644 statediff/test_helpers/constant.go create mode 100644 statediff/test_helpers/helpers.go create mode 100644 statediff/test_helpers/mocks/backend.go create mode 100644 statediff/test_helpers/mocks/blockchain.go create mode 100644 statediff/test_helpers/mocks/builder.go create mode 100644 statediff/test_helpers/mocks/indexer.go create mode 100644 statediff/test_helpers/mocks/service.go create mode 100644 statediff/test_helpers/mocks/service_test.go create mode 100644 statediff/test_helpers/test_data.go create mode 100644 statediff/trie_helpers/helpers.go create mode 100644 statediff/types/types.go rename README.md => trie/concurrent_iterator/README.md (91%) create mode 100644 trie/concurrent_iterator/fixture/chaindata.go create mode 100644 trie/concurrent_iterator/fixture/chaindata/.gitignore create mode 100644 trie/concurrent_iterator/fixture/chaindata/000002.ldb create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/bodies.0000.cdat create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/bodies.cidx create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/diffs.0000.rdat create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/diffs.ridx create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/hashes.0000.rdat create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/hashes.ridx create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/headers.0000.cdat create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/headers.cidx create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/receipts.0000.cdat create mode 100644 trie/concurrent_iterator/fixture/chaindata/ancient/receipts.cidx create mode 100644 trie/concurrent_iterator/fixture/paths.go create mode 100644 trie/concurrent_iterator/iterator.go create mode 100644 trie/concurrent_iterator/iterator_test.go create mode 100644 trie/concurrent_iterator/tracker/tracker.go create mode 100644 trie/concurrent_iterator/util.go diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml new file mode 100644 index 000000000..f3f88a1ae --- /dev/null +++ b/.github/workflows/checks.yml @@ -0,0 +1,15 @@ +name: checks + +on: [pull_request] + +jobs: + linter-check: + runs-on: ubuntu-latest + steps: + - uses: actions/setup-go@v3 + with: + go-version: "1.18" + check-latest: true + - uses: actions/checkout@v2 + - name: Run linter + run: go run build/ci.go lint diff --git a/.github/workflows/manual_binary_publish.yaml b/.github/workflows/manual_binary_publish.yaml new file mode 100644 index 000000000..843aa3644 --- /dev/null +++ b/.github/workflows/manual_binary_publish.yaml @@ -0,0 +1,21 @@ +name: MANUAL Override Publish geth binary to release +on: + workflow_dispatch: + inputs: + giteaPublishTag: + description: 'Package to publish TO on gitea; e.g. v1.10.25-statediff-4.2.1-alpha' + required: true + cercContainerTag: + description: 'Tagged Container to extract geth binary FROM' + required: true +jobs: + build: + name: Manual override publish of geth binary FROM tagged release TO TAGGED package on git.vdb.to + runs-on: ubuntu-latest + steps: + - name: Copy ethereum binary file + run: docker run --rm --entrypoint cat git.vdb.to/cerc-io/go-ethereum/go-ethereum:${{ github.event.inputs.cercContainerTag }} /usr/local/bin/geth > geth-linux-amd64 + - name: curl + uses: enflo/curl-action@master + with: + curl: --user cerccicd:${{ secrets.GITEA_TOKEN }} --upload-file geth-linux-amd64 https://git.vdb.to/api/packages/cerc-io/generic/go-ethereum/${{ github.event.inputs.giteaPublishTag }}/geth-linux-amd64 diff --git a/.github/workflows/manual_publish.yaml b/.github/workflows/manual_publish.yaml new file mode 100644 index 000000000..e8990be1e --- /dev/null +++ b/.github/workflows/manual_publish.yaml @@ -0,0 +1,21 @@ +name: MANUAL Override Publish geth binary to release +on: + workflow_dispatch: + inputs: + giteaPublishTag: + description: 'Package to publish TO on gitea; e.g. v1.10.25-statediff-4.2.1-alpha' + required: true + cercContainerTag: + description: 'Tagged Container to extract geth binary FROM' + required: true +jobs: + build: + name: Manual override publish of geth binary FROM tagged release TO TAGGED package on git.vdb.to + runs-on: ubuntu-latest + steps: + - name: Copy ethereum binary file + run: docker run --rm --entrypoint cat git.vdb.to/cerc-io/go-ethereum/go-ethereum:${{ github.event.inputs.cercContainerTag }} /usr/local/bin/geth > geth-linux-amd64 + - name: curl + uses: enflo/curl-action@master + with: + curl: --user circcicd:${{ secrets.GITEA_TOKEN }} --upload-file geth-linux-amd64 https://git.vdb.to/api/packages/cerc-io/generic/go-ethereum/${{ github.event.inputs.giteaPublishTag }}/geth-linux-amd64 diff --git a/.github/workflows/old_tests.yml b/.github/workflows/old_tests.yml new file mode 100644 index 000000000..8e20a5f59 --- /dev/null +++ b/.github/workflows/old_tests.yml @@ -0,0 +1,145 @@ +name: Tests for Geth that are used in multiple jobs. + +on: + workflow_call: + +env: + stack-orchestrator-ref: ${{ github.event.inputs.stack-orchestrator-ref || '37da42481357102a4e02156ad3b178cc5d1f9a42'}} + ipld-eth-db-ref: ${{ github.event.inputs.ipld-ethcl-db-ref || 'be345e0733d2c025e4082c5154e441317ae94cf7' }} + GOPATH: /tmp/go + +jobs: + build: + name: Run docker build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Run docker build + run: docker build -t cerc-io/go-ethereum . + + geth-unit-test: + name: Run geth unit test + runs-on: ubuntu-latest + env: + GO111MODULE: on + steps: + - name: Create GOPATH + run: mkdir -p /tmp/go + + - uses: actions/setup-go@v3 + with: + go-version: "1.18" + check-latest: true + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Run unit tests + run: | + make test + + statediff-unit-test: + name: Run state diff unit test + runs-on: ubuntu-latest + steps: + - name: Create GOPATH + run: mkdir -p /tmp/go + + - uses: actions/setup-go@v3 + with: + go-version: "1.18" + check-latest: true + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Run docker compose + run: | + docker-compose up -d + + - name: Give the migration a few seconds + run: sleep 30; + + - name: Run unit tests + run: make statedifftest + + private-network-test: + name: Start Geth in a private network. + runs-on: ubuntu-latest + steps: + - name: Create GOPATH + run: mkdir -p /tmp/go + + - uses: actions/setup-go@v3 + with: + go-version: "1.18" + check-latest: true + + - name: Checkout code + uses: actions/checkout@v3 + with: + path: "./go-ethereum" + + - uses: actions/checkout@v3 + with: + ref: ${{ env.stack-orchestrator-ref }} + path: "./stack-orchestrator/" + repository: cerc-io/mshaw_stack_hack + fetch-depth: 0 + + - uses: actions/checkout@v3 + with: + ref: ${{ env.ipld-eth-db-ref }} + repository: cerc-io/ipld-eth-db + path: "./ipld-eth-db/" + fetch-depth: 0 + + - name: Create config file + run: | + echo vulcanize_ipld_eth_db=$GITHUB_WORKSPACE/ipld-eth-db/ > $GITHUB_WORKSPACE/config.sh + echo vulcanize_go_ethereum=$GITHUB_WORKSPACE/go-ethereum/ >> $GITHUB_WORKSPACE/config.sh + echo db_write=true >> $GITHUB_WORKSPACE/config.sh + echo genesis_file_path=start-up-files/go-ethereum/genesis.json >> $GITHUB_WORKSPACE/config.sh + cat $GITHUB_WORKSPACE/config.sh + + - name: Compile Geth + run: | + cd $GITHUB_WORKSPACE/stack-orchestrator/helper-scripts + ./compile-geth.sh -e docker -p $GITHUB_WORKSPACE/config.sh + cd - + + - name: Run docker compose + run: | + docker-compose \ + -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-go-ethereum.yml" \ + -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-db-sharding.yml" \ + --env-file $GITHUB_WORKSPACE/config.sh \ + up -d --build + + - name: Make sure the /root/transaction_info/STATEFUL_TEST_DEPLOYED_ADDRESS exists within a certain time frame. + shell: bash + run: | + COUNT=0 + ATTEMPTS=15 + docker ps + sleep 30; + docker logs local_go-ethereum_1 + docker compose -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-db-sharding.yml" -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-go-ethereum.yml" exec go-ethereum ps aux + until $(docker compose -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-db-sharding.yml" -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-go-ethereum.yml" cp go-ethereum:/root/transaction_info/STATEFUL_TEST_DEPLOYED_ADDRESS ./STATEFUL_TEST_DEPLOYED_ADDRESS) || [[ $COUNT -eq $ATTEMPTS ]]; do echo -e "$(( COUNT++ ))... \c"; sleep 10; done + [[ $COUNT -eq $ATTEMPTS ]] && echo "Could not find the successful contract deployment" && (exit 1) + cat ./STATEFUL_TEST_DEPLOYED_ADDRESS + sleep 15; + + - name: Create a new transaction. + shell: bash + run: | + docker compose -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-db-sharding.yml" -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-go-ethereum.yml" exec go-ethereum /bin/bash /root/transaction_info/NEW_TRANSACTION + echo $? + + - name: Make sure we see entries in the header table + shell: bash + run: | + rows=$(docker compose -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-db-sharding.yml" -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-go-ethereum.yml" exec ipld-eth-db psql -U vdbm -d vulcanize_testing -AXqtc "SELECT COUNT(*) FROM eth.header_cids") + [[ "$rows" -lt "1" ]] && echo "We could not find any rows in postgres table." && (exit 1) + echo $rows + docker compose -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-db-sharding.yml" -f "$GITHUB_WORKSPACE/stack-orchestrator/docker/local/docker-compose-go-ethereum.yml" exec ipld-eth-db psql -U vdbm -d vulcanize_testing -AXqtc "SELECT * FROM eth.header_cids" \ No newline at end of file diff --git a/.github/workflows/on-pr.yml b/.github/workflows/on-pr.yml new file mode 100644 index 000000000..4dad68b60 --- /dev/null +++ b/.github/workflows/on-pr.yml @@ -0,0 +1,7 @@ +name: Build and test + +on: [pull_request] + +jobs: + run-oldtests: + uses: ./.github/workflows/old_tests.yml diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 000000000..e386b35b1 --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,50 @@ +name: Publish geth to release +on: + release: + types: [published] +jobs: + run-tests: + uses: ./.github/workflows/tests.yml + build: + name: Run docker build and publish + needs: run-tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Run docker build + run: docker build -t vulcanize/go-ethereum -f Dockerfile . + - name: Get the version + id: vars + run: echo ::set-output name=sha::$(echo ${GITHUB_SHA:0:7}) + - name: Tag docker image + run: docker tag vulcanize/go-ethereum docker.pkg.github.com/vulcanize/go-ethereum/go-ethereum:${{steps.vars.outputs.sha}} + - name: Docker Login + run: echo ${{ secrets.GITHUB_TOKEN }} | docker login https://docker.pkg.github.com -u vulcanize --password-stdin + - name: Docker Push + run: docker push docker.pkg.github.com/vulcanize/go-ethereum/go-ethereum:${{steps.vars.outputs.sha}} + push_to_registries: + name: Publish assets to Release + runs-on: ubuntu-latest + needs: build + steps: + - name: Get the version + id: vars + run: | + echo ::set-output name=sha::$(echo ${GITHUB_SHA:0:7}) + echo ::set-output name=tag::$(echo ${GITHUB_REF#refs/tags/}) + - name: Tag docker image + run: docker tag cerc-io/go-ethereum git.vdb.to/cerc-io/go-ethereum/go-ethereum:${{steps.vars.outputs.sha}} + - name: Tag docker image + run: docker tag git.vdb.to/cerc-io/go-ethereum/go-ethereum:${{steps.vars.outputs.sha}} git.vdb.to/cerc-io/go-ethereum/go-ethereum:${{steps.vars.outputs.tag}} + - name: Docker Login + run: echo ${{ secrets.GITEA_TOKEN }} | docker login https://git.vdb.to -u cerccicd --password-stdin + - name: Docker Push + run: docker push git.vdb.to/cerc-io/go-ethereum/go-ethereum:${{steps.vars.outputs.sha}} + - name: Docker Push TAGGED + run: docker push git.vdb.to/cerc-io/go-ethereum/go-ethereum:${{steps.vars.outputs.tag}} + - name: Copy ethereum binary file + run: docker run --rm --entrypoint cat git.vdb.to/cerc-io/go-ethereum/go-ethereum:${{steps.vars.outputs.sha}} /usr/local/bin/geth > geth-linux-amd64 + - name: curl + uses: enflo/curl-action@master + with: + curl: --user cerccicd:${{ secrets.GITEA_TOKEN }} --upload-file geth-linux-amd64 https://git.vdb.to/api/packages/cerc-io/generic/go-ethereum/${{steps.vars.outputs.tag}}/geth-linux-amd64 diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml new file mode 100644 index 000000000..4dfe7cbc7 --- /dev/null +++ b/.github/workflows/tests.yml @@ -0,0 +1,143 @@ +name: Tests for Geth that are used in multiple jobs. + +on: + workflow_call: + +env: + stack-orchestrator-ref: ${{ github.event.inputs.stack-orchestrator-ref || 'f2fd766f5400fcb9eb47b50675d2e3b1f2753702'}} + ipld-eth-db-ref: ${{ github.event.inputs.ipld-ethcl-db-ref || 'be345e0733d2c025e4082c5154e441317ae94cf7' }} + GOPATH: /tmp/go + +jobs: + build: + name: Run docker build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Run docker build + run: docker build -t cerc-io/go-ethereum . + + geth-unit-test: + name: Run geth unit test + runs-on: ubuntu-latest + env: + GO111MODULE: on + steps: + - name: Create GOPATH + run: mkdir -p /tmp/go + + - uses: actions/setup-go@v3 + with: + go-version: "1.18" + check-latest: true + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Run unit tests + run: | + make test + + statediff-unit-test: + name: Run state diff unit test + runs-on: ubuntu-latest + steps: + - name: Create GOPATH + run: mkdir -p /tmp/go + + - uses: actions/setup-go@v3 + with: + go-version: "1.18" + check-latest: true + + - name: Checkout code + uses: actions/checkout@v2 + + - name: Run docker compose + run: | + docker-compose up -d + + - name: Give the migration a few seconds + run: sleep 30; + + - name: Run unit tests + run: make statedifftest + + private-network-test: + name: Start Geth in a private network. + runs-on: ubuntu-latest + steps: + - name: Create GOPATH + run: mkdir -p /tmp/go + + - uses: actions/setup-go@v3 + with: + go-version: "1.18" + check-latest: true + - name: cerc mkdir + run: mkdir /home/runner/cerc + + - name: Checkout code + uses: actions/checkout@v3 + + - uses: actions/checkout@v3 + with: + repository: cerc-io/ipld-eth-db + path: "./ipld-eth-db/" + ref: a4961e5e597148c0ff6dd7a34958bdf8c469a47e + + - name: symlink for laconic-so + run: ln -sf /home/runner/work/go-ethereum/go-ethereum /home/runner/cerc/go-ethereum + + - name: symlink for laconic-so + run: ln -sf /home/runner/work/go-ethereum/go-ethereum/ipld-eth-db /home/runner/cerc/ipld-eth-db + + - name: Install stack orchestrator laconic-so + run: | + curl -L -o laconic-so https://github.com/cerc-io/stack-orchestrator/releases/latest/download/laconic-so + chmod +x laconic-so + + - name: Checkout supporting repos in workspace + run: | + ./laconic-so setup-repositories --include cerc/ipld-eth-db + + - name: Build containers from repos in workspace + run: | + ./laconic-so build-containers --include cerc/go-ethereum,cerc/go-ethereum-foundry,cerc/ipld-eth-db + + - name: Start containers + run: | + docker compose -f docker-compose-cicd.yml up -d + + - name: Make sure the /root/transaction_info/STATEFUL_TEST_DEPLOYED_ADDRESS exists within a certain time frame. + shell: bash + run: | + COUNT=0 + ATTEMPTS=15 + sleep 60 + docker logs go-ethereum-go-ethereum-1 + docker logs go-ethereum-ipld-eth-db-1 + docker logs go-ethereum-migrations-1 + docker compose -f docker-compose-cicd.yml exec go-ethereum ps aux + until $(docker compose -f docker-compose-cicd.yml cp go-ethereum:/root/transaction_info/STATEFUL_TEST_DEPLOYED_ADDRESS ./STATEFUL_TEST_DEPLOYED_ADDRESS) || [[ $COUNT -eq $ATTEMPTS ]]; do echo -e "$(( COUNT++ ))... \c"; sleep 10; done + [[ $COUNT -eq $ATTEMPTS ]] && echo "Could not find the successful contract deployment" && (exit 1) + cat ./STATEFUL_TEST_DEPLOYED_ADDRESS + sleep 15; + + - name: Create a new transaction. + shell: bash + run: | + docker compose -f docker-compose-cicd.yml exec go-ethereum /bin/bash /root/transaction_info/NEW_TRANSACTION + echo $? + + - name: Make sure we see entries in the header table + shell: bash + run: | + rows=$(docker compose -f docker-compose-cicd.yml - exec ipld-eth-db psql -U vdbm -d vulcanize_testing -AXqtc "SELECT COUNT(*) FROM eth.header_cids") + [[ "$rows" -lt "1" ]] && echo "We could not find any rows in postgres table." && (exit 1) + echo $rows + docker compose -f docker-compose-cicd.yml exec ipld-eth-db psql -U vdbm -d vulcanize_testing -AXqtc "SELECT * FROM eth.header_cids" + + - name: Stop containers + run: | + docker compose -f docker-compose-cicd.yml down \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1ee8b8302..a4b4cc127 100644 --- a/.gitignore +++ b/.gitignore @@ -47,3 +47,18 @@ profile.cov /dashboard/assets/package-lock.json **/yarn-error.log +foundry/deployments/local-private-network/geth-linux-amd64 +foundry/projects/local-private-network/geth-linux-amd64 + +# Helpful repos +related-repositories/foundry-test/** +related-repositories/hive/** +related-repositories/ipld-eth-db/** +statediff/indexer/database/sql/statediffing_test_file.sql +statediff/statediffing_test_file.sql +statediff/known_gaps.sql +related-repositories/foundry-test/ +related-repositories/ipld-eth-db/ +.idea/ +trie/concurrent_iterator/fixture/chaindata/ancient/*.meta + diff --git a/.gitmodules b/.gitmodules index 241c169c4..2171d3b2c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -5,4 +5,4 @@ [submodule "evm-benchmarks"] path = tests/evm-benchmarks url = https://github.com/ipsilon/evm-benchmarks - shallow = true + shallow = true \ No newline at end of file diff --git a/Dockerfile.amd64 b/Dockerfile.amd64 new file mode 100644 index 000000000..7a35376c9 --- /dev/null +++ b/Dockerfile.amd64 @@ -0,0 +1,7 @@ +# Build Geth in a stock Go builder container +FROM golang:1.15.5 as builder + +#RUN apk add --no-cache make gcc musl-dev linux-headers git + +ADD . /go-ethereum +RUN cd /go-ethereum && make geth diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 000000000..98b02490a --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,50 @@ +pipeline { + agent any + + stages { + stage('Build') { + steps { + script{ + docker.withRegistry('https://git.vdb.to'){ + echo 'Building geth image...' + //def geth_image = docker.build("cerc-io/go-ethereum:jenkinscicd") + echo 'built geth image' + } + } + } + } + stage('Test') { + agent { + docker { + image 'cerc-io/foundation:jenkinscicd' + //image 'cerc-io/foundation_alpine:jenkinscicd' + } + } + + environment { + GO111MODULE = "on" + CGO_ENABLED = 1 + //GOPATH = "${JENKINS_HOME}/jobs/${JOB_NAME}/builds/${BUILD_ID}" + //GOPATH = "/go" + GOPATH = "/tmp/go" + //GOMODCACHE = "/go/pkg/mod" + GOCACHE = "${WORKSPACE}/.cache/go-build" + GOENV = "${WORKSPACE}/.config/go/env" + GOMODCACHE = "/tmp/go/pkg/mod" + GOWORK="" + //GOFLAGS="" + + } + steps { + echo 'Testing ...' + //sh '/usr/local/go/bin/go test -p 1 -v ./...' + sh 'make test' + } + } + stage('Packaging') { + steps { + echo 'Packaging ...' + } + } + } +} \ No newline at end of file diff --git a/Makefile b/Makefile index e6286da7f..bddfe8eaf 100644 --- a/Makefile +++ b/Makefile @@ -4,10 +4,31 @@ .PHONY: geth android ios evm all test clean +BIN = $(GOPATH)/bin + +## Migration tool +GOOSE = $(BIN)/goose +$(BIN)/goose: + go get -u github.com/pressly/goose/cmd/goose + GOBIN = ./build/bin GO ?= latest GORUN = env GO111MODULE=on go run +#Database +HOST_NAME = localhost +PORT = 5432 +USER = vdbm +PASSWORD = password + +# Set env variable +# `PGPASSWORD` is used by `createdb` and `dropdb` +export PGPASSWORD=$(PASSWORD) + +#Test +TEST_DB = vulcanize_public +TEST_CONNECT_STRING = postgresql://$(USER):$(PASSWORD)@$(HOST_NAME):$(PORT)/$(TEST_DB)?sslmode=disable + geth: $(GORUN) build/ci.go install ./cmd/geth @echo "Done building." @@ -17,7 +38,7 @@ all: $(GORUN) build/ci.go install test: all - $(GORUN) build/ci.go test + $(GORUN) build/ci.go test -v lint: ## Run linters. $(GORUN) build/ci.go lint @@ -36,3 +57,13 @@ devtools: env GOBIN= go install ./cmd/abigen @type "solc" 2> /dev/null || echo 'Please install solc' @type "protoc" 2> /dev/null || echo 'Please install protoc' + +.PHONY: statedifftest +statedifftest: | $(GOOSE) + GO111MODULE=on go get github.com/stretchr/testify/assert@v1.7.0 + GO111MODULE=on MODE=statediff go test -p 1 ./statediff/... -v + +.PHONY: statediff_filewriting_test +statediff_filetest: | $(GOOSE) + GO111MODULE=on go get github.com/stretchr/testify/assert@v1.7.0 + GO111MODULE=on MODE=statediff STATEDIFF_DB=file go test -p 1 ./statediff/... -v diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 0b856d1c1..89d3ef450 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -18,10 +18,12 @@ package main import ( "bufio" + "context" "errors" "fmt" "os" "reflect" + "time" "unicode" "github.com/urfave/cli/v2" @@ -40,6 +42,12 @@ import ( "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/statediff" + dumpdb "github.com/ethereum/go-ethereum/statediff/indexer/database/dump" + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/shared" "github.com/naoina/toml" ) @@ -151,6 +159,9 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, gethConfig) { cfg.Ethstats.URL = ctx.String(utils.EthStatsURLFlag.Name) } applyMetricConfig(ctx, &cfg) + if ctx.Bool(utils.StateDiffFlag.Name) { + cfg.Eth.Diffing = true + } return stack, cfg } @@ -167,7 +178,110 @@ func makeFullNode(ctx *cli.Context) (*node.Node, ethapi.Backend) { // Configure log filter RPC API. filterSystem := utils.RegisterFilterAPI(stack, backend, &cfg.Eth) - // Configure GraphQL if requested. + if ctx.Bool(utils.StateDiffFlag.Name) { + var indexerConfig interfaces.Config + var clientName, nodeID string + if ctx.IsSet(utils.StateDiffWritingFlag.Name) { + clientName = ctx.String(utils.StateDiffDBClientNameFlag.Name) + if ctx.IsSet(utils.StateDiffDBNodeIDFlag.Name) { + nodeID = ctx.String(utils.StateDiffDBNodeIDFlag.Name) + } else { + utils.Fatalf("Must specify node ID for statediff DB output") + } + + dbTypeStr := ctx.String(utils.StateDiffDBTypeFlag.Name) + dbType, err := shared.ResolveDBType(dbTypeStr) + if err != nil { + utils.Fatalf("%v", err) + } + switch dbType { + case shared.FILE: + fileModeStr := ctx.String(utils.StateDiffFileMode.Name) + fileMode, err := file.ResolveFileMode(fileModeStr) + if err != nil { + utils.Fatalf("%v", err) + } + + indexerConfig = file.Config{ + Mode: fileMode, + OutputDir: ctx.String(utils.StateDiffFileCsvDir.Name), + FilePath: ctx.String(utils.StateDiffFilePath.Name), + WatchedAddressesFilePath: ctx.String(utils.StateDiffWatchedAddressesFilePath.Name), + } + case shared.POSTGRES: + driverTypeStr := ctx.String(utils.StateDiffDBDriverTypeFlag.Name) + driverType, err := postgres.ResolveDriverType(driverTypeStr) + if err != nil { + utils.Fatalf("%v", err) + } + pgConfig := postgres.Config{ + Hostname: ctx.String(utils.StateDiffDBHostFlag.Name), + Port: ctx.Int(utils.StateDiffDBPortFlag.Name), + DatabaseName: ctx.String(utils.StateDiffDBNameFlag.Name), + Username: ctx.String(utils.StateDiffDBUserFlag.Name), + Password: ctx.String(utils.StateDiffDBPasswordFlag.Name), + ID: nodeID, + ClientName: clientName, + Driver: driverType, + } + if ctx.IsSet(utils.StateDiffUpsert.Name) { + pgConfig.Upsert = ctx.Bool(utils.StateDiffUpsert.Name) + } + if ctx.IsSet(utils.StateDiffDBMinConns.Name) { + pgConfig.MinConns = ctx.Int(utils.StateDiffDBMinConns.Name) + } + if ctx.IsSet(utils.StateDiffDBMaxConns.Name) { + pgConfig.MaxConns = ctx.Int(utils.StateDiffDBMaxConns.Name) + } + if ctx.IsSet(utils.StateDiffDBMaxIdleConns.Name) { + pgConfig.MaxIdle = ctx.Int(utils.StateDiffDBMaxIdleConns.Name) + } + if ctx.IsSet(utils.StateDiffDBMaxConnLifetime.Name) { + pgConfig.MaxConnLifetime = time.Duration(ctx.Duration(utils.StateDiffDBMaxConnLifetime.Name).Seconds()) + } + if ctx.IsSet(utils.StateDiffDBMaxConnIdleTime.Name) { + pgConfig.MaxConnIdleTime = time.Duration(ctx.Duration(utils.StateDiffDBMaxConnIdleTime.Name).Seconds()) + } + if ctx.IsSet(utils.StateDiffDBConnTimeout.Name) { + pgConfig.ConnTimeout = time.Duration(ctx.Duration(utils.StateDiffDBConnTimeout.Name).Seconds()) + } + if ctx.IsSet(utils.StateDiffLogStatements.Name) { + pgConfig.LogStatements = ctx.Bool(utils.StateDiffLogStatements.Name) + } + indexerConfig = pgConfig + case shared.DUMP: + dumpTypeStr := ctx.String(utils.StateDiffDBDumpDst.Name) + dumpType, err := dumpdb.ResolveDumpType(dumpTypeStr) + if err != nil { + utils.Fatalf("%v", err) + } + switch dumpType { + case dumpdb.STDERR: + indexerConfig = dumpdb.Config{Dump: os.Stdout} + case dumpdb.STDOUT: + indexerConfig = dumpdb.Config{Dump: os.Stderr} + case dumpdb.DISCARD: + indexerConfig = dumpdb.Config{Dump: dumpdb.NewDiscardWriterCloser()} + default: + utils.Fatalf("unrecognized dump destination: %s", dumpType) + } + default: + utils.Fatalf("unrecognized database type: %s", dbType) + } + } + p := statediff.Config{ + IndexerConfig: indexerConfig, + ID: nodeID, + ClientName: clientName, + Context: context.Background(), + EnableWriteLoop: ctx.Bool(utils.StateDiffWritingFlag.Name), + NumWorkers: ctx.Uint(utils.StateDiffWorkersFlag.Name), + WaitForSync: ctx.Bool(utils.StateDiffWaitForSync.Name), + } + utils.RegisterStateDiffService(stack, eth, &cfg.Eth, p, backend) + } + + // Configure GraphQL if requested if ctx.IsSet(utils.GraphQLEnabledFlag.Name) { utils.RegisterGraphQLService(stack, backend, filterSystem, &cfg.Node) } diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 5ba070249..8f4bb6727 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -149,6 +149,32 @@ var ( utils.GpoMaxGasPriceFlag, utils.GpoIgnoreGasPriceFlag, utils.MinerNotifyFullFlag, + utils.StateDiffFlag, + utils.StateDiffDBTypeFlag, + utils.StateDiffDBDriverTypeFlag, + utils.StateDiffDBDumpDst, + utils.StateDiffDBNameFlag, + utils.StateDiffDBPasswordFlag, + utils.StateDiffDBUserFlag, + utils.StateDiffDBHostFlag, + utils.StateDiffDBPortFlag, + utils.StateDiffDBMaxConnLifetime, + utils.StateDiffDBMaxConnIdleTime, + utils.StateDiffDBMaxConns, + utils.StateDiffDBMinConns, + utils.StateDiffDBMaxIdleConns, + utils.StateDiffDBConnTimeout, + utils.StateDiffDBNodeIDFlag, + utils.StateDiffDBClientNameFlag, + utils.StateDiffWritingFlag, + utils.StateDiffWorkersFlag, + utils.StateDiffFileMode, + utils.StateDiffFileCsvDir, + utils.StateDiffFilePath, + utils.StateDiffWaitForSync, + utils.StateDiffWatchedAddressesFilePath, + utils.StateDiffUpsert, + utils.StateDiffLogStatements, configFileFlag, }, utils.NetworkFlags, utils.DatabasePathFlags) diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index 08de71ee8..f97dce8ac 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -74,6 +74,8 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/statediff" + pcsclite "github.com/gballet/go-libpcsclite" gopsutil "github.com/shirou/gopsutil/mem" "github.com/urfave/cli/v2" @@ -994,6 +996,123 @@ Please note that --` + MetricsHTTPFlag.Name + ` must be set to start the server. Value: metrics.DefaultConfig.InfluxDBOrganization, Category: flags.MetricsCategory, } + + StateDiffFlag = &cli.BoolFlag{ + Name: "statediff", + Usage: "Enables the processing of state diffs between each block", + Category: flags.MiscCategory, + } + StateDiffDBTypeFlag = &cli.StringFlag{ + Name: "statediff.db.type", + Usage: "Statediff database type (current options: postgres, file, dump)", + Value: "postgres", + } + StateDiffDBDriverTypeFlag = &cli.StringFlag{ + Name: "statediff.db.driver", + Usage: "Statediff database driver type", + Value: "pgx", + } + StateDiffDBDumpDst = &cli.StringFlag{ + Name: "statediff.dump.dst", + Usage: "Statediff database dump destination (default is stdout)", + Value: "stdout", + } + StateDiffDBHostFlag = &cli.StringFlag{ + Name: "statediff.db.host", + Usage: "Statediff database hostname/ip", + Value: "localhost", + } + StateDiffDBPortFlag = &cli.IntFlag{ + Name: "statediff.db.port", + Usage: "Statediff database port", + Value: 5432, + } + StateDiffDBNameFlag = &cli.StringFlag{ + Name: "statediff.db.name", + Usage: "Statediff database name", + } + StateDiffDBPasswordFlag = &cli.StringFlag{ + Name: "statediff.db.password", + Usage: "Statediff database password", + } + StateDiffDBUserFlag = &cli.StringFlag{ + Name: "statediff.db.user", + Usage: "Statediff database username", + Value: "postgres", + } + StateDiffDBMaxConnLifetime = &cli.DurationFlag{ + Name: "statediff.db.maxconnlifetime", + Usage: "Statediff database maximum connection lifetime (in seconds)", + } + StateDiffDBMaxConnIdleTime = &cli.DurationFlag{ + Name: "statediff.db.maxconnidletime", + Usage: "Statediff database maximum connection idle time (in seconds)", + } + StateDiffDBMaxConns = &cli.IntFlag{ + Name: "statediff.db.maxconns", + Usage: "Statediff database maximum connections", + } + StateDiffDBMinConns = &cli.IntFlag{ + Name: "statediff.db.minconns", + Usage: "Statediff database minimum connections", + } + StateDiffDBMaxIdleConns = &cli.IntFlag{ + Name: "statediff.db.maxidleconns", + Usage: "Statediff database maximum idle connections", + } + StateDiffDBConnTimeout = &cli.DurationFlag{ + Name: "statediff.db.conntimeout", + Usage: "Statediff database connection timeout (in seconds)", + } + StateDiffDBNodeIDFlag = &cli.StringFlag{ + Name: "statediff.db.nodeid", + Usage: "Node ID to use when writing state diffs to database", + } + StateDiffFileMode = &cli.StringFlag{ + Name: "statediff.file.mode", + Usage: "Statediff file writing mode (current options: csv, sql)", + Value: "csv", + } + StateDiffFileCsvDir = &cli.StringFlag{ + Name: "statediff.file.csvdir", + Usage: "Full path of output directory to write statediff data out to when operating in csv file mode", + } + StateDiffFilePath = &cli.StringFlag{ + Name: "statediff.file.path", + Usage: "Full path (including filename) to write statediff data out to when operating in sql file mode", + } + StateDiffWatchedAddressesFilePath = &cli.StringFlag{ + Name: "statediff.file.wapath", + Usage: "Full path (including filename) to write statediff watched addresses out to when operating in file mode", + } + StateDiffDBClientNameFlag = &cli.StringFlag{ + Name: "statediff.db.clientname", + Usage: "Client name to use when writing state diffs to database", + Value: "go-ethereum", + } + StateDiffUpsert = &cli.BoolFlag{ + Name: "statediff.db.upsert", + Usage: "Should the statediff service overwrite data existing in the database?", + Value: false, + } + StateDiffLogStatements = &cli.BoolFlag{ + Name: "statediff.db.logstatements", + Usage: "Should the statediff service log all database statements? (Note: pgx only)", + Value: false, + } + StateDiffWritingFlag = &cli.BoolFlag{ + Name: "statediff.writing", + Usage: "Activates progressive writing of state diffs to database as new block are synced", + } + StateDiffWorkersFlag = &cli.UintFlag{ + Name: "statediff.workers", + Usage: "Number of concurrent workers to use during statediff processing (default 1)", + Value: 1, + } + StateDiffWaitForSync = &cli.BoolFlag{ + Name: "statediff.waitforsync", + Usage: "Should the statediff service wait for geth to catch up to the head of the chain?", + } ) var ( @@ -1246,6 +1365,10 @@ func setWS(ctx *cli.Context, cfg *node.Config) { if ctx.IsSet(WSPathPrefixFlag.Name) { cfg.WSPathPrefix = ctx.String(WSPathPrefixFlag.Name) } + + if ctx.Bool(StateDiffFlag.Name) { + cfg.WSModules = append(cfg.WSModules, "statediff") + } } // setIPC creates an IPC path configuration from the set command line flags, @@ -2017,6 +2140,15 @@ func RegisterEthService(stack *node.Node, cfg *ethconfig.Config) (ethapi.Backend return backend.APIBackend, backend } +// RegisterLesEthService adds an Ethereum les client to the stack. +func RegisterLesEthService(stack *node.Node, cfg *eth.Config) *les.LightEthereum { + backend, err := les.New(stack, cfg) + if err != nil { + Fatalf("Failed to register the Ethereum service: %v", err) + } + return backend +} + // RegisterEthStatsService configures the Ethereum Stats daemon and adds it to the node. func RegisterEthStatsService(stack *node.Node, backend ethapi.Backend, url string) { if err := ethstats.New(stack, backend, backend.Engine(), url); err != nil { @@ -2063,6 +2195,13 @@ func RegisterFullSyncTester(stack *node.Node, eth *eth.Ethereum, path string) { log.Info("Registered full-sync tester", "number", block.NumberU64(), "hash", block.Hash()) } +// RegisterStateDiffService configures and registers a service to stream state diff data over RPC +func RegisterStateDiffService(stack *node.Node, ethServ *eth.Ethereum, cfg *ethconfig.Config, params statediff.Config, backend ethapi.Backend) { + if err := statediff.New(stack, ethServ, cfg, params, backend); err != nil { + Fatalf("Failed to register the Statediff service: %v", err) + } +} + func SetupMetrics(ctx *cli.Context) { if metrics.Enabled { log.Info("Enabling metrics collection") diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index da29e1659..8b0b88ed5 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/consensus/misc" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" @@ -333,7 +334,13 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa // the difficulty that a new block should have when created at time // given the parent block's time and difficulty. func (ethash *Ethash) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { - return CalcDifficulty(chain.Config(), time, parent) + var config = chain.Config() + var ret = CalcDifficulty(config, time, parent) + if nil != config.CappedMaximumDifficulty && ret.Cmp(config.CappedMaximumDifficulty) >= 0 { + log.Info(fmt.Sprintf("Using capped difficulty %d", config.CappedMaximumDifficulty)) + return config.CappedMaximumDifficulty + } + return ret } // CalcDifficulty is the difficulty adjustment algorithm. It returns diff --git a/core/blockchain.go b/core/blockchain.go index 38a129d4e..12719a805 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -139,6 +139,7 @@ type CacheConfig struct { SnapshotNoBuild bool // Whether the background generation is allowed SnapshotWait bool // Wait for snapshot construction on startup. TODO(karalabe): This is a dirty hack for testing, nuke it + StateDiffing bool // Whether or not the statediffing service is running } // defaultCacheConfig are the default caching values if none are specified by the @@ -224,6 +225,10 @@ type BlockChain struct { processor Processor // Block transaction processor interface forker *ForkChoice vmConfig vm.Config + + // Locked roots and their mutex + trieLock sync.Mutex + lockedRoots map[common.Hash]bool } // NewBlockChain returns a fully initialised block chain using information @@ -272,6 +277,7 @@ func NewBlockChain(db ethdb.Database, cacheConfig *CacheConfig, genesis *Genesis futureBlocks: lru.NewCache[common.Hash, *types.Block](maxFutureBlocks), engine: engine, vmConfig: vmConfig, + lockedRoots: make(map[common.Hash]bool), } bc.forker = NewForkChoice(bc, shouldPreserve) bc.stateCache = state.NewDatabaseWithNodeDB(bc.db, bc.triedb) @@ -957,7 +963,10 @@ func (bc *BlockChain) Stop() { } } for !bc.triegc.Empty() { - triedb.Dereference(bc.triegc.PopItem()) + pruneRoot := bc.triegc.PopItem() + if !bc.TrieLocked(pruneRoot) { + triedb.Dereference(pruneRoot) + } } if size, _ := triedb.Size(); size != 0 { log.Error("Dangling trie nodes after full cleanup") @@ -1349,6 +1358,10 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. bc.triedb.Reference(root, common.Hash{}) // metadata reference to keep trie alive bc.triegc.Push(root, -int64(block.NumberU64())) + if bc.cacheConfig.StateDiffing { + bc.LockTrie(root) + } + current := block.NumberU64() // Flush limits are not considered for the first TriesInMemory blocks. if current <= TriesInMemory { @@ -2474,3 +2487,28 @@ func (bc *BlockChain) SetBlockValidatorAndProcessorForTesting(v Validator, p Pro func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) { atomic.StoreInt64(&bc.flushInterval, int64(interval)) } + +// TrieLocked returns whether the trie associated with the provided root is locked for use +func (bc *BlockChain) TrieLocked(root common.Hash) bool { + bc.trieLock.Lock() + locked, ok := bc.lockedRoots[root] + bc.trieLock.Unlock() + if !ok { + return false + } + return locked +} + +// LockTrie prevents dereferencing of the provided root +func (bc *BlockChain) LockTrie(root common.Hash) { + bc.trieLock.Lock() + bc.lockedRoots[root] = true + bc.trieLock.Unlock() +} + +// UnlockTrie allows dereferencing of the provided root- provided it was previously locked +func (bc *BlockChain) UnlockTrie(root common.Hash) { + bc.trieLock.Lock() + bc.lockedRoots[root] = false + bc.trieLock.Unlock() +} diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index e4dac3407..fc7c9bece 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -643,6 +643,23 @@ func ReadReceipts(db ethdb.Reader, hash common.Hash, number uint64, config *para return receipts } +// ReadStorageReceipts is a modification of ReadRawReceipts that skips a conversion to types.Receipt +// and returns the ReceipstForStorage instead +func ReadStorageReceipts(db ethdb.Reader, hash common.Hash, number uint64) []*types.ReceiptForStorage { + // Retrieve the flattened receipt slice + data := ReadReceiptsRLP(db, hash, number) + if len(data) == 0 { + return nil + } + // Convert the receipts from their storage form to their internal representation + var storageReceipts []*types.ReceiptForStorage + if err := rlp.DecodeBytes(data, &storageReceipts); err != nil { + log.Error("Invalid receipt array RLP", "hash", hash, "err", err) + return nil + } + return storageReceipts +} + // WriteReceipts stores all the transaction receipts belonging to a block. func WriteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64, receipts types.Receipts) { // Convert the receipts into their storage form and serialize them @@ -785,6 +802,17 @@ func WriteAncientBlocks(db ethdb.AncientWriter, blocks []*types.Block, receipts }) } +// WriteAncientBlock is a public wrapper of writeAncientBlock +func WriteAncientBlock(op ethdb.AncientWriteOp, block *types.Block, receipts types.Receipts, td *big.Int) error { + stReceipts := make([]*types.ReceiptForStorage, len(receipts)) + // Convert receipts to storage format and sum up total difficulty. + stReceipts = stReceipts[:0] + for i, receipt := range receipts { + stReceipts[i] = (*types.ReceiptForStorage)(receipt) + } + return writeAncientBlock(op, block, block.Header(), stReceipts, td) +} + func writeAncientBlock(op ethdb.AncientWriteOp, block *types.Block, header *types.Header, receipts []*types.ReceiptForStorage, td *big.Int) error { num := block.NumberU64() if err := op.AppendRaw(ChainFreezerHashTable, num, block.Hash().Bytes()); err != nil { diff --git a/core/types/receipt.go b/core/types/receipt.go index 4404b2788..cd6e7b258 100644 --- a/core/types/receipt.go +++ b/core/types/receipt.go @@ -69,6 +69,7 @@ type Receipt struct { BlockHash common.Hash `json:"blockHash,omitempty"` BlockNumber *big.Int `json:"blockNumber,omitempty"` TransactionIndex uint `json:"transactionIndex"` + LogRoot common.Hash `json:"logRoot"` } type receiptMarshaling struct { @@ -114,6 +115,9 @@ func NewReceipt(root []byte, failed bool, cumulativeGasUsed uint64) *Receipt { // EncodeRLP implements rlp.Encoder, and flattens the consensus fields of a receipt // into an RLP stream. If no post state is present, byzantium fork is assumed. +// For a legacy Receipt this returns RLP([PostStateOrStatus, CumulativeGasUsed, Bloom, Logs]) +// For a EIP-2718 Receipt this returns RLP(TxType || ReceiptPayload) +// For a EIP-2930 Receipt, TxType == 0x01 and ReceiptPayload == RLP([PostStateOrStatus, CumulativeGasUsed, Bloom, Logs]) func (r *Receipt) EncodeRLP(w io.Writer) error { data := &receiptRLP{r.statusEncoding(), r.CumulativeGasUsed, r.Bloom, r.Logs} if r.Type == LegacyTxType { diff --git a/core/types/transaction.go b/core/types/transaction.go index 353e0e599..c6191c377 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -88,6 +88,9 @@ type TxData interface { } // EncodeRLP implements rlp.Encoder +// For a legacy Transaction this returns RLP([AccountNonce, GasPrice, GasLimit, Recipient, Amount, Data, V, R, S]) +// For a EIP-2718 Transaction this returns RLP(TxType || TxPayload) +// For a EIP-2930 Transaction, TxType == 0x01 and TxPayload == RLP([ChainID, AccountNonce, GasPrice, GasLimit, Recipient, Amount, Data, AccessList, V, R, S] func (tx *Transaction) EncodeRLP(w io.Writer) error { if tx.Type() == LegacyTxType { return rlp.Encode(w, tx.inner) @@ -108,9 +111,10 @@ func (tx *Transaction) encodeTyped(w *bytes.Buffer) error { return rlp.Encode(w, tx.inner) } -// MarshalBinary returns the canonical encoding of the transaction. -// For legacy transactions, it returns the RLP encoding. For EIP-2718 typed -// transactions, it returns the type and payload. +// MarshalBinary returns the canonical consensus encoding of the transaction. +// For a legacy Transaction this returns RLP([AccountNonce, GasPrice, GasLimit, Recipient, Amount, Data, V, R, S]) +// For a EIP-2718 Transaction this returns TxType || TxPayload +// For a EIP-2930 Transaction, TxType == 0x01 and TxPayload == RLP([ChainID, AccountNonce, GasPrice, GasLimit, Recipient, Amount, Data, AccessList, V, R, S] func (tx *Transaction) MarshalBinary() ([]byte, error) { if tx.Type() == LegacyTxType { return rlp.EncodeToBytes(tx.inner) diff --git a/docker-compose-cicd.yml b/docker-compose-cicd.yml new file mode 100644 index 000000000..e953fe49f --- /dev/null +++ b/docker-compose-cicd.yml @@ -0,0 +1,54 @@ +version: "3.2" + +services: + go-ethereum: + restart: always + depends_on: + - migrations + image: cerc/go-ethereum-foundry:local + healthcheck: + test: [ "CMD", "nc", "-v", "localhost", "8545" ] + interval: 30s + timeout: 3s + retries: 10 + environment: + DB_USER: vdbm + DB_NAME: vulcanize_testing + DB_HOST: ipld-eth-db + DB_PORT: 5432 + DB_PASSWORD: password + DB_WRITE: "true" + DB_TYPE: postgres + DB_DRIVER: sqlx + DB_WAIT_FOR_SYNC: "true" + CHAIN_ID: "99" + USE_GENESIS: "true" + EXTRA_START_ARGS: ${extra_args} + ports: + - "127.0.0.1:8545:8545" + - "127.0.0.1:8546:8546" + + migrations: + restart: on-failure + depends_on: + - ipld-eth-db + image: cerc/ipld-eth-db:local + environment: + DATABASE_USER: "vdbm" + DATABASE_NAME: "vulcanize_testing" + DATABASE_PASSWORD: "password" + DATABASE_HOSTNAME: "ipld-eth-db" + DATABASE_PORT: 5432 + + ipld-eth-db: + image: timescale/timescaledb:latest-pg14 + restart: on-failure + command: ["postgres", "-c", "log_statement=all"] + environment: + POSTGRES_USER: "vdbm" + POSTGRES_DB: "vulcanize_testing" + POSTGRES_PASSWORD: "password" + ports: + - "127.0.0.1:8077:5432" + volumes: + - ./statediff/indexer/database/file:/file_indexer diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..62a81b0aa --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,27 @@ +version: "3.2" + +services: + migrations: + restart: on-failure + depends_on: + - ipld-eth-db + image: vulcanize/ipld-eth-db:v4.2.1-alpha + environment: + DATABASE_USER: "vdbm" + DATABASE_NAME: "vulcanize_testing" + DATABASE_PASSWORD: "password" + DATABASE_HOSTNAME: "ipld-eth-db" + DATABASE_PORT: 5432 + + ipld-eth-db: + image: timescale/timescaledb:latest-pg14 + restart: always + command: ["postgres", "-c", "log_statement=all"] + environment: + POSTGRES_USER: "vdbm" + POSTGRES_DB: "vulcanize_testing" + POSTGRES_PASSWORD: "password" + ports: + - "127.0.0.1:8077:5432" + volumes: + - ./statediff/indexer/database/file:/file_indexer diff --git a/eth/backend.go b/eth/backend.go index 6368c0e03..f690339ff 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -191,6 +191,7 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { TrieTimeLimit: config.TrieTimeout, SnapshotLimit: config.SnapshotCache, Preimages: config.Preimages, + StateDiffing: config.Diffing, } ) // Override the chain config with provided settings. diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index db686c5d0..362e962d4 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -207,6 +207,10 @@ type Config struct { // OverrideShanghai (TODO: remove after the fork) OverrideShanghai *uint64 `toml:",omitempty"` + + // Signify whether or not we are producing statediffs + // If we are, do not dereference state roots until the statediffing service is done with them + Diffing bool } // CreateConsensusEngine creates a consensus engine for the given chain configuration. diff --git a/eth/protocols/snap/sync.go b/eth/protocols/snap/sync.go index 13279fd96..fdc04533a 100644 --- a/eth/protocols/snap/sync.go +++ b/eth/protocols/snap/sync.go @@ -81,6 +81,7 @@ const ( // minTrienodeHealThrottle is the minimum divisor for throttling trie node // heal requests to avoid overloading the local node and excessively expanding // the state trie breadth wise. + minTrienodeHealThrottle = 1 // maxTrienodeHealThrottle is the maximum divisor for throttling trie node diff --git a/go.mod b/go.mod index fbac3e4d6..ae688186c 100644 --- a/go.mod +++ b/go.mod @@ -40,6 +40,14 @@ require ( github.com/huin/goupnp v1.0.3 github.com/influxdata/influxdb v1.8.3 github.com/influxdata/influxdb-client-go/v2 v2.4.0 + github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect + github.com/ipfs/go-block-format v0.0.3 + github.com/ipfs/go-cid v0.2.0 + github.com/ipfs/go-ipfs-blockstore v1.2.0 + github.com/ipfs/go-ipfs-ds-help v1.1.0 + github.com/ipfs/go-ipld-format v0.4.0 + github.com/jackc/pgconn v1.10.0 + github.com/jackc/pgx/v4 v4.13.0 github.com/jackpal/go-nat-pmp v1.0.2 github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e github.com/julienschmidt/httprouter v1.3.0 @@ -58,7 +66,7 @@ require ( github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/tyler-smith/go-bip39 v1.1.0 github.com/urfave/cli/v2 v2.17.2-0.20221006022127-8f469abc00aa - golang.org/x/crypto v0.1.0 + golang.org/x/crypto v0.6.0 golang.org/x/exp v0.0.0-20230206171751-46f607a40771 golang.org/x/sync v0.1.0 golang.org/x/sys v0.5.0 @@ -68,6 +76,15 @@ require ( gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce ) +require ( + github.com/georgysavva/scany v1.2.1 + github.com/jmoiron/sqlx v1.3.5 + github.com/lib/pq v1.10.7 + github.com/multiformats/go-multihash v0.0.15 + github.com/pganalyze/pg_query_go/v2 v2.2.0 + github.com/thoas/go-funk v0.9.3 +) + require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3 // indirect @@ -90,35 +107,60 @@ require ( github.com/deepmap/oapi-codegen v1.8.2 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect - github.com/getsentry/sentry-go v0.18.0 // indirect + github.com/getsentry/sentry-go v0.17.0 // indirect github.com/go-ole/go-ole v1.2.1 // indirect github.com/go-sourcemap/sourcemap v2.1.3+incompatible // indirect + github.com/go-sql-driver/mysql v1.7.0 // indirect github.com/gogo/protobuf v1.3.2 // indirect - github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect + github.com/hashicorp/golang-lru v0.5.4 // indirect + github.com/ipfs/bbloom v0.0.4 // indirect + github.com/ipfs/go-datastore v0.5.0 // indirect + github.com/ipfs/go-ipfs-util v0.0.2 // indirect + github.com/ipfs/go-log v0.0.1 // indirect + github.com/ipfs/go-metrics-interface v0.0.1 // indirect + github.com/jackc/chunkreader/v2 v2.0.1 // indirect + github.com/jackc/pgio v1.0.0 // indirect + github.com/jackc/pgpassfile v1.0.0 // indirect + github.com/jackc/pgproto3/v2 v2.1.1 // indirect + github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect + github.com/jackc/pgtype v1.8.1 // indirect + github.com/jackc/puddle v1.1.3 // indirect + github.com/jbenet/goprocess v0.1.4 // indirect github.com/klauspost/compress v1.15.15 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mattn/go-sqlite3 v1.14.16 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect + github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/mitchellh/pointerstructure v1.2.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect + github.com/mr-tron/base58 v1.2.0 // indirect + github.com/multiformats/go-base32 v0.0.3 // indirect + github.com/multiformats/go-base36 v0.1.0 // indirect + github.com/multiformats/go-multibase v0.0.3 // indirect + github.com/multiformats/go-varint v0.0.6 // indirect github.com/naoina/go-stringutil v0.1.0 // indirect github.com/opentracing/opentracing-go v1.1.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/client_golang v1.14.0 // indirect github.com/prometheus/client_model v0.3.0 // indirect - github.com/prometheus/common v0.39.0 // indirect + github.com/prometheus/common v0.37.1 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/tklauser/go-sysconf v0.3.5 // indirect - github.com/tklauser/numcpus v0.2.2 // indirect + github.com/tklauser/go-sysconf v0.3.11 // indirect + github.com/tklauser/numcpus v0.6.0 // indirect + github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc // indirect github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect + go.uber.org/atomic v1.6.0 // indirect golang.org/x/mod v0.6.0 // indirect - golang.org/x/net v0.4.0 // indirect + golang.org/x/net v0.6.0 // indirect golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index bf28cd2e2..b0e42a336 100644 --- a/go.sum +++ b/go.sum @@ -8,14 +8,31 @@ cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTj cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigtable v1.2.0/go.mod h1:JcVAOl45lrTmQfLj7T6TxyMzIN/3FGGcFm+2xVAli2o= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= collectd.org v0.3.0/go.mod h1:A/8DzQBkF6abtvrT2j/AU/4tiBgJWYyh0y/oB/4MlWE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= @@ -33,6 +50,7 @@ github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q github.com/DataDog/zstd v1.5.2 h1:vUG4lAyuPCXO0TLbXvPv7EB7cNK1QV/luu55UHLrrn8= github.com/DataDog/zstd v1.5.2/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= @@ -42,7 +60,10 @@ github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNu github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= @@ -82,6 +103,7 @@ github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -90,7 +112,12 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.14.0 h1:gFqGlGl/5f9UGXAaKapCGUfaTCgRKKnzu2VvzMZlOFA= github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/cockroach-go/v2 v2.2.0 h1:/5znzg5n373N/3ESjHF5SMLxiW4RKB05Ql//KWfeTFs= +github.com/cockroachdb/cockroach-go/v2 v2.2.0/go.mod h1:u3MiKYGupPPjkn3ozknpMUpxPaNLTFWAya419/zv6eI= github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= github.com/cockroachdb/datadriven v1.0.2/go.mod h1:a9RdTaap04u637JoCzcUoIcDmvwSUtcUFtT/C3kJlTU= github.com/cockroachdb/errors v1.9.1 h1:yFVvsI0VxmRShfawbt/laCIDy/mtTqqnvoNgiy5bEV8= @@ -110,12 +137,15 @@ github.com/consensys/gnark-crypto v0.9.1-0.20230105202408-1a7a29904a7c/go.mod h1 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7 h1:6IrxszG5G+O7zhtkWxq6+unVvnrm1fqV2Pe+T95DUzw= github.com/crate-crypto/go-ipa v0.0.0-20220523130400-f11357ae11c7/go.mod h1:gFnFS95y8HstDP6P9pPwzrxOOC5TRDkwbM+ao15ChAI= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/dave/jennifer v1.2.0/go.mod h1:fIb+770HOpJ2fmN9EPPKOqm1vMGhB+TwXKMZhrIygKg= @@ -156,6 +186,7 @@ github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaB github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= @@ -179,11 +210,13 @@ github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqG github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-verkle v0.0.0-20220902153445-097bd83b7732 h1:AB7YjNrzlVHsYz06zCULVV2zYCEft82P86dSmtwxKL0= github.com/gballet/go-verkle v0.0.0-20220902153445-097bd83b7732/go.mod h1:o/XfIXWi4/GqbQirfRm5uTbXMG5NpqxkxblnbZ+QM9I= +github.com/georgysavva/scany v1.2.1 h1:91PAMBpwBtDjvn46TaLQmuVhxpAG6p6sjQaU4zPHPSM= +github.com/georgysavva/scany v1.2.1/go.mod h1:vGBpL5XRLOocMFFa55pj0P04DrL3I7qKVRL49K6Eu5o= github.com/getkin/kin-openapi v0.53.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getkin/kin-openapi v0.61.0/go.mod h1:7Yn5whZr5kJi6t+kShccXS8ae1APpYTW6yheSwk8Yi4= github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c= -github.com/getsentry/sentry-go v0.18.0 h1:MtBW5H9QgdcJabtZcuJG80BMOwaBpkRDZkxRkNC1sN0= -github.com/getsentry/sentry-go v0.18.0/go.mod h1:Kgon4Mby+FJ7ZWHFUAZgVaIa8sxHtnRJRLTXZr51aKQ= +github.com/getsentry/sentry-go v0.17.0 h1:UustVWnOoDFHBS7IJUB2QK/nB5pap748ZEp0swnQJak= +github.com/getsentry/sentry-go v0.17.0/go.mod h1:B82dxtBvxG0KaPD8/hfSV+VcHD+Lg/xUS4JuQn1P4cM= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= @@ -195,11 +228,17 @@ github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= @@ -208,17 +247,27 @@ github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh github.com/go-sourcemap/sourcemap v2.1.3+incompatible h1:W1iEw64niKVGogNgBN3ePyLFfuisuzeidWPMPWmECqU= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-sql-driver/mysql v1.7.0 h1:ueSltNNllEqE3qcWBTD0iQd3IpL/6U+mJxLkazJ7YPc= +github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/googleapis v1.4.1/go.mod h1:2lpHqI5OcWCtVElxXnPt+s8oJvMpySlOyM6xDCrzib4= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= @@ -231,12 +280,19 @@ github.com/golang/geo v0.0.0-20190916061304-5b978397cfec/go.mod h1:QZ0nwyI2jOfgR github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -245,6 +301,7 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= @@ -263,6 +320,7 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= @@ -271,11 +329,17 @@ github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa h1:Q75Upo5UN4JbPFURXZ8nLKYUvF85dyFRop/vQ0Rv+64= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -288,11 +352,15 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e h1:pIYdhNkDh+YENVNi3gto8n9hAmRxKxoar0iE6BLucjw= github.com/holiman/big v0.0.0-20221017200358-a027dc42d04e/go.mod h1:j9cQbcqHQujT0oKJ38PylVfqohClLr3CvDC+Qcg+lhU= @@ -322,19 +390,122 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= +github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= +github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-block-format v0.0.3 h1:r8t66QstRp/pd/or4dpnbVfXT5Gt7lOqRvC+/dDTpMc= +github.com/ipfs/go-block-format v0.0.3/go.mod h1:4LmD4ZUw0mhO+JSKdpWwrzATiEfM7WWgQ8H5l6P8MVk= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.5/go.mod h1:plgt+Y5MnOey4vO4UlUazGqdbEXuFYitED67FexhXog= +github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= +github.com/ipfs/go-cid v0.2.0 h1:01JTiihFq9en9Vz0lc0VDWvZe/uBonGpzo4THP0vcQ0= +github.com/ipfs/go-cid v0.2.0/go.mod h1:P+HXFDF4CVhaVayiEb4wkAy7zBHxBwsJyt0Y5U6MLro= +github.com/ipfs/go-datastore v0.5.0 h1:rQicVCEacWyk4JZ6G5bD9TKR7lZEG1MWcG7UdWYrFAU= +github.com/ipfs/go-datastore v0.5.0/go.mod h1:9zhEApYMTl17C8YDp7JmU7sQZi2/wqiYh73hakZ90Bk= +github.com/ipfs/go-detect-race v0.0.1 h1:qX/xay2W3E4Q1U7d9lNs1sU9nvguX0a7319XbyQ6cOk= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ipfs-blockstore v1.2.0 h1:n3WTeJ4LdICWs/0VSfjHrlqpPpl6MZ+ySd3j8qz0ykw= +github.com/ipfs/go-ipfs-blockstore v1.2.0/go.mod h1:eh8eTFLiINYNSNawfZOC7HOxNTxpB1PFuA5E1m/7exE= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v1.1.0 h1:yLE2w9RAsl31LtfMt91tRZcrx+e61O5mDxFRR994w4Q= +github.com/ipfs/go-ipfs-ds-help v1.1.0/go.mod h1:YR5+6EaebOhfcqVCyqemItCLthrpVNot+rsOU/5IatU= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipfs-util v0.0.2 h1:59Sswnk1MFaiq+VcaknX7aYEyGyGDAA73ilhEK2POp8= +github.com/ipfs/go-ipfs-util v0.0.2/go.mod h1:CbPtkWJzjLdEcezDns2XYaehFVNXG9zrdrtMecczcsQ= +github.com/ipfs/go-ipld-format v0.3.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= +github.com/ipfs/go-ipld-format v0.4.0 h1:yqJSaJftjmjc9jEOFYlpkwOLVKv68OD27jFLlSghBlQ= +github.com/ipfs/go-ipld-format v0.4.0/go.mod h1:co/SdBE8h99968X0hViiw1MNlh6fvxxnHpvVLnH7jSM= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= github.com/iris-contrib/jade v1.1.3/go.mod h1:H/geBymxJhShH5kecoiOCSssPX7QWYH7UaeZTSWddIk= github.com/iris-contrib/pongo2 v0.0.1/go.mod h1:Ssh+00+3GAZqSQb30AvBRNxBx7rf0GqwkjqxNd0u65g= github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.4.0/go.mod h1:Y2O3ZDF0q4mMacyWV3AstPJpeHXWGEetiFttmq5lahk= +github.com/jackc/pgconn v1.5.0/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.5.1-0.20200601181101-fa742c524853/go.mod h1:QeD3lBfpTFe8WUnPZWN5KY/mB8FGMIYRdd8P8Jr0fAI= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.10.0 h1:4EYhlDVEMsJ30nNj0mmgwIUXoq7e9sMJrVC2ED6QlCU= +github.com/jackc/pgconn v1.10.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1 h1:7PQ/4gLoqnl87ZxL7xjO0DR5gYuviDCZxQJsUlFW1eI= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200307190119-3430c5407db8/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.2.0/go.mod h1:5m2OfMh1wTK7x+Fk952IDmI4nw3nPrvtQdM0ZT4WpC0= +github.com/jackc/pgtype v1.3.1-0.20200510190516-8cd94a14c75a/go.mod h1:vaogEUkALtxZMCH411K+tKzNpwzCKU+AnPzBKZ+I+Po= +github.com/jackc/pgtype v1.3.1-0.20200606141011-f6355165a91c/go.mod h1:cvk9Bgu/VzJ9/lxTO5R5sf80p0DiucVtN7ZxvaC4GmQ= +github.com/jackc/pgtype v1.6.2/go.mod h1:JCULISAZBFGrHaOXIIFiyfzW5VY0GRitRr8NeJsrdig= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.8.1 h1:9k0IXtdJXHJbyAWQgbWr1lU+MEhPXZz6RIXxfR5oxXs= +github.com/jackc/pgtype v1.8.1/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.5.0/go.mod h1:EpAKPLdnTorwmPUUsqrPxy5fphV18j9q3wrfRXgo+kA= +github.com/jackc/pgx/v4 v4.6.1-0.20200510190926-94ba730bb1e9/go.mod h1:t3/cdRQl6fOLDxqtlyhe9UWgfIi9R8+8v8GKV5TRA/o= +github.com/jackc/pgx/v4 v4.6.1-0.20200606145419-4e5062306904/go.mod h1:ZDaNWkt9sW1JMiNn0kdYBaLelIhw7Pg4qd+Vk6tw7Hg= +github.com/jackc/pgx/v4 v4.10.1/go.mod h1:QlrWebbs3kqEZPHCTGyxecvzG6tvIsYu+A5b1raylkA= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.13.0 h1:JCjhT5vmhMAf/YwBHLvrBn4OGdIQBiFG6ym8Zmdx570= +github.com/jackc/pgx/v4 v4.13.0/go.mod h1:9P4X524sErlaxj0XSGZk7s+LD0eOyu1ZDUrrpznYDF0= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3 h1:JnPg/5Q9xVJGfjsO5CPUOjnJps1JaRUm8I9FXVCFK94= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= +github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e h1:UvSe12bq+Uj2hWd8aOlwPmoZ+CITRFrdit+sDGfAg8U= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= +github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= +github.com/jinzhu/now v1.1.1/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/jmoiron/sqlx v1.3.1/go.mod h1:2BljVx/86SuTyjE+aPYlHCTNvZrnJXghYGpNiXLBMCQ= +github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= +github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= @@ -352,6 +523,7 @@ github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYb github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE= github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro= github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -362,16 +534,23 @@ github.com/klauspost/compress v1.15.15 h1:EF27CXIuDsYJ6mmvtBRlEuB2UVOqHG1tAXgZ7y github.com/klauspost/compress v1.15.15/go.mod h1:ZcK2JAFqKOpnBlxcLsJzYfrS9X1akm9fHZNnD9+Vo/4= github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= @@ -383,18 +562,28 @@ github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= @@ -406,6 +595,9 @@ github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzp github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-sqlite3 v1.11.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y= +github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= github.com/mattn/go-tty v0.0.0-20180907095812-13ff1204f104/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE= github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -413,6 +605,12 @@ github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zk github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8= github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= +github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= @@ -426,10 +624,31 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= +github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mschoch/smat v0.0.0-20160514031455-90eadee771ae/go.mod h1:qAyveg+e4CE+eKJXWVjKXM4ck2QobLqTDytGJbLLhJg= +github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp8Nq/kkI= +github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= +github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= +github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= +github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= +github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.14/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= +github.com/multiformats/go-multihash v0.0.15 h1:hWOPdrNqDjwHDx82vsYGSDZNyktOJJ2dzZJzFkOV1jM= +github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= +github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= +github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/naoina/go-stringutil v0.1.0 h1:rCUeRUHjBjGTSHl0VC00jUPLz8/F9dDzYI70Hzifhks= github.com/naoina/go-stringutil v0.1.0/go.mod h1:XJ2SJL9jCtBh+P9q5btrd/Ylo8XwT/h1USek5+NqSA0= github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcouEdwIeOtOGA/ELRUw/GwvxwfT+0= @@ -460,6 +679,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/peterh/liner v1.0.1-0.20180619022028-8c1271fcf47f/go.mod h1:xIteQHvHuaLYG9IFj6mSxM0fCKrs34IrEQUhOYuGPHc= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 h1:oYW+YCJ1pachXTQmzR3rNLYGGz4g/UgFcjb28p/viDM= github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= +github.com/pganalyze/pg_query_go/v2 v2.2.0 h1:OW+reH+ZY7jdEuPyuLGlf1m7dLbE+fDudKXhLs0Ttpk= +github.com/pganalyze/pg_query_go/v2 v2.2.0/go.mod h1:XAxmVqz1tEGqizcQ3YSdN90vCOHBWjJi8URL1er5+cA= github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= @@ -474,20 +695,30 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.39.0 h1:oOyhkDq05hPZKItWVBkJ6g6AtGxi+fy7F4JvUV8uhsI= -github.com/prometheus/common v0.39.0/go.mod h1:6XBZ7lYdLCbkAVhwRsWTZn+IN5AB9F/NXd5w0BbEX0Y= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.37.1 h1:pYY6b5sGXqEB0WwcRGAoVGKbxVthy9qF17R4gbHZVe0= +github.com/prometheus/common v0.37.1/go.mod h1:jEuMeTn4pKGSAxwr7rXtOD70GeY0ERpt0d9FkKf9sK4= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= @@ -500,22 +731,34 @@ github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZV github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -527,6 +770,8 @@ github.com/status-im/keycard-go v0.2.0 h1:QDLFswOQu1r5jsycloeQh3bVU8n/NatHHaZobt github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9+mHxBEeo3Hbg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= @@ -541,11 +786,13 @@ github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344 h1:m+8fKfQwCA github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= +github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw= +github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= -github.com/tklauser/go-sysconf v0.3.5 h1:uu3Xl4nkLzQfXNsWn15rPc/HQCJKObbt1dKJeWp3vU4= -github.com/tklauser/go-sysconf v0.3.5/go.mod h1:MkWzOF4RMCshBAMXuhXJs64Rte09mITnppBXY/rYEFI= -github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefldA= -github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= +github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= +github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= +github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= +github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= @@ -561,6 +808,8 @@ github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBn github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= @@ -573,31 +822,56 @@ github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmv github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190909091759-094676da4a83/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191227163750-53104e6ec876/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= +golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -608,6 +882,9 @@ golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm0 golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20230206171751-46f607a40771 h1:xP7rWLUr1e1n2xkK5YB4LI0hPEy3LJC6Wk+D4pGlOJg= golang.org/x/exp v0.0.0-20230206171751-46f607a40771/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= @@ -621,15 +898,20 @@ golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -639,6 +921,7 @@ golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -647,11 +930,24 @@ golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -660,24 +956,34 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.6.0 h1:L4ZwwTvKW9gr0ZMS1yrHD9GZhIuVjOBBnaKH+SPQK0Q= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -687,9 +993,12 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -697,40 +1006,67 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200107162124-548cf772de50/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210316164454-77fc1eacc6aa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -739,14 +1075,17 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -760,27 +1099,53 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200108203644-89082a384178/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -800,11 +1165,21 @@ google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -820,7 +1195,23 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200108215221-bd8f9a0ef82f/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -830,6 +1221,11 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -839,6 +1235,7 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= @@ -854,6 +1251,7 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= @@ -864,6 +1262,7 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= @@ -873,12 +1272,19 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gorm.io/driver/postgres v1.0.8/go.mod h1:4eOzrI1MUfm6ObJU/UcmbXyiHSs8jSwH95G5P5dxcAg= +gorm.io/gorm v1.20.12/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= +gorm.io/gorm v1.21.4/go.mod h1:0HFTzE/SqkGTzK6TlDPPQbAYCluiVvhzoA1+aVyzenw= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA= diff --git a/metrics/prometheus/collector.go b/metrics/prometheus/collector.go index e8d5e4f5d..76bece915 100644 --- a/metrics/prometheus/collector.go +++ b/metrics/prometheus/collector.go @@ -82,6 +82,9 @@ func (c *collector) addTimer(name string, m metrics.Timer) { c.writeSummaryPercentile(name, strconv.FormatFloat(pv[i], 'f', -1, 64), ps[i]) } c.buff.WriteRune('\n') + + c.buff.WriteString(fmt.Sprintf(typeGaugeTpl, mutateKey(name+"_total"))) + c.buff.WriteString(fmt.Sprintf(keyValueTpl, mutateKey(name+"_total"), m.Total())) } func (c *collector) addResettingTimer(name string, m metrics.ResettingTimer) { diff --git a/metrics/prometheus/collector_test.go b/metrics/prometheus/collector_test.go index 43f2f804d..194ff5541 100644 --- a/metrics/prometheus/collector_test.go +++ b/metrics/prometheus/collector_test.go @@ -92,6 +92,9 @@ test_timer {quantile="0.99"} 1.2e+08 test_timer {quantile="0.999"} 1.2e+08 test_timer {quantile="0.9999"} 1.2e+08 +# TYPE test_timer_total gauge +test_timer_total 230000000 + # TYPE test_resetting_timer_count counter test_resetting_timer_count 6 diff --git a/metrics/timer.go b/metrics/timer.go index a63c9dfb6..3d68c3135 100644 --- a/metrics/timer.go +++ b/metrics/timer.go @@ -25,6 +25,7 @@ type Timer interface { Update(time.Duration) UpdateSince(time.Time) Variance() float64 + Total() int64 } // GetOrRegisterTimer returns an existing Timer or constructs and registers a @@ -47,6 +48,7 @@ func NewCustomTimer(h Histogram, m Meter) Timer { return &StandardTimer{ histogram: h, meter: m, + total: NewCounter(), } } @@ -72,6 +74,7 @@ func NewTimer() Timer { return &StandardTimer{ histogram: NewHistogram(NewExpDecaySample(1028, 0.015)), meter: NewMeter(), + total: NewCounter(), } } @@ -134,11 +137,15 @@ func (NilTimer) UpdateSince(time.Time) {} // Variance is a no-op. func (NilTimer) Variance() float64 { return 0.0 } +// Total is a no-op. +func (NilTimer) Total() int64 { return int64(0) } + // StandardTimer is the standard implementation of a Timer and uses a Histogram // and Meter. type StandardTimer struct { histogram Histogram meter Meter + total Counter mutex sync.Mutex } @@ -200,6 +207,7 @@ func (t *StandardTimer) Snapshot() Timer { return &TimerSnapshot{ histogram: t.histogram.Snapshot().(*HistogramSnapshot), meter: t.meter.Snapshot().(*MeterSnapshot), + total: t.total.Snapshot().(CounterSnapshot), } } @@ -231,14 +239,12 @@ func (t *StandardTimer) Update(d time.Duration) { defer t.mutex.Unlock() t.histogram.Update(int64(d)) t.meter.Mark(1) + t.total.Inc(int64(d)) } // Record the duration of an event that started at a time and ends now. func (t *StandardTimer) UpdateSince(ts time.Time) { - t.mutex.Lock() - defer t.mutex.Unlock() - t.histogram.Update(int64(time.Since(ts))) - t.meter.Mark(1) + t.Update(time.Since(ts)) } // Variance returns the variance of the values in the sample. @@ -246,10 +252,18 @@ func (t *StandardTimer) Variance() float64 { return t.histogram.Variance() } +// Total returns the total time the timer has run in nanoseconds. +// This differs from Sum in that it is a simple counter, not based +// on a histogram Sample. +func (t *StandardTimer) Total() int64 { + return t.total.Count() +} + // TimerSnapshot is a read-only copy of another Timer. type TimerSnapshot struct { histogram *HistogramSnapshot meter *MeterSnapshot + total CounterSnapshot } // Count returns the number of events recorded at the time the snapshot was @@ -324,3 +338,6 @@ func (*TimerSnapshot) UpdateSince(time.Time) { // Variance returns the variance of the values at the time the snapshot was // taken. func (t *TimerSnapshot) Variance() float64 { return t.histogram.Variance() } + +// Total returns the total time the timer has run in nanoseconds. +func (t *TimerSnapshot) Total() int64 { return t.total.Count() } diff --git a/mobile/android_test.go b/mobile/android_test.go new file mode 100644 index 000000000..71ab8d9a4 --- /dev/null +++ b/mobile/android_test.go @@ -0,0 +1,262 @@ +// Copyright 2016 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package geth + +import ( + "os" + "os/exec" + "path/filepath" + "runtime" + "testing" + "time" + + "github.com/cespare/cp" +) + +// androidTestClass is a Java class to do some lightweight tests against the Android +// bindings. The goal is not to test each individual functionality, rather just to +// catch breaking API and/or implementation changes. +const androidTestClass = ` +package go; + +import android.test.InstrumentationTestCase; +import android.test.MoreAsserts; + +import java.math.BigInteger; +import java.util.Arrays; + +import org.ethereum.geth.*; + +public class AndroidTest extends InstrumentationTestCase { + public AndroidTest() {} + + public void testAccountManagement() { + // Create an encrypted keystore with light crypto parameters. + KeyStore ks = new KeyStore(getInstrumentation().getContext().getFilesDir() + "/keystore", Geth.LightScryptN, Geth.LightScryptP); + + try { + // Create a new account with the specified encryption passphrase. + Account newAcc = ks.newAccount("Creation password"); + + // Export the newly created account with a different passphrase. The returned + // data from this method invocation is a JSON encoded, encrypted key-file. + byte[] jsonAcc = ks.exportKey(newAcc, "Creation password", "Export password"); + + // Update the passphrase on the account created above inside the local keystore. + ks.updateAccount(newAcc, "Creation password", "Update password"); + + // Delete the account updated above from the local keystore. + ks.deleteAccount(newAcc, "Update password"); + + // Import back the account we've exported (and then deleted) above with yet + // again a fresh passphrase. + Account impAcc = ks.importKey(jsonAcc, "Export password", "Import password"); + + // Create a new account to sign transactions with + Account signer = ks.newAccount("Signer password"); + + Transaction tx = new Transaction( + 1, new Address("0x0000000000000000000000000000000000000000"), + new BigInt(0), 0, new BigInt(1), null); // Random empty transaction + BigInt chain = new BigInt(1); // Chain identifier of the main net + + // Sign a transaction with a single authorization + Transaction signed = ks.signTxPassphrase(signer, "Signer password", tx, chain); + + // Sign a transaction with multiple manually cancelled authorizations + ks.unlock(signer, "Signer password"); + signed = ks.signTx(signer, tx, chain); + ks.lock(signer.getAddress()); + + // Sign a transaction with multiple automatically cancelled authorizations + ks.timedUnlock(signer, "Signer password", 1000000000); + signed = ks.signTx(signer, tx, chain); + } catch (Exception e) { + fail(e.toString()); + } + } + + public void testInprocNode() { + Context ctx = new Context(); + + try { + // Start up a new inprocess node + Node node = new Node(getInstrumentation().getContext().getFilesDir() + "/.ethereum", new NodeConfig()); + node.start(); + + // Retrieve some data via function calls (we don't really care about the results) + NodeInfo info = node.getNodeInfo(); + info.getName(); + info.getListenerAddress(); + info.getProtocols(); + + // Retrieve some data via the APIs (we don't really care about the results) + EthereumClient ec = node.getEthereumClient(); + ec.getBlockByNumber(ctx, -1).getNumber(); + + NewHeadHandler handler = new NewHeadHandler() { + @Override public void onError(String error) {} + @Override public void onNewHead(final Header header) {} + }; + ec.subscribeNewHead(ctx, handler, 16); + } catch (Exception e) { + fail(e.toString()); + } + } + + // Tests that recovering transaction signers works for both Homestead and EIP155 + // signatures too. Regression test for go-ethereum issue #14599. + public void testIssue14599() { + try { + byte[] preEIP155RLP = new BigInteger("f901fc8032830138808080b901ae60056013565b6101918061001d6000396000f35b3360008190555056006001600060e060020a6000350480630a874df61461003a57806341c0e1b514610058578063a02b161e14610066578063dbbdf0831461007757005b610045600435610149565b80600160a060020a031660005260206000f35b610060610161565b60006000f35b6100716004356100d4565b60006000f35b61008560043560243561008b565b60006000f35b600054600160a060020a031632600160a060020a031614156100ac576100b1565b6100d0565b8060018360005260205260406000208190555081600060005260206000a15b5050565b600054600160a060020a031633600160a060020a031614158015610118575033600160a060020a0316600182600052602052604060002054600160a060020a031614155b61012157610126565b610146565b600060018260005260205260406000208190555080600060005260206000a15b50565b60006001826000526020526040600020549050919050565b600054600160a060020a031633600160a060020a0316146101815761018f565b600054600160a060020a0316ff5b561ca0c5689ed1ad124753d54576dfb4b571465a41900a1dff4058d8adf16f752013d0a01221cbd70ec28c94a3b55ec771bcbc70778d6ee0b51ca7ea9514594c861b1884", 16).toByteArray(); + preEIP155RLP = Arrays.copyOfRange(preEIP155RLP, 1, preEIP155RLP.length); + + byte[] postEIP155RLP = new BigInteger("f86b80847735940082520894ef5bbb9bba2e1ca69ef81b23a8727d889f3ef0a1880de0b6b3a7640000802ba06fef16c44726a102e6d55a651740636ef8aec6df3ebf009e7b0c1f29e4ac114aa057e7fbc69760b522a78bb568cfc37a58bfdcf6ea86cb8f9b550263f58074b9cc", 16).toByteArray(); + postEIP155RLP = Arrays.copyOfRange(postEIP155RLP, 1, postEIP155RLP.length); + + Transaction preEIP155 = new Transaction(preEIP155RLP); + Transaction postEIP155 = new Transaction(postEIP155RLP); + + preEIP155.getFrom(null); // Homestead should accept homestead + preEIP155.getFrom(new BigInt(4)); // EIP155 should accept homestead (missing chain ID) + postEIP155.getFrom(new BigInt(4)); // EIP155 should accept EIP 155 + + try { + postEIP155.getFrom(null); + fail("EIP155 transaction accepted by Homestead"); + } catch (Exception e) {} + } catch (Exception e) { + fail(e.toString()); + } + } +} +` + +// TestAndroid runs the Android java test class specified above. +// +// This requires the gradle command in PATH and the Android SDK whose path is available +// through ANDROID_HOME environment variable. To successfully run the tests, an Android +// device must also be available with debugging enabled. +// +// This method has been adapted from golang.org/x/mobile/bind/java/seq_test.go/runTest +func TestAndroid(t *testing.T) { + t.Skip("Skipping this test for statediff as this is not relevant") + // Skip tests on Windows altogether + if runtime.GOOS == "windows" { + t.Skip("cannot test Android bindings on Windows, skipping") + } + // Make sure all the Android tools are installed + if _, err := exec.Command("which", "gradle").CombinedOutput(); err != nil { + t.Skip("command gradle not found, skipping") + } + if sdk := os.Getenv("ANDROID_HOME"); sdk == "" { + // Android SDK not explicitly given, try to auto-resolve + autopath := filepath.Join(os.Getenv("HOME"), "Android", "Sdk") + if _, err := os.Stat(autopath); err != nil { + t.Skip("ANDROID_HOME environment var not set, skipping") + } + os.Setenv("ANDROID_HOME", autopath) + } + if _, err := exec.Command("which", "gomobile").CombinedOutput(); err != nil { + t.Log("gomobile missing, installing it...") + if out, err := exec.Command("go", "get", "golang.org/x/mobile/cmd/gomobile").CombinedOutput(); err != nil { + t.Fatalf("install failed: %v\n%s", err, string(out)) + } + t.Log("initializing gomobile...") + start := time.Now() + if _, err := exec.Command("gomobile", "init").CombinedOutput(); err != nil { + t.Fatalf("initialization failed: %v", err) + } + t.Logf("initialization took %v", time.Since(start)) + } + // Create and switch to a temporary workspace + workspace := t.TempDir() + + pwd, err := os.Getwd() + if err != nil { + t.Fatalf("failed to get current working directory: %v", err) + } + if err := os.Chdir(workspace); err != nil { + t.Fatalf("failed to switch to temporary workspace: %v", err) + } + defer os.Chdir(pwd) + + // Create the skeleton of the Android project + for _, dir := range []string{"src/main", "src/androidTest/java/org/ethereum/gethtest", "libs"} { + err = os.MkdirAll(dir, os.ModePerm) + if err != nil { + t.Fatal(err) + } + } + // Generate the mobile bindings for Geth and add the tester class + gobind := exec.Command("gomobile", "bind", "-javapkg", "org.ethereum", "github.com/ethereum/go-ethereum/mobile") + if output, err := gobind.CombinedOutput(); err != nil { + t.Logf("%s", output) + t.Fatalf("failed to run gomobile bind: %v", err) + } + cp.CopyFile(filepath.Join("libs", "geth.aar"), "geth.aar") + + if err = os.WriteFile(filepath.Join("src", "androidTest", "java", "org", "ethereum", "gethtest", "AndroidTest.java"), []byte(androidTestClass), os.ModePerm); err != nil { + t.Fatalf("failed to write Android test class: %v", err) + } + // Finish creating the project and run the tests via gradle + if err = os.WriteFile(filepath.Join("src", "main", "AndroidManifest.xml"), []byte(androidManifest), os.ModePerm); err != nil { + t.Fatalf("failed to write Android manifest: %v", err) + } + if err = os.WriteFile("build.gradle", []byte(gradleConfig), os.ModePerm); err != nil { + t.Fatalf("failed to write gradle build file: %v", err) + } + if output, err := exec.Command("gradle", "connectedAndroidTest").CombinedOutput(); err != nil { + t.Logf("%s", output) + t.Errorf("failed to run gradle test: %v", err) + } +} + +const androidManifest = ` + + + +` + +const gradleConfig = `buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:2.2.3' + } +} +allprojects { + repositories { jcenter() } +} +apply plugin: 'com.android.library' +android { + compileSdkVersion 'android-19' + buildToolsVersion '21.1.2' + defaultConfig { minSdkVersion 15 } +} +repositories { + flatDir { dirs 'libs' } +} +dependencies { + compile 'com.android.support:appcompat-v7:19.0.0' + compile(name: "geth", ext: "aar") +} +` diff --git a/params/config.go b/params/config.go index 816577a54..76d6a898e 100644 --- a/params/config.go +++ b/params/config.go @@ -440,6 +440,9 @@ type ChainConfig struct { // the network that triggers the consensus upgrade. TerminalTotalDifficulty *big.Int `json:"terminalTotalDifficulty,omitempty"` + // Cap the maximum total difficulty (for testnet use only). + CappedMaximumDifficulty *big.Int `json:"cappedMaximumDifficulty,omitempty"` + // TerminalTotalDifficultyPassed is a flag specifying that the network already // passed the terminal total difficulty. Its purpose is to disable legacy sync // even without having seen the TTD locally (safer long term). @@ -482,7 +485,11 @@ func (c *ChainConfig) Description() string { switch { case c.Ethash != nil: if c.TerminalTotalDifficulty == nil { - banner += "Consensus: Ethash (proof-of-work)\n" + if nil == c.CappedMaximumDifficulty { + banner += "Consensus: Ethash (proof-of-work)\n" + } else { + banner += fmt.Sprintf("Consensus: Ethash (proof-of-work, capped difficulty at %d)\n", c.CappedMaximumDifficulty) + } } else if !c.TerminalTotalDifficultyPassed { banner += "Consensus: Beacon (proof-of-stake), merging from Ethash (proof-of-work)\n" } else { @@ -497,7 +504,11 @@ func (c *ChainConfig) Description() string { banner += "Consensus: Beacon (proof-of-stake), merged from Clique (proof-of-authority)\n" } default: - banner += "Consensus: unknown\n" + if nil == c.CappedMaximumDifficulty { + banner += "Consensus: unknown\n" + } else { + banner += fmt.Sprintf("Consensus: unknown (capped difficulty at %d)\n", c.CappedMaximumDifficulty) + } } banner += "\n" diff --git a/params/version.go b/params/version.go index 8bbf0b99b..40fdeb073 100644 --- a/params/version.go +++ b/params/version.go @@ -21,10 +21,10 @@ import ( ) const ( - VersionMajor = 1 // Major version component of the current release - VersionMinor = 11 // Minor version component of the current release - VersionPatch = 2 // Patch version component of the current release - VersionMeta = "stable" // Version metadata to append to the version string + VersionMajor = 1 // Major version component of the current release + VersionMinor = 11 // Minor version component of the current release + VersionPatch = 2 // Patch version component of the current release + VersionMeta = "statediff-4.3.7-alpha" // Version metadata to append to the version string ) // Version holds the textual version string. diff --git a/rpc/http.go b/rpc/http.go index 8712f9961..8a9a69acb 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -33,7 +33,7 @@ import ( ) const ( - maxRequestContentLength = 1024 * 1024 * 5 + maxRequestContentLength = 1024 * 1024 * 12 contentType = "application/json" ) diff --git a/scripts/run_unit_test.sh b/scripts/run_unit_test.sh new file mode 100755 index 000000000..b449090f6 --- /dev/null +++ b/scripts/run_unit_test.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +mkdir -p out + +# Remove existing docker-tsdb directory +rm -rf out/docker-tsdb/ + +# Copy over files to setup TimescaleDB +ID=$(docker create vulcanize/ipld-eth-db:v4.1.1-alpha) +docker cp $ID:/app/docker-tsdb out/docker-tsdb/ +docker rm -v $ID + +# Spin up TimescaleDB +docker-compose -f out/docker-tsdb/docker-compose.test.yml -f docker-compose.yml up ipld-eth-db +sleep 45 + +# Run unit tests +go clean -testcache +make statedifftest + +# Clean up +docker-compose -f out/docker-tsdb/docker-compose.test.yml -f docker-compose.yml down --remove-orphans --volumes +rm -rf out/docker-tsdb/ diff --git a/statediff/README.md b/statediff/README.md new file mode 100644 index 000000000..56a2fffd2 --- /dev/null +++ b/statediff/README.md @@ -0,0 +1,320 @@ +# Statediff + +This package provides an auxiliary service that asynchronously processes state diff objects from chain events, +either relaying the state objects to RPC subscribers or writing them directly to Postgres as IPLD objects. + +It also exposes RPC endpoints for fetching or writing to Postgres the state diff at a specific block height +or for a specific block hash, this operates on historical block and state data and so depends on a complete state archive. + +Data is emitted in this differential format in order to make it feasible to IPLD-ize and index the _entire_ Ethereum state +(including intermediate state and storage trie nodes). If this state diff process is ran continuously from genesis, +the entire state at any block can be materialized from the cumulative differentials up to that point. + +## Statediff object + +A state diff `StateObject` is the collection of all the state and storage trie nodes that have been updated in a given block. +For convenience, we also associate these nodes with the block number and hash, and optionally the set of code hashes and code for any +contracts deployed in this block. + +A complete state diff `StateObject` will include all state and storage intermediate nodes, which is necessary for generating proofs and for +traversing the tries. + +```go +// StateObject is a collection of state (and linked storage nodes) as well as the associated block number, block hash, +// and a set of code hashes and their code +type StateObject struct { + BlockNumber *big.Int `json:"blockNumber" gencodec:"required"` + BlockHash common.Hash `json:"blockHash" gencodec:"required"` + Nodes []StateNode `json:"nodes" gencodec:"required"` + CodeAndCodeHashes []CodeAndCodeHash `json:"codeMapping"` +} + +// StateNode holds the data for a single state diff node +type StateNode struct { + NodeType NodeType `json:"nodeType" gencodec:"required"` + Path []byte `json:"path" gencodec:"required"` + NodeValue []byte `json:"value" gencodec:"required"` + StorageNodes []StorageNode `json:"storage"` + LeafKey []byte `json:"leafKey"` +} + +// StorageNode holds the data for a single storage diff node +type StorageNode struct { + NodeType NodeType `json:"nodeType" gencodec:"required"` + Path []byte `json:"path" gencodec:"required"` + NodeValue []byte `json:"value" gencodec:"required"` + LeafKey []byte `json:"leafKey"` +} + +// CodeAndCodeHash struct for holding codehash => code mappings +// we can't use an actual map because they are not rlp serializable +type CodeAndCodeHash struct { + Hash common.Hash `json:"codeHash"` + Code []byte `json:"code"` +} +``` + +These objects are packed into a `Payload` structure which can additionally associate the `StateObject` +with the block (header, uncles, and transactions), receipts, and total difficulty. +This `Payload` encapsulates all of the differential data at a given block, and allows us to index the entire Ethereum data structure +as hash-linked IPLD objects. + +```go +// Payload packages the data to send to state diff subscriptions +type Payload struct { + BlockRlp []byte `json:"blockRlp"` + TotalDifficulty *big.Int `json:"totalDifficulty"` + ReceiptsRlp []byte `json:"receiptsRlp"` + StateObjectRlp []byte `json:"stateObjectRlp" gencodec:"required"` + + encoded []byte + err error +} +``` + +## Usage + +This state diffing service runs as an auxiliary service concurrent to the regular syncing process of the geth node. + +### CLI configuration + +This service introduces a CLI flag namespace `statediff` + +`--statediff` flag is used to turn on the service + +`--statediff.writing` is used to tell the service to write state diff objects it produces from synced ChainEvents directly to a configured Postgres database + +`--statediff.workers` is used to set the number of concurrent workers to process state diff objects and write them into the database + +`--statediff.db.type` is the type of database we write out to (current options: postgres, dump, file) + +`--statediff.dump.dst` is the destination to write to when operating in database dump mode (stdout, stderr, discard) + +`--statediff.db.driver` is the specific driver to use for the database (current options for postgres: pgx and sqlx) + +`--statediff.db.host` is the hostname/ip to dial to connect to the database + +`--statediff.db.port` is the port to dial to connect to the database + +`--statediff.db.name` is the name of the database to connect to + +`--statediff.db.user` is the user to connect to the database as + +`--statediff.db.password` is the password to use to connect to the database + +`--statediff.db.conntimeout` is the connection timeout (in seconds) + +`--statediff.db.maxconns` is the maximum number of database connections + +`--statediff.db.minconns` is the minimum number of database connections + +`--statediff.db.maxidleconns` is the maximum number of idle connections + +`--statediff.db.maxconnidletime` is the maximum lifetime for an idle connection (in seconds) + +`--statediff.db.maxconnlifetime` is the maximum lifetime for a connection (in seconds) + +`--statediff.db.nodeid` is the node id to use in the Postgres database + +`--statediff.db.clientname` is the client name to use in the Postgres database + +`--statediff.db.upsert` whether or not the service, when operating in a direct database writing mode, should overwrite any existing conflicting data + +`--statediff.file.path` full path (including filename) to write statediff data out to when operating in file mode + +`--statediff.file.wapath` full path (including filename) to write statediff watched addresses out to when operating in file mode + +The service can only operate in full sync mode (`--syncmode=full`), but only the historical RPC endpoints require an archive node (`--gcmode=archive`) + +e.g. +`./build/bin/geth --syncmode=full --gcmode=archive --statediff --statediff.writing --statediff.db.type=postgres --statediff.db.driver=sqlx --statediff.db.host=localhost --statediff.db.port=5432 --statediff.db.name=vulcanize_test --statediff.db.user=postgres --statediff.db.nodeid=nodeid --statediff.db.clientname=clientname` + +When operating in `--statediff.db.type=file` mode, the service will write SQL statements out to the file designated by +`--statediff.file.path`. Please note that it writes out SQL statements with all `ON CONFLICT` constraint checks dropped. +This is done so that we can scale out the production of the SQL statements horizontally, merge the separate SQL files produced, +de-duplicate using unix tools (`sort statediff.sql | uniq` or `sort -u statediff.sql`), bulk load using psql +(`psql db_name --set ON_ERROR_STOP=on -f statediff.sql`), and then add our primary and foreign key constraints and indexes +back afterwards. + +### RPC endpoints + +The state diffing service exposes both a WS subscription endpoint, and a number of HTTP unary endpoints. + +Each of these endpoints requires a set of parameters provided by the caller + +```go +// Params is used to carry in parameters from subscribing/requesting clients configuration +type Params struct { + IntermediateStateNodes bool + IntermediateStorageNodes bool + IncludeBlock bool + IncludeReceipts bool + IncludeTD bool + IncludeCode bool + WatchedAddresses []common.Address +} +``` + +Using these params we can tell the service whether to include state and/or storage intermediate nodes; whether +to include the associated block (header, uncles, and transactions); whether to include the associated receipts; +whether to include the total difficulty for this block; whether to include the set of code hashes and code for +contracts deployed in this block; whether to limit the diffing process to a list of specific addresses. + +#### Subscription endpoint + +A websocket supporting RPC endpoint is exposed for subscribing to state diff `StateObjects` that come off the head of the chain while the geth node syncs. + +```go +// Stream is a subscription endpoint that fires off state diff payloads as they are created +Stream(ctx context.Context, params Params) (*rpc.Subscription, error) +``` + +To expose this endpoint the node needs to have the websocket server turned on (`--ws`), +and the `statediff` namespace exposed (`--ws.api=statediff`). + +Go code subscriptions to this endpoint can be created using the `rpc.Client.Subscribe()` method, +with the "statediff" namespace, a `statediff.Payload` channel, and the name of the statediff api's rpc method: "stream". + +e.g. + +```go + +cli, err := rpc.Dial("ipcPathOrWsURL") +if err != nil { + // handle error +} +stateDiffPayloadChan := make(chan statediff.Payload, 20000) +methodName := "stream" +params := statediff.Params{ + IncludeBlock: true, + IncludeTD: true, + IncludeReceipts: true, + IntermediateStorageNodes: true, + IntermediateStateNodes: true, +} +rpcSub, err := cli.Subscribe(context.Background(), statediff.APIName, stateDiffPayloadChan, methodName, params) +if err != nil { + // handle error +} +for { + select { + case stateDiffPayload := <- stateDiffPayloadChan: + // process the payload + case err := <- rpcSub.Err(): + // handle rpc subscription error + } +} +``` + +#### Unary endpoints + +The service also exposes unary RPC endpoints for retrieving the state diff `StateObject` for a specific block height/hash. + +```go +// StateDiffAt returns a state diff payload at the specific blockheight +StateDiffAt(ctx context.Context, blockNumber uint64, params Params) (*Payload, error) + +// StateDiffFor returns a state diff payload for the specific blockhash +StateDiffFor(ctx context.Context, blockHash common.Hash, params Params) (*Payload, error) +``` + +To expose this endpoint the node needs to have the HTTP server turned on (`--http`), +and the `statediff` namespace exposed (`--http.api=statediff`). + +### Direct indexing into Postgres + +If `--statediff.writing` is set, the service will convert the state diff `StateObject` data into IPLD objects, persist them directly to Postgres, +and generate secondary indexes around the IPLD data. + +The schema and migrations for this Postgres database are provided in `statediff/db/`. + +#### Postgres setup + +We use [pressly/goose](https://github.com/pressly/goose) as our Postgres migration manager. +You can also load the Postgres schema directly into a database using + +`psql database_name < schema.sql` + +This will only work on a version 12.4 Postgres database. + +#### Schema overview + +Our Postgres schemas are built around a single IPFS backing Postgres IPLD blockstore table (`public.blocks`) that conforms with [go-ds-sql](https://github.com/ipfs/go-ds-sql/blob/master/postgres/postgres.go). +All IPLD objects are stored in this table, where `key` is the blockstore-prefixed multihash key for the IPLD object and `data` contains +the bytes for the IPLD block (in the case of all Ethereum IPLDs, this is the RLP byte encoding of the Ethereum object). + +The IPLD objects in this table can be traversed using an IPLD DAG interface, but since this table only maps multihash to raw IPLD object +it is not particularly useful for searching through the data by looking up Ethereum objects by their constituent fields +(e.g. by block number, tx source/recipient, state/storage trie node path). To improve the accessibility of these objects +we create an Ethereum [advanced data layout](https://github.com/ipld/specs#schemas-and-advanced-data-layouts) (ADL) by generating secondary +indexes on top of the raw IPLDs in other Postgres tables. + +These secondary index tables fall under the `eth` schema and follow an `{objectType}_cids` naming convention. +These tables provide a view into individual fields of the underlying Ethereum IPLD objects, allowing lookups on these fields, and reference the raw IPLD objects stored in `public.blocks` +by foreign keys to their multihash keys. +Additionally, these tables maintain the hash-linked nature of Ethereum objects to one another. E.g. a storage trie node entry in the `storage_cids` +table contains a `state_id` foreign key which references the `id` for the `state_cids` entry that contains the state leaf node for the contract that storage node belongs to, +and in turn that `state_cids` entry contains a `header_id` foreign key which references the `id` of the `header_cids` entry that contains the header for the block these state and storage nodes were updated (diffed). + +### Optimization + +On mainnet this process is extremely IO intensive and requires significant resources to allow it to keep up with the head of the chain. +The state diff processing time for a specific block is dependent on the number and complexity of the state changes that occur in a block and +the number of updated state nodes that are available in the in-memory cache vs must be retrieved from disc. + +If memory permits, one means of improving the efficiency of this process is to increase the in-memory trie cache allocation. +This can be done by increasing the overall `--cache` allocation and/or by increasing the % of the cache allocated to trie +usage with `--cache.trie`. + +## Versioning, Branches, Rebasing, and Releasing + +Internal tagged releases are maintained for building the latest version of statediffing geth or using it as a go mod dependency. +When a new core go-ethereum version is released, statediffing geth is rebased onto and adjusted to work with the new tag. + +We want to maintain a complete record of our git history, but in order to make frequent and timely rebases feasible we also +need to be able to squash our work before performing a rebase. To this end we retain multiple branches with partial incremental history that culminate in +the full incremental history. + +### Versioning + +Example: `v1.10.16-statediff-3.0.2` + +- The first section, `v1.10.16`, corresponds to the release of the root branch this version is rebased onto (e.g., [](https://github.com/ethereum/go-ethereum/releases/tag/v1.10.16)[https://github.com/ethereum/go-ethereum/releases/tag/v1.10.16](https://github.com/ethereum/go-ethereum/releases/tag/v1.10.16)) +- The second section, `3.0.2`, corresponds to the version of our statediffing code. The major version here (3) should always correspond with the major version of the `ipld-eth-db` schema version it works with (e.g., [](https://github.com/vulcanize/ipld-eth-db/releases/tag/v3.0.6)[https://github.com/vulcanize/ipld-eth-db/releases/tag/v3.0.6](https://github.com/vulcanize/ipld-eth-db/releases/tag/v3.0.6)); it is only bumped when we bump the major version of the schema. + - The major version of the schema is only bumped when a breaking change is made to the schema. + - The minor version is bumped when a new feature is added, or a fix is performed that breaks or updates the statediffing API or CLI in some way. + - The patch version is bumped whenever minor fixes/patches/features are done that don’t change/break API/CLI compatibility. +- We are very strict about the first section and the major version of the statediffing code, but some discretion is required when deciding to bump minor versus patch version of the statediffing code. + +The statediff version is included in the `VersionMeta` in params/version.go + +### Branches + +We maintain two official kinds of branches: + +Major Branch: `{Root Version}-statediff` +Major branches retain the cumulative state of all changes made before the latest root version rebase and track the full incremental history of changes made between the latest root version rebase and the next. +Aside from creating the branch by performing the rebase described in the section below, these branches are never worked off of or committed to directly. + +Feature Branch: `{Root Version}-statediff-{Statediff Version}` +Feature branches are checked out from a major branch in order to work on a new feature or fix for the statediffing code. +The statediff version of a feature branch is the new version it affects on the major branch when merged. Internal tagged releases +are cut against these branches after they are merged back to the major branch. + +If a developer is unsure what version their patch should affect, they should remain working on an unofficial branch. From there +they can open a PR against the targeted root branch and be directed to the appropriate feature version and branch. + +### Rebasing + +When a new root tagged release comes out we rebase our statediffing code on top of the new tag using the following process: + +1. Checkout a new major branch for the tag from the current major branch +2. On the new major branch, squash all our commits since the last major rebase +3. On the new major branch, perform the rebase against the new tag +4. Push the new major branch to the remote +5. From the new major branch, checkout a new feature branch based on the new major version and the last statediff version +6. On this new feature branch, add the new major branch to the .github/workflows/on-master.yml list of "on push" branches +7. On this new feature branch, make any fixes/adjustments required for all statediffing geth tests to pass +8. PR this feature branch into the new major branch, this PR will trigger CI tests and builds. +9. After merging PR, rebase feature branch onto major branch +10. Cut a new release targeting the feature branch, this release should have the new root version but the same statediff version as the last release diff --git a/statediff/api.go b/statediff/api.go new file mode 100644 index 000000000..09622d20b --- /dev/null +++ b/statediff/api.go @@ -0,0 +1,213 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package statediff + +import ( + "context" + + "github.com/ethereum/go-ethereum/statediff/types" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rpc" +) + +// APIName is the namespace used for the state diffing service API +const APIName = "statediff" + +// APIVersion is the version of the state diffing service API +const APIVersion = "0.0.1" + +// PublicStateDiffAPI provides an RPC subscription interface +// that can be used to stream out state diffs as they +// are produced by a full node +type PublicStateDiffAPI struct { + sds IService +} + +// NewPublicStateDiffAPI creates an rpc subscription interface for the underlying statediff service +func NewPublicStateDiffAPI(sds IService) *PublicStateDiffAPI { + return &PublicStateDiffAPI{ + sds: sds, + } +} + +// Stream is the public method to setup a subscription that fires off statediff service payloads as they are created +func (api *PublicStateDiffAPI) Stream(ctx context.Context, params Params) (*rpc.Subscription, error) { + // ensure that the RPC connection supports subscriptions + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return nil, rpc.ErrNotificationsUnsupported + } + + // create subscription and start waiting for events + rpcSub := notifier.CreateSubscription() + + go func() { + // subscribe to events from the statediff service + payloadChannel := make(chan Payload, chainEventChanSize) + quitChan := make(chan bool, 1) + api.sds.Subscribe(rpcSub.ID, payloadChannel, quitChan, params) + // loop and await payloads and relay them to the subscriber with the notifier + for { + select { + case payload := <-payloadChannel: + if err := notifier.Notify(rpcSub.ID, payload); err != nil { + log.Error("Failed to send state diff packet; error: " + err.Error()) + if err := api.sds.Unsubscribe(rpcSub.ID); err != nil { + log.Error("Failed to unsubscribe from the state diff service; error: " + err.Error()) + } + return + } + case err := <-rpcSub.Err(): + if err != nil { + log.Error("State diff service rpcSub error: " + err.Error()) + err = api.sds.Unsubscribe(rpcSub.ID) + if err != nil { + log.Error("Failed to unsubscribe from the state diff service; error: " + err.Error()) + } + return + } + case <-quitChan: + // don't need to unsubscribe, service does so before sending the quit signal + return + } + } + }() + + return rpcSub, nil +} + +// StateDiffAt returns a state diff payload at the specific blockheight +func (api *PublicStateDiffAPI) StateDiffAt(ctx context.Context, blockNumber uint64, params Params) (*Payload, error) { + return api.sds.StateDiffAt(blockNumber, params) +} + +// StateDiffFor returns a state diff payload for the specific blockhash +func (api *PublicStateDiffAPI) StateDiffFor(ctx context.Context, blockHash common.Hash, params Params) (*Payload, error) { + return api.sds.StateDiffFor(blockHash, params) +} + +// StateTrieAt returns a state trie payload at the specific blockheight +func (api *PublicStateDiffAPI) StateTrieAt(ctx context.Context, blockNumber uint64, params Params) (*Payload, error) { + return api.sds.StateTrieAt(blockNumber, params) +} + +// StreamCodeAndCodeHash writes all of the codehash=>code pairs out to a websocket channel +func (api *PublicStateDiffAPI) StreamCodeAndCodeHash(ctx context.Context, blockNumber uint64) (*rpc.Subscription, error) { + // ensure that the RPC connection supports subscriptions + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return nil, rpc.ErrNotificationsUnsupported + } + + // create subscription and start waiting for events + rpcSub := notifier.CreateSubscription() + payloadChan := make(chan types.CodeAndCodeHash, chainEventChanSize) + quitChan := make(chan bool) + api.sds.StreamCodeAndCodeHash(blockNumber, payloadChan, quitChan) + go func() { + for { + select { + case payload := <-payloadChan: + if err := notifier.Notify(rpcSub.ID, payload); err != nil { + log.Error("Failed to send code and codehash packet", "err", err) + return + } + case err := <-rpcSub.Err(): + log.Error("State diff service rpcSub error", "err", err) + return + case <-quitChan: + return + } + } + }() + + return rpcSub, nil +} + +// WriteStateDiffAt writes a state diff object directly to DB at the specific blockheight +func (api *PublicStateDiffAPI) WriteStateDiffAt(ctx context.Context, blockNumber uint64, params Params) JobID { + var err error + start, logger := countApiRequestBegin("writeStateDiffAt", blockNumber) + defer countApiRequestEnd(start, logger, err) + + return api.sds.WriteStateDiffAt(blockNumber, params) +} + +// WriteStateDiffFor writes a state diff object directly to DB for the specific block hash +func (api *PublicStateDiffAPI) WriteStateDiffFor(ctx context.Context, blockHash common.Hash, params Params) error { + var err error + start, logger := countApiRequestBegin("writeStateDiffFor", blockHash.Hex()) + defer countApiRequestEnd(start, logger, err) + + err = api.sds.WriteStateDiffFor(blockHash, params) + return err +} + +// WatchAddress changes the list of watched addresses to which the direct indexing is restricted according to given operation +func (api *PublicStateDiffAPI) WatchAddress(operation types.OperationType, args []types.WatchAddressArg) error { + return api.sds.WatchAddress(operation, args) +} + +// StreamWrites sets up a subscription that streams the status of completed calls to WriteStateDiff* +func (api *PublicStateDiffAPI) StreamWrites(ctx context.Context) (*rpc.Subscription, error) { + // ensure that the RPC connection supports subscriptions + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return nil, rpc.ErrNotificationsUnsupported + } + + // create subscription and start waiting for events + rpcSub := notifier.CreateSubscription() + + go func() { + // subscribe to events from the statediff service + statusChan := make(chan JobStatus, chainEventChanSize) + quitChan := make(chan bool, 1) + api.sds.SubscribeWriteStatus(rpcSub.ID, statusChan, quitChan) + + var err error + defer func() { + if err != nil { + if err = api.sds.UnsubscribeWriteStatus(rpcSub.ID); err != nil { + log.Error("Failed to unsubscribe from job status stream: " + err.Error()) + } + } + }() + // loop and await payloads and relay them to the subscriber with the notifier + for { + select { + case status := <-statusChan: + if err = notifier.Notify(rpcSub.ID, status); err != nil { + log.Error("Failed to send job status; error: " + err.Error()) + return + } + case err = <-rpcSub.Err(): + if err != nil { + log.Error("State diff service rpcSub error: " + err.Error()) + return + } + case <-quitChan: + // don't need to unsubscribe, service does so before sending the quit signal + return + } + } + }() + + return rpcSub, nil +} diff --git a/statediff/builder.go b/statediff/builder.go new file mode 100644 index 000000000..3c413fad7 --- /dev/null +++ b/statediff/builder.go @@ -0,0 +1,934 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Contains a batch of utility type declarations used by the tests. As the node +// operates on unique types, a lot of them are needed to check various features. + +package statediff + +import ( + "bytes" + "fmt" + "time" + + metrics2 "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff/trie_helpers" + types2 "github.com/ethereum/go-ethereum/statediff/types" + "github.com/ethereum/go-ethereum/trie" +) + +var ( + nullHashBytes = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000") + emptyNode, _ = rlp.EncodeToBytes(&[]byte{}) + emptyContractRoot = crypto.Keccak256Hash(emptyNode) + nullCodeHash = crypto.Keccak256Hash([]byte{}).Bytes() +) + +// Builder interface exposes the method for building a state diff between two blocks +type Builder interface { + BuildStateDiffObject(args Args, params Params) (types2.StateObject, error) + BuildStateTrieObject(current *types.Block) (types2.StateObject, error) + WriteStateDiffObject(args Args, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error +} + +type StateDiffBuilder struct { + StateCache state.Database +} + +type IterPair struct { + Older, Newer trie.NodeIterator +} + +// convenience +func StateNodeAppender(nodes *[]types2.StateNode) types2.StateNodeSink { + return func(node types2.StateNode) error { + *nodes = append(*nodes, node) + return nil + } +} +func StorageNodeAppender(nodes *[]types2.StorageNode) types2.StorageNodeSink { + return func(node types2.StorageNode) error { + *nodes = append(*nodes, node) + return nil + } +} +func CodeMappingAppender(codeAndCodeHashes *[]types2.CodeAndCodeHash) types2.CodeSink { + return func(c types2.CodeAndCodeHash) error { + *codeAndCodeHashes = append(*codeAndCodeHashes, c) + return nil + } +} + +// NewBuilder is used to create a statediff builder +func NewBuilder(stateCache state.Database) Builder { + return &StateDiffBuilder{ + StateCache: stateCache, // state cache is safe for concurrent reads + } +} + +// BuildStateTrieObject builds a state trie object from the provided block +func (sdb *StateDiffBuilder) BuildStateTrieObject(current *types.Block) (types2.StateObject, error) { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.BuildStateTrieObjectTimer) + currentTrie, err := sdb.StateCache.OpenTrie(current.Root()) + if err != nil { + return types2.StateObject{}, fmt.Errorf("error creating trie for block %d: %v", current.Number(), err) + } + it := currentTrie.NodeIterator([]byte{}) + stateNodes, codeAndCodeHashes, err := sdb.buildStateTrie(it) + if err != nil { + return types2.StateObject{}, fmt.Errorf("error collecting state nodes for block %d: %v", current.Number(), err) + } + return types2.StateObject{ + BlockNumber: current.Number(), + BlockHash: current.Hash(), + Nodes: stateNodes, + CodeAndCodeHashes: codeAndCodeHashes, + }, nil +} + +func (sdb *StateDiffBuilder) buildStateTrie(it trie.NodeIterator) ([]types2.StateNode, []types2.CodeAndCodeHash, error) { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.BuildStateTrieTimer) + stateNodes := make([]types2.StateNode, 0) + codeAndCodeHashes := make([]types2.CodeAndCodeHash, 0) + for it.Next(true) { + // skip value nodes + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB()) + if err != nil { + return nil, nil, err + } + switch node.NodeType { + case types2.Leaf: + var account types.StateAccount + if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil { + return nil, nil, fmt.Errorf("error decoding account for leaf node at path %x nerror: %v", node.Path, err) + } + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(node.Path, partialPath...) + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + node.LeafKey = leafKey + if !bytes.Equal(account.CodeHash, nullCodeHash) { + var storageNodes []types2.StorageNode + err := sdb.buildStorageNodesEventual(account.Root, true, StorageNodeAppender(&storageNodes)) + if err != nil { + return nil, nil, fmt.Errorf("failed building eventual storage diffs for account %+v\r\nerror: %v", account, err) + } + node.StorageNodes = storageNodes + // emit codehash => code mappings for cod + codeHash := common.BytesToHash(account.CodeHash) + code, err := sdb.StateCache.ContractCode(common.Hash{}, codeHash) + if err != nil { + return nil, nil, fmt.Errorf("failed to retrieve code for codehash %s\r\n error: %v", codeHash.String(), err) + } + codeAndCodeHashes = append(codeAndCodeHashes, types2.CodeAndCodeHash{ + Hash: codeHash, + Code: code, + }) + } + stateNodes = append(stateNodes, node) + case types2.Extension, types2.Branch: + stateNodes = append(stateNodes, node) + default: + return nil, nil, fmt.Errorf("unexpected node type %s", node.NodeType) + } + } + return stateNodes, codeAndCodeHashes, it.Error() +} + +// BuildStateDiffObject builds a statediff object from two blocks and the provided parameters +func (sdb *StateDiffBuilder) BuildStateDiffObject(args Args, params Params) (types2.StateObject, error) { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.BuildStateDiffObjectTimer) + var stateNodes []types2.StateNode + var codeAndCodeHashes []types2.CodeAndCodeHash + err := sdb.WriteStateDiffObject(args, params, StateNodeAppender(&stateNodes), CodeMappingAppender(&codeAndCodeHashes)) + if err != nil { + return types2.StateObject{}, err + } + return types2.StateObject{ + BlockHash: args.BlockHash, + BlockNumber: args.BlockNumber, + Nodes: stateNodes, + CodeAndCodeHashes: codeAndCodeHashes, + }, nil +} + +// WriteStateDiffObject writes a statediff object to output callback +func (sdb *StateDiffBuilder) WriteStateDiffObject(args Args, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink) error { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.WriteStateDiffObjectTimer) + // Load tries for old and new states + oldTrie, err := sdb.StateCache.OpenTrie(args.OldStateRoot) + if err != nil { + return fmt.Errorf("error creating trie for oldStateRoot: %v", err) + } + newTrie, err := sdb.StateCache.OpenTrie(args.NewStateRoot) + if err != nil { + return fmt.Errorf("error creating trie for newStateRoot: %v", err) + } + + // we do two state trie iterations: + // one for new/updated nodes, + // one for deleted/updated nodes; + // prepare 2 iterator instances for each task + iterPairs := []IterPair{ + { + Older: oldTrie.NodeIterator([]byte{}), + Newer: newTrie.NodeIterator([]byte{}), + }, + { + Older: oldTrie.NodeIterator([]byte{}), + Newer: newTrie.NodeIterator([]byte{}), + }, + } + + logger := log.New("hash", args.BlockHash.Hex(), "number", args.BlockNumber) + if !params.IntermediateStateNodes { + return sdb.BuildStateDiffWithoutIntermediateStateNodes(iterPairs, params, output, codeOutput, logger) + } else { + return sdb.BuildStateDiffWithIntermediateStateNodes(iterPairs, params, output, codeOutput, logger) + } +} + +func (sdb *StateDiffBuilder) BuildStateDiffWithIntermediateStateNodes(iterPairs []IterPair, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink, logger log.Logger) error { + logger.Debug("statediff BEGIN BuildStateDiffWithIntermediateStateNodes") + defer metrics2.ReportAndUpdateDuration("statediff END BuildStateDiffWithIntermediateStateNodes", time.Now(), logger, metrics2.IndexerMetrics.BuildStateDiffWithIntermediateStateNodesTimer) + // collect a slice of all the nodes that were touched and exist at B (B-A) + // a map of their leafkey to all the accounts that were touched and exist at B + // and a slice of all the paths for the nodes in both of the above sets + diffAccountsAtB, diffPathsAtB, err := sdb.createdAndUpdatedStateWithIntermediateNodes( + iterPairs[0].Older, iterPairs[0].Newer, params.watchedAddressesLeafPaths, output, logger) + if err != nil { + return fmt.Errorf("error collecting createdAndUpdatedNodes: %v", err) + } + + // collect a slice of all the nodes that existed at a path in A that doesn't exist in B + // a map of their leafkey to all the accounts that were touched and exist at A + diffAccountsAtA, err := sdb.deletedOrUpdatedState( + iterPairs[1].Older, iterPairs[1].Newer, + diffAccountsAtB, diffPathsAtB, params.watchedAddressesLeafPaths, + params.IntermediateStateNodes, params.IntermediateStorageNodes, output, logger) + if err != nil { + return fmt.Errorf("error collecting deletedOrUpdatedNodes: %v", err) + } + + // collect and sort the leafkey keys for both account mappings into a slice + t := time.Now() + createKeys := trie_helpers.SortKeys(diffAccountsAtB) + deleteKeys := trie_helpers.SortKeys(diffAccountsAtA) + logger.Debug(fmt.Sprintf("statediff BuildStateDiffWithIntermediateStateNodes sort duration=%dms", time.Since(t).Milliseconds())) + + // and then find the intersection of these keys + // these are the leafkeys for the accounts which exist at both A and B but are different + // this also mutates the passed in createKeys and deleteKeys, removing the intersection keys + // and leaving the truly created or deleted keys in place + t = time.Now() + updatedKeys := trie_helpers.FindIntersection(createKeys, deleteKeys) + logger.Debug(fmt.Sprintf("statediff BuildStateDiffWithIntermediateStateNodes intersection count=%d duration=%dms", + len(updatedKeys), + time.Since(t).Milliseconds())) + + // build the diff nodes for the updated accounts using the mappings at both A and B as directed by the keys found as the intersection of the two + err = sdb.buildAccountUpdates( + diffAccountsAtB, diffAccountsAtA, updatedKeys, + params.IntermediateStorageNodes, output, logger) + if err != nil { + return fmt.Errorf("error building diff for updated accounts: %v", err) + } + // build the diff nodes for created accounts + err = sdb.buildAccountCreations(diffAccountsAtB, params.IntermediateStorageNodes, output, codeOutput, logger) + if err != nil { + return fmt.Errorf("error building diff for created accounts: %v", err) + } + return nil +} + +func (sdb *StateDiffBuilder) BuildStateDiffWithoutIntermediateStateNodes(iterPairs []IterPair, params Params, output types2.StateNodeSink, codeOutput types2.CodeSink, logger log.Logger) error { + logger.Debug("statediff BEGIN BuildStateDiffWithoutIntermediateStateNodes") + defer metrics2.ReportAndUpdateDuration("statediff END BuildStateDiffWithoutIntermediateStateNodes", time.Now(), logger, metrics2.IndexerMetrics.BuildStateDiffWithoutIntermediateStateNodesTimer) + // collect a map of their leafkey to all the accounts that were touched and exist at B + // and a slice of all the paths for the nodes in both of the above sets + diffAccountsAtB, diffPathsAtB, err := sdb.createdAndUpdatedState( + iterPairs[0].Older, iterPairs[0].Newer, + params.watchedAddressesLeafPaths, logger) + if err != nil { + return fmt.Errorf("error collecting createdAndUpdatedNodes: %v", err) + } + + // collect a slice of all the nodes that existed at a path in A that doesn't exist in B + // a map of their leafkey to all the accounts that were touched and exist at A + diffAccountsAtA, err := sdb.deletedOrUpdatedState( + iterPairs[1].Older, iterPairs[1].Newer, + diffAccountsAtB, diffPathsAtB, params.watchedAddressesLeafPaths, + params.IntermediateStateNodes, params.IntermediateStorageNodes, output, logger) + if err != nil { + return fmt.Errorf("error collecting deletedOrUpdatedNodes: %v", err) + } + + // collect and sort the leafkeys for both account mappings into a slice + t := time.Now() + createKeys := trie_helpers.SortKeys(diffAccountsAtB) + deleteKeys := trie_helpers.SortKeys(diffAccountsAtA) + logger.Debug(fmt.Sprintf("statediff BuildStateDiffWithoutIntermediateStateNodessort sort duration=%dms", time.Since(t).Milliseconds())) + + // and then find the intersection of these keys + // these are the leafkeys for the accounts which exist at both A and B but are different + // this also mutates the passed in createKeys and deleteKeys, removing in intersection keys + // and leaving the truly created or deleted keys in place + t = time.Now() + updatedKeys := trie_helpers.FindIntersection(createKeys, deleteKeys) + logger.Debug(fmt.Sprintf("statediff BuildStateDiffWithoutIntermediateStateNodes intersection count=%d duration=%dms", + len(updatedKeys), + time.Since(t).Milliseconds())) + + // build the diff nodes for the updated accounts using the mappings at both A and B as directed by the keys found as the intersection of the two + err = sdb.buildAccountUpdates( + diffAccountsAtB, diffAccountsAtA, updatedKeys, + params.IntermediateStorageNodes, output, logger) + if err != nil { + return fmt.Errorf("error building diff for updated accounts: %v", err) + } + // build the diff nodes for created accounts + err = sdb.buildAccountCreations(diffAccountsAtB, params.IntermediateStorageNodes, output, codeOutput, logger) + if err != nil { + return fmt.Errorf("error building diff for created accounts: %v", err) + } + return nil +} + +// createdAndUpdatedState returns +// a mapping of their leafkeys to all the accounts that exist in a different state at B than A +// and a slice of the paths for all of the nodes included in both +func (sdb *StateDiffBuilder) createdAndUpdatedState(a, b trie.NodeIterator, watchedAddressesLeafPaths [][]byte, logger log.Logger) (types2.AccountMap, map[string]bool, error) { + logger.Debug("statediff BEGIN createdAndUpdatedState") + defer metrics2.ReportAndUpdateDuration("statediff END createdAndUpdatedState", time.Now(), logger, metrics2.IndexerMetrics.CreatedAndUpdatedStateTimer) + diffPathsAtB := make(map[string]bool) + diffAccountsAtB := make(types2.AccountMap) + watchingAddresses := len(watchedAddressesLeafPaths) > 0 + + it, _ := trie.NewDifferenceIterator(a, b) + for it.Next(true) { + // ignore node if it is not along paths of interest + if watchingAddresses && !isValidPrefixPath(watchedAddressesLeafPaths, it.Path()) { + continue + } + + // skip value nodes + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + + node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB()) + if err != nil { + return nil, nil, err + } + if node.NodeType == types2.Leaf { + // created vs updated is important for leaf nodes since we need to diff their storage + // so we need to map all changed accounts at B to their leafkey, since account can change pathes but not leafkey + var account types.StateAccount + if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil { + return nil, nil, fmt.Errorf("error decoding account for leaf node at path %x nerror: %v", node.Path, err) + } + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(node.Path, partialPath...) + + // ignore leaf node if it is not a watched address + if !isWatchedAddress(watchedAddressesLeafPaths, valueNodePath) { + continue + } + + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + diffAccountsAtB[common.Bytes2Hex(leafKey)] = types2.AccountWrapper{ + NodeType: node.NodeType, + Path: node.Path, + NodeValue: node.NodeValue, + LeafKey: leafKey, + Account: &account, + } + } + // add both intermediate and leaf node paths to the list of diffPathsAtB + diffPathsAtB[common.Bytes2Hex(node.Path)] = true + } + return diffAccountsAtB, diffPathsAtB, it.Error() +} + +// createdAndUpdatedStateWithIntermediateNodes returns +// a slice of all the intermediate nodes that exist in a different state at B than A +// a mapping of their leafkeys to all the accounts that exist in a different state at B than A +// and a slice of the paths for all of the nodes included in both +func (sdb *StateDiffBuilder) createdAndUpdatedStateWithIntermediateNodes(a, b trie.NodeIterator, watchedAddressesLeafPaths [][]byte, output types2.StateNodeSink, logger log.Logger) (types2.AccountMap, map[string]bool, error) { + logger.Debug("statediff BEGIN createdAndUpdatedStateWithIntermediateNodes") + defer metrics2.ReportAndUpdateDuration("statediff END createdAndUpdatedStateWithIntermediateNodes", time.Now(), logger, metrics2.IndexerMetrics.CreatedAndUpdatedStateWithIntermediateNodesTimer) + diffPathsAtB := make(map[string]bool) + diffAccountsAtB := make(types2.AccountMap) + watchingAddresses := len(watchedAddressesLeafPaths) > 0 + + it, itCount := trie.NewDifferenceIterator(a, b) + for it.Next(true) { + // ignore node if it is not along paths of interest + if watchingAddresses && !isValidPrefixPath(watchedAddressesLeafPaths, it.Path()) { + continue + } + + // skip value nodes + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB()) + if err != nil { + return nil, nil, err + } + switch node.NodeType { + case types2.Leaf: + // created vs updated is important for leaf nodes since we need to diff their storage + // so we need to map all changed accounts at B to their leafkey, since account can change paths but not leafkey + var account types.StateAccount + if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil { + return nil, nil, fmt.Errorf("error decoding account for leaf node at path %x nerror: %v", node.Path, err) + } + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(node.Path, partialPath...) + + // ignore leaf node if it is not a watched address + if !isWatchedAddress(watchedAddressesLeafPaths, valueNodePath) { + continue + } + + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + diffAccountsAtB[common.Bytes2Hex(leafKey)] = types2.AccountWrapper{ + NodeType: node.NodeType, + Path: node.Path, + NodeValue: node.NodeValue, + LeafKey: leafKey, + Account: &account, + } + case types2.Extension, types2.Branch: + // create a diff for any intermediate node that has changed at b + // created vs updated makes no difference for intermediate nodes since we do not need to diff storage + if err := output(types2.StateNode{ + NodeType: node.NodeType, + Path: node.Path, + NodeValue: node.NodeValue, + }); err != nil { + return nil, nil, err + } + default: + return nil, nil, fmt.Errorf("unexpected node type %s", node.NodeType) + } + // add both intermediate and leaf node paths to the list of diffPathsAtB + diffPathsAtB[common.Bytes2Hex(node.Path)] = true + } + logger.Debug("statediff COUNTS createdAndUpdatedStateWithIntermediateNodes", "it", itCount, "diffAccountsAtB", len(diffAccountsAtB), "diffPathsAtB", len(diffPathsAtB)) + metrics2.IndexerMetrics.DifferenceIteratorCounter.Inc(int64(*itCount)) + return diffAccountsAtB, diffPathsAtB, it.Error() +} + +// deletedOrUpdatedState returns a slice of all the pathes that are emptied at B +// and a mapping of their leafkeys to all the accounts that exist in a different state at A than B +func (sdb *StateDiffBuilder) deletedOrUpdatedState(a, b trie.NodeIterator, diffAccountsAtB types2.AccountMap, diffPathsAtB map[string]bool, watchedAddressesLeafPaths [][]byte, intermediateStateNodes, intermediateStorageNodes bool, output types2.StateNodeSink, logger log.Logger) (types2.AccountMap, error) { + logger.Debug("statediff BEGIN deletedOrUpdatedState") + defer metrics2.ReportAndUpdateDuration("statediff END deletedOrUpdatedState", time.Now(), logger, metrics2.IndexerMetrics.DeletedOrUpdatedStateTimer) + diffAccountAtA := make(types2.AccountMap) + watchingAddresses := len(watchedAddressesLeafPaths) > 0 + + it, _ := trie.NewDifferenceIterator(b, a) + for it.Next(true) { + // ignore node if it is not along paths of interest + if watchingAddresses && !isValidPrefixPath(watchedAddressesLeafPaths, it.Path()) { + continue + } + + // skip value nodes + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + + node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB()) + if err != nil { + return nil, err + } + switch node.NodeType { + case types2.Leaf: + // map all different accounts at A to their leafkey + var account types.StateAccount + if err := rlp.DecodeBytes(nodeElements[1].([]byte), &account); err != nil { + return nil, fmt.Errorf("error decoding account for leaf node at path %x nerror: %v", node.Path, err) + } + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(node.Path, partialPath...) + + // ignore leaf node if it is not a watched address + if !isWatchedAddress(watchedAddressesLeafPaths, valueNodePath) { + continue + } + + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + diffAccountAtA[common.Bytes2Hex(leafKey)] = types2.AccountWrapper{ + NodeType: node.NodeType, + Path: node.Path, + NodeValue: node.NodeValue, + LeafKey: leafKey, + Account: &account, + } + // if this node's path did not show up in diffPathsAtB + // that means the node at this path was deleted (or moved) in B + if _, ok := diffPathsAtB[common.Bytes2Hex(node.Path)]; !ok { + var diff types2.StateNode + // if this node's leaf key also did not show up in diffAccountsAtB + // that means the node was deleted + // in that case, emit an empty "removed" diff state node + // include empty "removed" diff storage nodes for all the storage slots + if _, ok := diffAccountsAtB[common.Bytes2Hex(leafKey)]; !ok { + diff = types2.StateNode{ + NodeType: types2.Removed, + Path: node.Path, + LeafKey: leafKey, + NodeValue: []byte{}, + } + + var storageDiffs []types2.StorageNode + err := sdb.buildRemovedAccountStorageNodes(account.Root, intermediateStorageNodes, StorageNodeAppender(&storageDiffs)) + if err != nil { + return nil, fmt.Errorf("failed building storage diffs for removed node %x\r\nerror: %v", node.Path, err) + } + diff.StorageNodes = storageDiffs + } else { + // emit an empty "removed" diff with empty leaf key if the account was moved + diff = types2.StateNode{ + NodeType: types2.Removed, + Path: node.Path, + NodeValue: []byte{}, + } + } + + if err := output(diff); err != nil { + return nil, err + } + } + case types2.Extension, types2.Branch: + // if this node's path did not show up in diffPathsAtB + // that means the node at this path was deleted (or moved) in B + // emit an empty "removed" diff to signify as such + if intermediateStateNodes { + if _, ok := diffPathsAtB[common.Bytes2Hex(node.Path)]; !ok { + if err := output(types2.StateNode{ + Path: node.Path, + NodeValue: []byte{}, + NodeType: types2.Removed, + }); err != nil { + return nil, err + } + } + } + // fall through, we did everything we need to do with these node types + default: + return nil, fmt.Errorf("unexpected node type %s", node.NodeType) + } + } + return diffAccountAtA, it.Error() +} + +// buildAccountUpdates uses the account diffs maps for A => B and B => A and the known intersection of their leafkeys +// to generate the statediff node objects for all of the accounts that existed at both A and B but in different states +// needs to be called before building account creations and deletions as this mutates +// those account maps to remove the accounts which were updated +func (sdb *StateDiffBuilder) buildAccountUpdates(creations, deletions types2.AccountMap, updatedKeys []string, intermediateStorageNodes bool, output types2.StateNodeSink, logger log.Logger) error { + logger.Debug("statediff BEGIN buildAccountUpdates", "creations", len(creations), "deletions", len(deletions), "updatedKeys", len(updatedKeys)) + defer metrics2.ReportAndUpdateDuration("statediff END buildAccountUpdates ", time.Now(), logger, metrics2.IndexerMetrics.BuildAccountUpdatesTimer) + var err error + for _, key := range updatedKeys { + createdAcc := creations[key] + deletedAcc := deletions[key] + var storageDiffs []types2.StorageNode + if deletedAcc.Account != nil && createdAcc.Account != nil { + oldSR := deletedAcc.Account.Root + newSR := createdAcc.Account.Root + err = sdb.buildStorageNodesIncremental( + oldSR, newSR, intermediateStorageNodes, + StorageNodeAppender(&storageDiffs)) + if err != nil { + return fmt.Errorf("failed building incremental storage diffs for account with leafkey %s\r\nerror: %v", key, err) + } + } + if err = output(types2.StateNode{ + NodeType: createdAcc.NodeType, + Path: createdAcc.Path, + NodeValue: createdAcc.NodeValue, + LeafKey: createdAcc.LeafKey, + StorageNodes: storageDiffs, + }); err != nil { + return err + } + delete(creations, key) + delete(deletions, key) + } + + return nil +} + +// buildAccountCreations returns the statediff node objects for all the accounts that exist at B but not at A +// it also returns the code and codehash for created contract accounts +func (sdb *StateDiffBuilder) buildAccountCreations(accounts types2.AccountMap, intermediateStorageNodes bool, output types2.StateNodeSink, codeOutput types2.CodeSink, logger log.Logger) error { + logger.Debug("statediff BEGIN buildAccountCreations") + defer metrics2.ReportAndUpdateDuration("statediff END buildAccountCreations", time.Now(), logger, metrics2.IndexerMetrics.BuildAccountCreationsTimer) + for _, val := range accounts { + diff := types2.StateNode{ + NodeType: val.NodeType, + Path: val.Path, + LeafKey: val.LeafKey, + NodeValue: val.NodeValue, + } + if !bytes.Equal(val.Account.CodeHash, nullCodeHash) { + // For contract creations, any storage node contained is a diff + var storageDiffs []types2.StorageNode + err := sdb.buildStorageNodesEventual(val.Account.Root, intermediateStorageNodes, StorageNodeAppender(&storageDiffs)) + if err != nil { + return fmt.Errorf("failed building eventual storage diffs for node %x\r\nerror: %v", val.Path, err) + } + diff.StorageNodes = storageDiffs + // emit codehash => code mappings for cod + codeHash := common.BytesToHash(val.Account.CodeHash) + code, err := sdb.StateCache.ContractCode(common.Hash{}, codeHash) + if err != nil { + return fmt.Errorf("failed to retrieve code for codehash %s\r\n error: %v", codeHash.String(), err) + } + if err := codeOutput(types2.CodeAndCodeHash{ + Hash: codeHash, + Code: code, + }); err != nil { + return err + } + } + if err := output(diff); err != nil { + return err + } + } + + return nil +} + +// buildStorageNodesEventual builds the storage diff node objects for a created account +// i.e. it returns all the storage nodes at this state, since there is no previous state +func (sdb *StateDiffBuilder) buildStorageNodesEventual(sr common.Hash, intermediateNodes bool, output types2.StorageNodeSink) error { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.BuildStorageNodesEventualTimer) + if bytes.Equal(sr.Bytes(), emptyContractRoot.Bytes()) { + return nil + } + log.Debug("Storage Root For Eventual Diff", "root", sr.Hex()) + sTrie, err := sdb.StateCache.OpenTrie(sr) + if err != nil { + log.Info("error in build storage diff eventual", "error", err) + return err + } + it := sTrie.NodeIterator(make([]byte, 0)) + err = sdb.buildStorageNodesFromTrie(it, intermediateNodes, output) + if err != nil { + return err + } + return nil +} + +// buildStorageNodesFromTrie returns all the storage diff node objects in the provided node interator +// including intermediate nodes can be turned on or off +func (sdb *StateDiffBuilder) buildStorageNodesFromTrie(it trie.NodeIterator, intermediateNodes bool, output types2.StorageNodeSink) error { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.BuildStorageNodesFromTrieTimer) + for it.Next(true) { + // skip value nodes + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB()) + if err != nil { + return err + } + switch node.NodeType { + case types2.Leaf: + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(node.Path, partialPath...) + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + if err := output(types2.StorageNode{ + NodeType: node.NodeType, + Path: node.Path, + NodeValue: node.NodeValue, + LeafKey: leafKey, + }); err != nil { + return err + } + case types2.Extension, types2.Branch: + if intermediateNodes { + if err := output(types2.StorageNode{ + NodeType: node.NodeType, + Path: node.Path, + NodeValue: node.NodeValue, + }); err != nil { + return err + } + } + default: + return fmt.Errorf("unexpected node type %s", node.NodeType) + } + } + return it.Error() +} + +// buildRemovedAccountStorageNodes builds the "removed" diffs for all the storage nodes for a destroyed account +func (sdb *StateDiffBuilder) buildRemovedAccountStorageNodes(sr common.Hash, intermediateNodes bool, output types2.StorageNodeSink) error { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.BuildRemovedAccountStorageNodesTimer) + if bytes.Equal(sr.Bytes(), emptyContractRoot.Bytes()) { + return nil + } + log.Debug("Storage Root For Removed Diffs", "root", sr.Hex()) + sTrie, err := sdb.StateCache.OpenTrie(sr) + if err != nil { + log.Info("error in build removed account storage diffs", "error", err) + return err + } + it := sTrie.NodeIterator(make([]byte, 0)) + err = sdb.buildRemovedStorageNodesFromTrie(it, intermediateNodes, output) + if err != nil { + return err + } + return nil +} + +// buildRemovedStorageNodesFromTrie returns diffs for all the storage nodes in the provided node interator +// including intermediate nodes can be turned on or off +func (sdb *StateDiffBuilder) buildRemovedStorageNodesFromTrie(it trie.NodeIterator, intermediateNodes bool, output types2.StorageNodeSink) error { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.BuildRemovedStorageNodesFromTrieTimer) + for it.Next(true) { + // skip value nodes + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB()) + if err != nil { + return err + } + switch node.NodeType { + case types2.Leaf: + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(node.Path, partialPath...) + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + if err := output(types2.StorageNode{ + NodeType: types2.Removed, + Path: node.Path, + NodeValue: []byte{}, + LeafKey: leafKey, + }); err != nil { + return err + } + case types2.Extension, types2.Branch: + if intermediateNodes { + if err := output(types2.StorageNode{ + NodeType: types2.Removed, + Path: node.Path, + NodeValue: []byte{}, + }); err != nil { + return err + } + } + default: + return fmt.Errorf("unexpected node type %s", node.NodeType) + } + } + return it.Error() +} + +// buildStorageNodesIncremental builds the storage diff node objects for all nodes that exist in a different state at B than A +func (sdb *StateDiffBuilder) buildStorageNodesIncremental(oldSR common.Hash, newSR common.Hash, intermediateNodes bool, output types2.StorageNodeSink) error { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.BuildStorageNodesIncrementalTimer) + if bytes.Equal(newSR.Bytes(), oldSR.Bytes()) { + return nil + } + log.Trace("Storage Roots for Incremental Diff", "old", oldSR.Hex(), "new", newSR.Hex()) + oldTrie, err := sdb.StateCache.OpenTrie(oldSR) + if err != nil { + return err + } + newTrie, err := sdb.StateCache.OpenTrie(newSR) + if err != nil { + return err + } + + diffSlotsAtB, diffPathsAtB, err := sdb.createdAndUpdatedStorage( + oldTrie.NodeIterator([]byte{}), newTrie.NodeIterator([]byte{}), + intermediateNodes, output) + if err != nil { + return err + } + err = sdb.deletedOrUpdatedStorage(oldTrie.NodeIterator([]byte{}), newTrie.NodeIterator([]byte{}), + diffSlotsAtB, diffPathsAtB, intermediateNodes, output) + if err != nil { + return err + } + return nil +} + +func (sdb *StateDiffBuilder) createdAndUpdatedStorage(a, b trie.NodeIterator, intermediateNodes bool, output types2.StorageNodeSink) (map[string]bool, map[string]bool, error) { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.CreatedAndUpdatedStorageTimer) + diffPathsAtB := make(map[string]bool) + diffSlotsAtB := make(map[string]bool) + it, _ := trie.NewDifferenceIterator(a, b) + for it.Next(true) { + // skip value nodes + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB()) + if err != nil { + return nil, nil, err + } + switch node.NodeType { + case types2.Leaf: + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(node.Path, partialPath...) + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + diffSlotsAtB[common.Bytes2Hex(leafKey)] = true + if err := output(types2.StorageNode{ + NodeType: node.NodeType, + Path: node.Path, + NodeValue: node.NodeValue, + LeafKey: leafKey, + }); err != nil { + return nil, nil, err + } + case types2.Extension, types2.Branch: + if intermediateNodes { + if err := output(types2.StorageNode{ + NodeType: node.NodeType, + Path: node.Path, + NodeValue: node.NodeValue, + }); err != nil { + return nil, nil, err + } + } + default: + return nil, nil, fmt.Errorf("unexpected node type %s", node.NodeType) + } + diffPathsAtB[common.Bytes2Hex(node.Path)] = true + } + return diffSlotsAtB, diffPathsAtB, it.Error() +} + +func (sdb *StateDiffBuilder) deletedOrUpdatedStorage(a, b trie.NodeIterator, diffSlotsAtB, diffPathsAtB map[string]bool, intermediateNodes bool, output types2.StorageNodeSink) error { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.DeletedOrUpdatedStorageTimer) + it, _ := trie.NewDifferenceIterator(b, a) + for it.Next(true) { + // skip value nodes + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + node, nodeElements, err := trie_helpers.ResolveNode(it, sdb.StateCache.TrieDB()) + if err != nil { + return err + } + + switch node.NodeType { + case types2.Leaf: + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(node.Path, partialPath...) + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + + // if this node's path did not show up in diffPathsAtB + // that means the node at this path was deleted (or moved) in B + if _, ok := diffPathsAtB[common.Bytes2Hex(node.Path)]; !ok { + // if this node's leaf key also did not show up in diffSlotsAtB + // that means the node was deleted + // in that case, emit an empty "removed" diff storage node + if _, ok := diffSlotsAtB[common.Bytes2Hex(leafKey)]; !ok { + if err := output(types2.StorageNode{ + NodeType: types2.Removed, + Path: node.Path, + NodeValue: []byte{}, + LeafKey: leafKey, + }); err != nil { + return err + } + } else { + // emit an empty "removed" diff with empty leaf key if the account was moved + if err := output(types2.StorageNode{ + NodeType: types2.Removed, + Path: node.Path, + NodeValue: []byte{}, + }); err != nil { + return err + } + } + } + case types2.Extension, types2.Branch: + // if this node's path did not show up in diffPathsAtB + // that means the node at this path was deleted in B + // in that case, emit an empty "removed" diff storage node + if _, ok := diffPathsAtB[common.Bytes2Hex(node.Path)]; !ok { + if intermediateNodes { + if err := output(types2.StorageNode{ + NodeType: types2.Removed, + Path: node.Path, + NodeValue: []byte{}, + }); err != nil { + return err + } + } + } + default: + return fmt.Errorf("unexpected node type %s", node.NodeType) + } + } + return it.Error() +} + +// isValidPrefixPath is used to check if a node at currentPath is a parent | ancestor to one of the addresses the builder is configured to watch +func isValidPrefixPath(watchedAddressesLeafPaths [][]byte, currentPath []byte) bool { + for _, watchedAddressPath := range watchedAddressesLeafPaths { + if bytes.HasPrefix(watchedAddressPath, currentPath) { + return true + } + } + + return false +} + +// isWatchedAddress is used to check if a state account corresponds to one of the addresses the builder is configured to watch +func isWatchedAddress(watchedAddressesLeafPaths [][]byte, valueNodePath []byte) bool { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.IsWatchedAddressTimer) + // If we aren't watching any specific addresses, we are watching everything + if len(watchedAddressesLeafPaths) == 0 { + return true + } + + for _, watchedAddressPath := range watchedAddressesLeafPaths { + if bytes.Equal(watchedAddressPath, valueNodePath) { + return true + } + } + + return false +} diff --git a/statediff/builder_test.go b/statediff/builder_test.go new file mode 100644 index 000000000..4ff6ed9fc --- /dev/null +++ b/statediff/builder_test.go @@ -0,0 +1,2600 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package statediff_test + +import ( + "bytes" + "fmt" + "math/big" + "os" + "sort" + "testing" + + types2 "github.com/ethereum/go-ethereum/statediff/types" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff" + "github.com/ethereum/go-ethereum/statediff/test_helpers" +) + +var ( + contractLeafKey []byte + emptyDiffs = make([]types2.StateNode, 0) + emptyStorage = make([]types2.StorageNode, 0) + block0, block1, block2, block3, block4, block5, block6 *types.Block + builder statediff.Builder + minerAddress = common.HexToAddress("0x0") + minerLeafKey = test_helpers.AddressToLeafKey(minerAddress) + + slot0 = common.HexToHash("0") + slot1 = common.HexToHash("1") + slot2 = common.HexToHash("2") + slot3 = common.HexToHash("3") + + slot0StorageKey = crypto.Keccak256Hash(slot0[:]) + slot1StorageKey = crypto.Keccak256Hash(slot1[:]) + slot2StorageKey = crypto.Keccak256Hash(slot2[:]) + slot3StorageKey = crypto.Keccak256Hash(slot3[:]) + + slot0StorageValue = common.Hex2Bytes("94703c4b2bd70c169f5717101caee543299fc946c7") // prefixed AccountAddr1 + slot1StorageValue = common.Hex2Bytes("01") + slot2StorageValue = common.Hex2Bytes("09") + slot3StorageValue = common.Hex2Bytes("03") + + slot0StorageLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("390decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"), + slot0StorageValue, + }) + slot1StorageLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("310e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf6"), + slot1StorageValue, + }) + slot2StorageLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("305787fa12a823e0f2b7631cc41b3ba8828b3321ca811111fa75cd3aa3bb5ace"), + slot2StorageValue, + }) + slot3StorageLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("32575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b"), + slot3StorageValue, + }) + + contractAccountAtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 1, + Balance: big.NewInt(0), + CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(), + Root: crypto.Keccak256Hash(block2StorageBranchRootNode), + }) + contractAccountAtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"), + contractAccountAtBlock2, + }) + contractAccountAtBlock3, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 1, + Balance: big.NewInt(0), + CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(), + Root: crypto.Keccak256Hash(block3StorageBranchRootNode), + }) + contractAccountAtBlock3LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"), + contractAccountAtBlock3, + }) + contractAccountAtBlock4, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 1, + Balance: big.NewInt(0), + CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(), + Root: crypto.Keccak256Hash(block4StorageBranchRootNode), + }) + contractAccountAtBlock4LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"), + contractAccountAtBlock4, + }) + contractAccountAtBlock5, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 1, + Balance: big.NewInt(0), + CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(), + Root: crypto.Keccak256Hash(block5StorageBranchRootNode), + }) + contractAccountAtBlock5LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45"), + contractAccountAtBlock5, + }) + + minerAccountAtBlock1, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(2000002625000000000), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + minerAccountAtBlock1LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"), + minerAccountAtBlock1, + }) + minerAccountAtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(4000111203461610525), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + minerAccountAtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"), + minerAccountAtBlock2, + }) + + account1AtBlock1, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: test_helpers.Block1Account1Balance, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + account1AtBlock1LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1AtBlock1, + }) + account1AtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 2, + Balance: big.NewInt(999555797000009000), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + account1AtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1AtBlock2, + }) + account1AtBlock5, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 2, + Balance: big.NewInt(2999586469962854280), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + account1AtBlock5LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1AtBlock5, + }) + account1AtBlock6, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 3, + Balance: big.NewInt(2999557977962854280), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + account1AtBlock6LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1AtBlock6, + }) + + account2AtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(1000), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + account2AtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"), + account2AtBlock2, + }) + account2AtBlock3, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(2000013574009435976), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + account2AtBlock3LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"), + account2AtBlock3, + }) + account2AtBlock4, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(4000048088163070348), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + account2AtBlock4LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"), + account2AtBlock4, + }) + account2AtBlock6, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(6000063258066544204), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + account2AtBlock6LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45"), + account2AtBlock6, + }) + + bankAccountAtBlock0, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(test_helpers.TestBankFunds.Int64()), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + bankAccountAtBlock0LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("2000bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock0, + }) + + block1BankBalance = big.NewInt(test_helpers.TestBankFunds.Int64() - test_helpers.BalanceChange10000 - test_helpers.GasFees) + bankAccountAtBlock1, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 1, + Balance: block1BankBalance, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + bankAccountAtBlock1LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock1, + }) + + block2BankBalance = block1BankBalance.Int64() - test_helpers.BalanceChange1Ether - test_helpers.GasFees + bankAccountAtBlock2, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 2, + Balance: big.NewInt(block2BankBalance), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + bankAccountAtBlock2LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock2, + }) + bankAccountAtBlock3, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 3, + Balance: big.NewInt(999914255999990000), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + bankAccountAtBlock3LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock3, + }) + bankAccountAtBlock4, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 6, + Balance: big.NewInt(999826859999990000), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + bankAccountAtBlock4LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock4, + }) + bankAccountAtBlock5, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 8, + Balance: big.NewInt(999761283999990000), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + bankAccountAtBlock5LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock5, + }) + + block1BranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256(bankAccountAtBlock1LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(minerAccountAtBlock1LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(account1AtBlock1LeafNode), + []byte{}, + []byte{}, + }) + block2BranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256(bankAccountAtBlock2LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(minerAccountAtBlock2LeafNode), + crypto.Keccak256(contractAccountAtBlock2LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(account2AtBlock2LeafNode), + []byte{}, + crypto.Keccak256(account1AtBlock2LeafNode), + []byte{}, + []byte{}, + }) + block3BranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256(bankAccountAtBlock3LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(minerAccountAtBlock2LeafNode), + crypto.Keccak256(contractAccountAtBlock3LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(account2AtBlock3LeafNode), + []byte{}, + crypto.Keccak256(account1AtBlock2LeafNode), + []byte{}, + []byte{}, + }) + block4BranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256(bankAccountAtBlock4LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(minerAccountAtBlock2LeafNode), + crypto.Keccak256(contractAccountAtBlock4LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(account2AtBlock4LeafNode), + []byte{}, + crypto.Keccak256(account1AtBlock2LeafNode), + []byte{}, + []byte{}, + }) + block5BranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256(bankAccountAtBlock5LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(minerAccountAtBlock2LeafNode), + crypto.Keccak256(contractAccountAtBlock5LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(account2AtBlock4LeafNode), + []byte{}, + crypto.Keccak256(account1AtBlock5LeafNode), + []byte{}, + []byte{}, + }) + block6BranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256(bankAccountAtBlock5LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(minerAccountAtBlock2LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(account2AtBlock6LeafNode), + []byte{}, + crypto.Keccak256(account1AtBlock6LeafNode), + []byte{}, + []byte{}, + }) + + block2StorageBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + []byte{}, + []byte{}, + crypto.Keccak256(slot0StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(slot1StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + }) + block3StorageBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + []byte{}, + []byte{}, + crypto.Keccak256(slot0StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(slot1StorageLeafNode), + crypto.Keccak256(slot3StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + }) + block4StorageBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + []byte{}, + []byte{}, + crypto.Keccak256(slot0StorageLeafNode), + []byte{}, + crypto.Keccak256(slot2StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + }) + block5StorageBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + []byte{}, + []byte{}, + crypto.Keccak256(slot0StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(slot3StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + }) +) + +func init() { + if os.Getenv("MODE") != "statediff" { + fmt.Println("Skipping statediff test") + os.Exit(0) + } +} + +func TestBuilder(t *testing.T) { + blocks, chain := test_helpers.MakeChain(3, test_helpers.Genesis, test_helpers.TestChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block0 = test_helpers.Genesis + block1 = blocks[0] + block2 = blocks[1] + block3 = blocks[2] + params := statediff.Params{} + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + { + "testEmptyDiff", + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: emptyDiffs, + }, + }, + { + "testBlock0", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: test_helpers.NullHash, + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock0LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock1", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block1.Root(), + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + }, + &types2.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x05'}, + NodeType: types2.Leaf, + LeafKey: minerLeafKey, + NodeValue: minerAccountAtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock2", + // 1000 transferred from testBankAddress to account1Addr + // 1000 transferred from account1Addr to account2Addr + // account1addr creates a new contract + statediff.Args{ + OldStateRoot: block1.Root(), + NewStateRoot: block2.Root(), + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + }, + &types2.StateObject{ + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x05'}, + NodeType: types2.Leaf, + LeafKey: minerLeafKey, + NodeValue: minerAccountAtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock2LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{'\x02'}, + NodeType: types2.Leaf, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: slot0StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Leaf, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: slot1StorageLeafNode, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + }, + CodeAndCodeHashes: []types2.CodeAndCodeHash{ + { + Hash: test_helpers.CodeHash, + Code: test_helpers.ByteCodeAfterDeployment, + }, + }, + }, + }, + { + "testBlock3", + //the contract's storage is changed + //and the block is mined by account 2 + statediff.Args{ + OldStateRoot: block2.Root(), + NewStateRoot: block3.Root(), + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + }, + &types2.StateObject{ + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock3LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock3LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: slot3StorageLeafNode, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock3LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\nexpected state diff: %+v", diff, test.expected) + } + } +} + +func TestBuilderWithIntermediateNodes(t *testing.T) { + blocks, chain := test_helpers.MakeChain(3, test_helpers.Genesis, test_helpers.TestChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block0 = test_helpers.Genesis + block1 = blocks[0] + block2 = blocks[1] + block3 = blocks[2] + blocks = append([]*types.Block{block0}, blocks...) + params := statediff.Params{ + IntermediateStateNodes: true, + IntermediateStorageNodes: true, + } + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + { + "testEmptyDiff", + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: emptyDiffs, + }, + }, + { + "testBlock0", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: test_helpers.NullHash, + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock0LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock1", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block1.Root(), + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + }, + &types2.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block1BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x05'}, + NodeType: types2.Leaf, + LeafKey: minerLeafKey, + NodeValue: minerAccountAtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock2", + // 1000 transferred from testBankAddress to account1Addr + // 1000 transferred from account1Addr to account2Addr + // account1addr creates a new contract + statediff.Args{ + OldStateRoot: block1.Root(), + NewStateRoot: block2.Root(), + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + }, + &types2.StateObject{ + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block2BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x05'}, + NodeType: types2.Leaf, + LeafKey: minerLeafKey, + NodeValue: minerAccountAtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock2LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block2StorageBranchRootNode, + }, + { + Path: []byte{'\x02'}, + NodeType: types2.Leaf, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: slot0StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Leaf, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: slot1StorageLeafNode, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + }, + CodeAndCodeHashes: []types2.CodeAndCodeHash{ + { + Hash: test_helpers.CodeHash, + Code: test_helpers.ByteCodeAfterDeployment, + }, + }, + }, + }, + { + "testBlock3", + //the contract's storage is changed + //and the block is mined by account 2 + statediff.Args{ + OldStateRoot: block2.Root(), + NewStateRoot: block3.Root(), + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + }, + &types2.StateObject{ + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block3BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock3LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock3LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block3StorageBranchRootNode, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: slot3StorageLeafNode, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock3LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + } + + for i, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected) + } + // Let's also confirm that our root state nodes form the state root hash in the headers + if i > 0 { + block := blocks[i-1] + expectedStateRoot := block.Root() + for _, node := range test.expected.Nodes { + if bytes.Equal(node.Path, []byte{}) { + stateRoot := crypto.Keccak256Hash(node.NodeValue) + if !bytes.Equal(expectedStateRoot.Bytes(), stateRoot.Bytes()) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual stateroot: %x\r\nexpected stateroot: %x", stateRoot.Bytes(), expectedStateRoot.Bytes()) + } + } + } + } + } +} + +func TestBuilderWithWatchedAddressList(t *testing.T) { + blocks, chain := test_helpers.MakeChain(3, test_helpers.Genesis, test_helpers.TestChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block0 = test_helpers.Genesis + block1 = blocks[0] + block2 = blocks[1] + block3 = blocks[2] + params := statediff.Params{ + IntermediateStateNodes: true, + IntermediateStorageNodes: true, + WatchedAddresses: []common.Address{test_helpers.Account1Addr, test_helpers.ContractAddr}, + } + params.ComputeWatchedAddressesLeafPaths() + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + { + "testEmptyDiff", + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: emptyDiffs, + }, + }, + { + "testBlock0", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: test_helpers.NullHash, + NewStateRoot: block0.Root(), + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + }, + &types2.StateObject{ + BlockNumber: block0.Number(), + BlockHash: block0.Hash(), + Nodes: emptyDiffs, + }, + }, + { + "testBlock1", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block1.Root(), + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + }, + &types2.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block1BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock2", + //1000 transferred from testBankAddress to account1Addr + //1000 transferred from account1Addr to account2Addr + statediff.Args{ + OldStateRoot: block1.Root(), + NewStateRoot: block2.Root(), + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + }, + &types2.StateObject{ + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block2BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock2LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block2StorageBranchRootNode, + }, + { + Path: []byte{'\x02'}, + NodeType: types2.Leaf, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: slot0StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Leaf, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: slot1StorageLeafNode, + }, + }, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + }, + CodeAndCodeHashes: []types2.CodeAndCodeHash{ + { + Hash: test_helpers.CodeHash, + Code: test_helpers.ByteCodeAfterDeployment, + }, + }, + }, + }, + { + "testBlock3", + //the contract's storage is changed + //and the block is mined by account 2 + statediff.Args{ + OldStateRoot: block2.Root(), + NewStateRoot: block3.Root(), + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + }, + &types2.StateObject{ + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block3BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock3LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block3StorageBranchRootNode, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: slot3StorageLeafNode, + }, + }, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\nexpected state diff: %+v", diff, test.expected) + } + } +} + +func TestBuilderWithRemovedAccountAndStorage(t *testing.T) { + blocks, chain := test_helpers.MakeChain(6, test_helpers.Genesis, test_helpers.TestChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block3 = blocks[2] + block4 = blocks[3] + block5 = blocks[4] + block6 = blocks[5] + params := statediff.Params{ + IntermediateStateNodes: true, + IntermediateStorageNodes: true, + } + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + // blocks 0-3 are the same as in TestBuilderWithIntermediateNodes + { + "testBlock4", + statediff.Args{ + OldStateRoot: block3.Root(), + NewStateRoot: block4.Root(), + BlockNumber: block4.Number(), + BlockHash: block4.Hash(), + }, + &types2.StateObject{ + BlockNumber: block4.Number(), + BlockHash: block4.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block4BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock4LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock4LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block4StorageBranchRootNode, + }, + { + Path: []byte{'\x04'}, + NodeType: types2.Leaf, + LeafKey: slot2StorageKey.Bytes(), + NodeValue: slot2StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Removed, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: []byte{}, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Removed, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: []byte{}, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock4LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock5", + statediff.Args{ + OldStateRoot: block4.Root(), + NewStateRoot: block5.Root(), + BlockNumber: block5.Number(), + BlockHash: block5.Hash(), + }, + &types2.StateObject{ + BlockNumber: block5.Number(), + BlockHash: block5.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block5BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock5LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock5LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block5StorageBranchRootNode, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: slot3StorageLeafNode, + }, + { + Path: []byte{'\x04'}, + NodeType: types2.Removed, + LeafKey: slot2StorageKey.Bytes(), + NodeValue: []byte{}, + }, + }, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock5LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock6", + statediff.Args{ + OldStateRoot: block5.Root(), + NewStateRoot: block6.Root(), + BlockNumber: block6.Number(), + BlockHash: block6.Hash(), + }, + &types2.StateObject{ + BlockNumber: block6.Number(), + BlockHash: block6.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block6BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Removed, + LeafKey: contractLeafKey, + NodeValue: []byte{}, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Removed, + NodeValue: []byte{}, + }, + { + Path: []byte{'\x02'}, + NodeType: types2.Removed, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: []byte{}, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Removed, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: []byte{}, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock6LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock6LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected) + } + } +} + +func TestBuilderWithRemovedAccountAndStorageWithoutIntermediateNodes(t *testing.T) { + blocks, chain := test_helpers.MakeChain(6, test_helpers.Genesis, test_helpers.TestChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block3 = blocks[2] + block4 = blocks[3] + block5 = blocks[4] + block6 = blocks[5] + params := statediff.Params{ + IntermediateStateNodes: false, + IntermediateStorageNodes: false, + } + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + // blocks 0-3 are the same as in TestBuilderWithIntermediateNodes + { + "testBlock4", + statediff.Args{ + OldStateRoot: block3.Root(), + NewStateRoot: block4.Root(), + BlockNumber: block4.Number(), + BlockHash: block4.Hash(), + }, + &types2.StateObject{ + BlockNumber: block4.Number(), + BlockHash: block4.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock4LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock4LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{'\x04'}, + NodeType: types2.Leaf, + LeafKey: slot2StorageKey.Bytes(), + NodeValue: slot2StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Removed, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: []byte{}, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Removed, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: []byte{}, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock4LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock5", + statediff.Args{ + OldStateRoot: block4.Root(), + NewStateRoot: block5.Root(), + BlockNumber: block5.Number(), + BlockHash: block5.Hash(), + }, + &types2.StateObject{ + BlockNumber: block5.Number(), + BlockHash: block5.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock5LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock5LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: slot3StorageLeafNode, + }, + { + Path: []byte{'\x04'}, + NodeType: types2.Removed, + LeafKey: slot2StorageKey.Bytes(), + NodeValue: []byte{}, + }, + }, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock5LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock6", + statediff.Args{ + OldStateRoot: block5.Root(), + NewStateRoot: block6.Root(), + BlockNumber: block6.Number(), + BlockHash: block6.Hash(), + }, + &types2.StateObject{ + BlockNumber: block6.Number(), + BlockHash: block6.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{'\x06'}, + NodeType: types2.Removed, + LeafKey: contractLeafKey, + NodeValue: []byte{}, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{'\x02'}, + NodeType: types2.Removed, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: []byte{}, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Removed, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: []byte{}, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock6LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock6LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected) + } + } +} + +func TestBuilderWithRemovedNonWatchedAccount(t *testing.T) { + blocks, chain := test_helpers.MakeChain(6, test_helpers.Genesis, test_helpers.TestChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block3 = blocks[2] + block4 = blocks[3] + block5 = blocks[4] + block6 = blocks[5] + params := statediff.Params{ + IntermediateStateNodes: true, + IntermediateStorageNodes: true, + WatchedAddresses: []common.Address{test_helpers.Account1Addr, test_helpers.Account2Addr}, + } + params.ComputeWatchedAddressesLeafPaths() + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + { + "testBlock4", + statediff.Args{ + OldStateRoot: block3.Root(), + NewStateRoot: block4.Root(), + BlockNumber: block4.Number(), + BlockHash: block4.Hash(), + }, + &types2.StateObject{ + BlockNumber: block4.Number(), + BlockHash: block4.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block4BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock4LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock5", + statediff.Args{ + OldStateRoot: block4.Root(), + NewStateRoot: block5.Root(), + BlockNumber: block5.Number(), + BlockHash: block5.Hash(), + }, + &types2.StateObject{ + BlockNumber: block5.Number(), + BlockHash: block5.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block5BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock5LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock6", + statediff.Args{ + OldStateRoot: block5.Root(), + NewStateRoot: block6.Root(), + BlockNumber: block6.Number(), + BlockHash: block6.Hash(), + }, + &types2.StateObject{ + BlockNumber: block6.Number(), + BlockHash: block6.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block6BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock6LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock6LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected) + } + } +} + +func TestBuilderWithRemovedWatchedAccount(t *testing.T) { + blocks, chain := test_helpers.MakeChain(6, test_helpers.Genesis, test_helpers.TestChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block3 = blocks[2] + block4 = blocks[3] + block5 = blocks[4] + block6 = blocks[5] + params := statediff.Params{ + IntermediateStateNodes: true, + IntermediateStorageNodes: true, + WatchedAddresses: []common.Address{test_helpers.Account1Addr, test_helpers.ContractAddr}, + } + params.ComputeWatchedAddressesLeafPaths() + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + { + "testBlock4", + statediff.Args{ + OldStateRoot: block3.Root(), + NewStateRoot: block4.Root(), + BlockNumber: block4.Number(), + BlockHash: block4.Hash(), + }, + &types2.StateObject{ + BlockNumber: block4.Number(), + BlockHash: block4.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block4BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock4LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block4StorageBranchRootNode, + }, + { + Path: []byte{'\x04'}, + NodeType: types2.Leaf, + LeafKey: slot2StorageKey.Bytes(), + NodeValue: slot2StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Removed, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: []byte{}, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Removed, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: []byte{}, + }, + }, + }, + }, + }, + }, + { + "testBlock5", + statediff.Args{ + OldStateRoot: block4.Root(), + NewStateRoot: block5.Root(), + BlockNumber: block5.Number(), + BlockHash: block5.Hash(), + }, + &types2.StateObject{ + BlockNumber: block5.Number(), + BlockHash: block5.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block5BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock5LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block5StorageBranchRootNode, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: slot3StorageLeafNode, + }, + { + Path: []byte{'\x04'}, + NodeType: types2.Removed, + LeafKey: slot2StorageKey.Bytes(), + NodeValue: []byte{}, + }, + }, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock5LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock6", + statediff.Args{ + OldStateRoot: block5.Root(), + NewStateRoot: block6.Root(), + BlockNumber: block6.Number(), + BlockHash: block6.Hash(), + }, + &types2.StateObject{ + BlockNumber: block6.Number(), + BlockHash: block6.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block6BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Removed, + LeafKey: contractLeafKey, + NodeValue: []byte{}, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Removed, + NodeValue: []byte{}, + }, + { + Path: []byte{'\x02'}, + NodeType: types2.Removed, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: []byte{}, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Removed, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: []byte{}, + }, + }, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock6LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected) + } + } +} + +var ( + slot00StorageValue = common.Hex2Bytes("9471562b71999873db5b286df957af199ec94617f7") // prefixed TestBankAddress + + slot00StorageLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("390decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563"), + slot00StorageValue, + }) + + contractAccountAtBlock01, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 1, + Balance: big.NewInt(0), + CodeHash: common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127").Bytes(), + Root: crypto.Keccak256Hash(block01StorageBranchRootNode), + }) + contractAccountAtBlock01LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3cb2583748c26e89ef19c2a8529b05a270f735553b4d44b6f2a1894987a71c8b"), + contractAccountAtBlock01, + }) + + bankAccountAtBlock01, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 1, + Balance: big.NewInt(3999629697375000000), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + bankAccountAtBlock01LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock01, + }) + bankAccountAtBlock02, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 2, + Balance: big.NewInt(5999607323457344852), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + bankAccountAtBlock02LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("2000bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccountAtBlock02, + }) + + block01BranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + crypto.Keccak256Hash(bankAccountAtBlock01LeafNode), + crypto.Keccak256Hash(contractAccountAtBlock01LeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + }) + + block01StorageBranchRootNode, _ = rlp.EncodeToBytes(&[]interface{}{ + []byte{}, + []byte{}, + crypto.Keccak256(slot00StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + crypto.Keccak256(slot1StorageLeafNode), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + }) +) + +func TestBuilderWithMovedAccount(t *testing.T) { + blocks, chain := test_helpers.MakeChain(2, test_helpers.Genesis, test_helpers.TestSelfDestructChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block0 = test_helpers.Genesis + block1 = blocks[0] + block2 = blocks[1] + params := statediff.Params{ + IntermediateStateNodes: true, + IntermediateStorageNodes: true, + } + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + { + "testBlock1", + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block1.Root(), + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + }, + &types2.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block01BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock01LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x01'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock01LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block01StorageBranchRootNode, + }, + { + Path: []byte{'\x02'}, + NodeType: types2.Leaf, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: slot00StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Leaf, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: slot1StorageLeafNode, + }, + }, + }, + }, + CodeAndCodeHashes: []types2.CodeAndCodeHash{ + { + Hash: test_helpers.CodeHash, + Code: test_helpers.ByteCodeAfterDeployment, + }, + }, + }, + }, + { + "testBlock2", + statediff.Args{ + OldStateRoot: block1.Root(), + NewStateRoot: block2.Root(), + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + }, + &types2.StateObject{ + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock02LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x01'}, + NodeType: types2.Removed, + LeafKey: contractLeafKey, + NodeValue: []byte{}, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Removed, + }, + { + Path: []byte{'\x02'}, + NodeType: types2.Removed, + LeafKey: slot0StorageKey.Bytes(), + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Removed, + LeafKey: slot1StorageKey.Bytes(), + }, + }, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Removed, + NodeValue: []byte{}, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected) + } + } +} + +func TestBuilderWithMovedAccountOnlyLeafs(t *testing.T) { + blocks, chain := test_helpers.MakeChain(2, test_helpers.Genesis, test_helpers.TestSelfDestructChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block0 = test_helpers.Genesis + block1 = blocks[0] + block2 = blocks[1] + params := statediff.Params{ + IntermediateStateNodes: false, + IntermediateStorageNodes: false, + } + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *types2.StateObject + }{ + { + "testBlock1", + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block1.Root(), + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + }, + &types2.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock01LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x01'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock01LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{'\x02'}, + NodeType: types2.Leaf, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: slot00StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Leaf, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: slot1StorageLeafNode, + }, + }, + }, + }, + CodeAndCodeHashes: []types2.CodeAndCodeHash{ + { + Hash: test_helpers.CodeHash, + Code: test_helpers.ByteCodeAfterDeployment, + }, + }, + }, + }, + { + "testBlock2", + statediff.Args{ + OldStateRoot: block1.Root(), + NewStateRoot: block2.Root(), + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + }, + &types2.StateObject{ + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock02LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x01'}, + NodeType: types2.Removed, + LeafKey: contractLeafKey, + NodeValue: []byte{}, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{'\x02'}, + NodeType: types2.Removed, + LeafKey: slot0StorageKey.Bytes(), + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Removed, + LeafKey: slot1StorageKey.Bytes(), + }, + }, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Removed, + NodeValue: []byte{}, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\r\n\r\n\r\nexpected state diff: %+v", diff, test.expected) + } + } +} + +func TestBuildStateTrie(t *testing.T) { + blocks, chain := test_helpers.MakeChain(3, test_helpers.Genesis, test_helpers.TestChainGen) + contractLeafKey = test_helpers.AddressToLeafKey(test_helpers.ContractAddr) + defer chain.Stop() + block1 = blocks[0] + block2 = blocks[1] + block3 = blocks[2] + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + block *types.Block + expected *types2.StateObject + }{ + { + "testBlock1", + block1, + &types2.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block1BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x05'}, + NodeType: types2.Leaf, + LeafKey: minerLeafKey, + NodeValue: minerAccountAtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock1LeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock2", + block2, + &types2.StateObject{ + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block2BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x05'}, + NodeType: types2.Leaf, + LeafKey: minerLeafKey, + NodeValue: minerAccountAtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock2LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block2StorageBranchRootNode, + }, + { + Path: []byte{'\x02'}, + NodeType: types2.Leaf, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: slot0StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Leaf, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: slot1StorageLeafNode, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + }, + CodeAndCodeHashes: []types2.CodeAndCodeHash{ + { + Hash: test_helpers.CodeHash, + Code: test_helpers.ByteCodeAfterDeployment, + }, + }, + }, + }, + { + "testBlock3", + block3, + &types2.StateObject{ + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + Nodes: []types2.StateNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block3BranchRootNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountAtBlock3LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x05'}, + NodeType: types2.Leaf, + LeafKey: minerLeafKey, + NodeValue: minerAccountAtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1AtBlock2LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x06'}, + NodeType: types2.Leaf, + LeafKey: contractLeafKey, + NodeValue: contractAccountAtBlock3LeafNode, + StorageNodes: []types2.StorageNode{ + { + Path: []byte{}, + NodeType: types2.Branch, + NodeValue: block3StorageBranchRootNode, + }, + { + Path: []byte{'\x02'}, + NodeType: types2.Leaf, + LeafKey: slot0StorageKey.Bytes(), + NodeValue: slot0StorageLeafNode, + }, + { + Path: []byte{'\x0b'}, + NodeType: types2.Leaf, + LeafKey: slot1StorageKey.Bytes(), + NodeValue: slot1StorageLeafNode, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: slot3StorageKey.Bytes(), + NodeValue: slot3StorageLeafNode, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: types2.Leaf, + LeafKey: test_helpers.Account2LeafKey, + NodeValue: account2AtBlock3LeafNode, + StorageNodes: emptyStorage, + }, + }, + CodeAndCodeHashes: []types2.CodeAndCodeHash{ + { + Hash: test_helpers.CodeHash, + Code: test_helpers.ByteCodeAfterDeployment, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateTrieObject(test.block) + if err != nil { + t.Error(err) + } + receivedStateTrieRlp, err := rlp.EncodeToBytes(&diff) + if err != nil { + t.Error(err) + } + expectedStateTrieRlp, err := rlp.EncodeToBytes(test.expected) + if err != nil { + t.Error(err) + } + sort.Slice(receivedStateTrieRlp, func(i, j int) bool { return receivedStateTrieRlp[i] < receivedStateTrieRlp[j] }) + sort.Slice(expectedStateTrieRlp, func(i, j int) bool { return expectedStateTrieRlp[i] < expectedStateTrieRlp[j] }) + if !bytes.Equal(receivedStateTrieRlp, expectedStateTrieRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state trie: %+v\r\n\r\n\r\nexpected state trie: %+v", diff, test.expected) + } + } +} + +/* +pragma solidity ^0.5.10; + +contract test { + address payable owner; + + modifier onlyOwner { + require( + msg.sender == owner, + "Only owner can call this function." + ); + _; + } + + uint256[100] data; + + constructor() public { + owner = msg.sender; + data = [1]; + } + + function Put(uint256 addr, uint256 value) public { + data[addr] = value; + } + + function close() public onlyOwner { //onlyOwner is custom modifier + selfdestruct(owner); // `owner` is the owners address + } +} +*/ diff --git a/statediff/config.go b/statediff/config.go new file mode 100644 index 000000000..0e3195524 --- /dev/null +++ b/statediff/config.go @@ -0,0 +1,89 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package statediff + +import ( + "context" + "math/big" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" +) + +// Config contains instantiation parameters for the state diffing service +type Config struct { + // The configuration used for the stateDiff Indexer + IndexerConfig interfaces.Config + // A unique ID used for this service + ID string + // Name for the client this service is running + ClientName string + // Whether to enable writing state diffs directly to track blockchain head + EnableWriteLoop bool + // Size of the worker pool + NumWorkers uint + // Should the statediff service wait until geth has synced to the head of the blockchain? + WaitForSync bool + // Context + Context context.Context +} + +// Params contains config parameters for the state diff builder +type Params struct { + IntermediateStateNodes bool + IntermediateStorageNodes bool + IncludeBlock bool + IncludeReceipts bool + IncludeTD bool + IncludeCode bool + WatchedAddresses []common.Address + watchedAddressesLeafPaths [][]byte +} + +// ComputeWatchedAddressesLeafPaths populates a slice with paths (hex_encoding(Keccak256)) of each of the WatchedAddresses +func (p *Params) ComputeWatchedAddressesLeafPaths() { + p.watchedAddressesLeafPaths = make([][]byte, len(p.WatchedAddresses)) + for i, address := range p.WatchedAddresses { + p.watchedAddressesLeafPaths[i] = keybytesToHex(crypto.Keccak256(address.Bytes())) + } +} + +// ParamsWithMutex allows to lock the parameters while they are being updated | read from +type ParamsWithMutex struct { + Params + sync.RWMutex +} + +// Args bundles the arguments for the state diff builder +type Args struct { + OldStateRoot, NewStateRoot, BlockHash common.Hash + BlockNumber *big.Int +} + +// https://github.com/ethereum/go-ethereum/blob/master/trie/encoding.go#L97 +func keybytesToHex(str []byte) []byte { + l := len(str)*2 + 1 + var nibbles = make([]byte, l) + for i, b := range str { + nibbles[i*2] = b / 16 + nibbles[i*2+1] = b % 16 + } + nibbles[l-1] = 16 + return nibbles +} diff --git a/statediff/docs/KnownGaps.md b/statediff/docs/KnownGaps.md new file mode 100644 index 000000000..72e712f47 --- /dev/null +++ b/statediff/docs/KnownGaps.md @@ -0,0 +1,17 @@ +# Overview + +This document will provide some insight into the `known_gaps` table, their use cases, and implementation. Please refer to the [following PR](https://github.com/vulcanize/go-ethereum/pull/217) and the [following epic](https://github.com/vulcanize/ops/issues/143) to grasp their inception. + +![known gaps](diagrams/KnownGapsProcess.png) + +# Use Cases + +The known gaps table is updated when the following events occur: + +1. At start up we check the latest block from the `eth.headers_cid` table. We compare the first block that we are processing with the latest block from the DB. If they are not one unit of expectedDifference away from each other, add the gap between the two blocks. +2. If there is any error in processing a block (db connection, deadlock, etc), add that block to the knownErrorBlocks slice, when the next block is successfully written, write this slice into the DB. + +# Glossary + +1. `expectedDifference (number)` - This number indicates what the difference between two blocks should be. If we are capturing all events on a geth node then this number would be `1`. But once we scale nodes, the `expectedDifference` might be `2` or greater. +2. `processingKey (number)` - This number can be used to keep track of different geth nodes and their specific `expectedDifference`. diff --git a/statediff/docs/README.md b/statediff/docs/README.md new file mode 100644 index 000000000..51b63e207 --- /dev/null +++ b/statediff/docs/README.md @@ -0,0 +1,3 @@ +# Overview + +This folder keeps tracks of random documents as they relate to the `statediff` service. diff --git a/statediff/docs/database.md b/statediff/docs/database.md new file mode 100644 index 000000000..847bc8fa2 --- /dev/null +++ b/statediff/docs/database.md @@ -0,0 +1,21 @@ +# Overview + +This document will go through some notes on the database component of the statediff service. + +# Components + +- Indexer: The indexer creates IPLD and DB models to insert to the Postgres DB. It performs the insert utilizing and atomic function. +- Builder: The builder constructs the statediff object that needs to be inserted. +- Known Gaps: Captures any gaps that might have occured and either writes them to the DB, local sql file, to prometeus, or a local error. + +# Making Code Changes + +## Adding a New Function to the Indexer + +If you want to implement a new feature for adding data to the database. Keep the following in mind: + +1. You need to handle `sql`, `file`, and `dump`. + 1. `sql` - Contains the code needed to write directly to the `sql` db. + 2. `file` - Contains all the code required to write the SQL statements to a file. + 3. `dump` - Contains all the code for outputting events to the console. +2. You will have to add it to the `interfaces.StateDiffIndexer` interface. diff --git a/statediff/docs/diagrams/KnownGapsProcess.png b/statediff/docs/diagrams/KnownGapsProcess.png new file mode 100644 index 0000000000000000000000000000000000000000..40ebaa80aad2fb03b6ff80ca364273e23039a7b9 GIT binary patch literal 33340 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 literal 0 HcmV?d00001 diff --git a/statediff/helpers.go b/statediff/helpers.go new file mode 100644 index 000000000..c4ffdee95 --- /dev/null +++ b/statediff/helpers.go @@ -0,0 +1,63 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package statediff + +import ( + "encoding/json" + "fmt" + "os" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum/go-ethereum/params" +) + +// LoadConfig loads chain config from json file +func LoadConfig(chainConfigPath string) (*params.ChainConfig, error) { + file, err := os.Open(chainConfigPath) + if err != nil { + log.Error(fmt.Sprintf("Failed to read chain config file: %v", err)) + + return nil, err + } + defer file.Close() + + chainConfig := new(params.ChainConfig) + if err := json.NewDecoder(file).Decode(chainConfig); err != nil { + log.Error(fmt.Sprintf("invalid chain config file: %v", err)) + + return nil, err + } + + log.Info(fmt.Sprintf("Using chain config from %s file. Content %+v", chainConfigPath, chainConfig)) + + return chainConfig, nil +} + +// ChainConfig returns the appropriate ethereum chain config for the provided chain id +func ChainConfig(chainID uint64) (*params.ChainConfig, error) { + switch chainID { + case 1: + return params.MainnetChainConfig, nil + case 4: + return params.RinkebyChainConfig, nil + case 5: + return params.GoerliChainConfig, nil + default: + return nil, fmt.Errorf("chain config for chainid %d not available", chainID) + } +} diff --git a/statediff/indexer/constructor.go b/statediff/indexer/constructor.go new file mode 100644 index 000000000..0f07e7410 --- /dev/null +++ b/statediff/indexer/constructor.go @@ -0,0 +1,81 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package indexer + +import ( + "context" + "fmt" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/statediff/indexer/database/dump" + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/node" + "github.com/ethereum/go-ethereum/statediff/indexer/shared" +) + +// NewStateDiffIndexer creates and returns an implementation of the StateDiffIndexer interface. +func NewStateDiffIndexer(ctx context.Context, chainConfig *params.ChainConfig, nodeInfo node.Info, config interfaces.Config) (sql.Database, interfaces.StateDiffIndexer, error) { + switch config.Type() { + case shared.FILE: + log.Info("Starting statediff service in SQL file writing mode") + fc, ok := config.(file.Config) + if !ok { + return nil, nil, fmt.Errorf("file config is not the correct type: got %T, expected %T", config, file.Config{}) + } + fc.NodeInfo = nodeInfo + ind, err := file.NewStateDiffIndexer(ctx, chainConfig, fc) + return nil, ind, err + case shared.POSTGRES: + log.Info("Starting statediff service in Postgres writing mode") + pgc, ok := config.(postgres.Config) + if !ok { + return nil, nil, fmt.Errorf("postgres config is not the correct type: got %T, expected %T", config, postgres.Config{}) + } + var err error + var driver sql.Driver + switch pgc.Driver { + case postgres.PGX: + driver, err = postgres.NewPGXDriver(ctx, pgc, nodeInfo) + if err != nil { + return nil, nil, err + } + case postgres.SQLX: + driver, err = postgres.NewSQLXDriver(ctx, pgc, nodeInfo) + if err != nil { + return nil, nil, err + } + default: + return nil, nil, fmt.Errorf("unrecognized Postgres driver type: %s", pgc.Driver) + } + db := postgres.NewPostgresDB(driver, pgc.Upsert) + ind, err := sql.NewStateDiffIndexer(ctx, chainConfig, db) + return db, ind, err + case shared.DUMP: + log.Info("Starting statediff service in data dump mode") + dumpc, ok := config.(dump.Config) + if !ok { + return nil, nil, fmt.Errorf("dump config is not the correct type: got %T, expected %T", config, dump.Config{}) + } + return nil, dump.NewStateDiffIndexer(chainConfig, dumpc), nil + default: + return nil, nil, fmt.Errorf("unrecognized database type: %s", config.Type()) + } +} diff --git a/statediff/indexer/database/dump/batch_tx.go b/statediff/indexer/database/dump/batch_tx.go new file mode 100644 index 000000000..ee195a558 --- /dev/null +++ b/statediff/indexer/database/dump/batch_tx.go @@ -0,0 +1,97 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package dump + +import ( + "fmt" + "io" + + "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + + "github.com/ethereum/go-ethereum/statediff/indexer/models" + blockstore "github.com/ipfs/go-ipfs-blockstore" + dshelp "github.com/ipfs/go-ipfs-ds-help" + node "github.com/ipfs/go-ipld-format" +) + +// BatchTx wraps a void with the state necessary for building the tx concurrently during trie difference iteration +type BatchTx struct { + BlockNumber string + dump io.Writer + quit chan struct{} + iplds chan models.IPLDModel + ipldCache models.IPLDBatch + + submit func(blockTx *BatchTx, err error) error +} + +// Submit satisfies indexer.AtomicTx +func (tx *BatchTx) Submit(err error) error { + return tx.submit(tx, err) +} + +func (tx *BatchTx) flush() error { + if _, err := fmt.Fprintf(tx.dump, "%+v\r\n", tx.ipldCache); err != nil { + return err + } + tx.ipldCache = models.IPLDBatch{} + return nil +} + +// run in background goroutine to synchronize concurrent appends to the ipldCache +func (tx *BatchTx) cache() { + for { + select { + case i := <-tx.iplds: + tx.ipldCache.Keys = append(tx.ipldCache.Keys, i.Key) + tx.ipldCache.Values = append(tx.ipldCache.Values, i.Data) + case <-tx.quit: + tx.ipldCache = models.IPLDBatch{} + return + } + } +} + +func (tx *BatchTx) cacheDirect(key string, value []byte) { + tx.iplds <- models.IPLDModel{ + BlockNumber: tx.BlockNumber, + Key: key, + Data: value, + } +} + +func (tx *BatchTx) cacheIPLD(i node.Node) { + tx.iplds <- models.IPLDModel{ + BlockNumber: tx.BlockNumber, + Key: blockstore.BlockPrefix.String() + dshelp.MultihashToDsKey(i.Cid().Hash()).String(), + Data: i.RawData(), + } +} + +func (tx *BatchTx) cacheRaw(codec, mh uint64, raw []byte) (string, string, error) { + c, err := ipld.RawdataToCid(codec, raw, mh) + if err != nil { + return "", "", err + } + prefixedKey := blockstore.BlockPrefix.String() + dshelp.MultihashToDsKey(c.Hash()).String() + tx.iplds <- models.IPLDModel{ + BlockNumber: tx.BlockNumber, + Key: prefixedKey, + Data: raw, + } + return c.String(), prefixedKey, err +} diff --git a/statediff/indexer/database/dump/config.go b/statediff/indexer/database/dump/config.go new file mode 100644 index 000000000..6fb1f0a9e --- /dev/null +++ b/statediff/indexer/database/dump/config.go @@ -0,0 +1,79 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package dump + +import ( + "fmt" + "io" + "strings" + + "github.com/ethereum/go-ethereum/statediff/indexer/shared" +) + +// DumpType to explicitly type the dump destination +type DumpType string + +const ( + STDOUT = "Stdout" + STDERR = "Stderr" + DISCARD = "Discard" + UNKNOWN = "Unknown" +) + +// ResolveDumpType resolves the dump type for the provided string +func ResolveDumpType(str string) (DumpType, error) { + switch strings.ToLower(str) { + case "stdout", "out", "std out": + return STDOUT, nil + case "stderr", "err", "std err": + return STDERR, nil + case "discard", "void", "devnull", "dev null": + return DISCARD, nil + default: + return UNKNOWN, fmt.Errorf("unrecognized dump type: %s", str) + } +} + +// Config for data dump +type Config struct { + Dump io.WriteCloser +} + +// Type satisfies interfaces.Config +func (c Config) Type() shared.DBType { + return shared.DUMP +} + +// NewDiscardWriterCloser returns a discardWrapper wrapping io.Discard +func NewDiscardWriterCloser() io.WriteCloser { + return discardWrapper{blackhole: io.Discard} +} + +// discardWrapper wraps io.Discard with io.Closer +type discardWrapper struct { + blackhole io.Writer +} + +// Write satisfies io.Writer +func (dw discardWrapper) Write(b []byte) (int, error) { + return dw.blackhole.Write(b) +} + +// Close satisfies io.Closer +func (dw discardWrapper) Close() error { + return nil +} diff --git a/statediff/indexer/database/dump/indexer.go b/statediff/indexer/database/dump/indexer.go new file mode 100644 index 000000000..213d9b55d --- /dev/null +++ b/statediff/indexer/database/dump/indexer.go @@ -0,0 +1,535 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package dump + +import ( + "fmt" + "io" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + + ipld2 "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + "github.com/ethereum/go-ethereum/statediff/indexer/shared" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +var _ interfaces.StateDiffIndexer = &StateDiffIndexer{} + +// StateDiffIndexer satisfies the indexer.StateDiffIndexer interface for ethereum statediff objects on top of a void +type StateDiffIndexer struct { + dump io.WriteCloser + chainConfig *params.ChainConfig +} + +// NewStateDiffIndexer creates a void implementation of interfaces.StateDiffIndexer +func NewStateDiffIndexer(chainConfig *params.ChainConfig, config Config) *StateDiffIndexer { + return &StateDiffIndexer{ + dump: config.Dump, + chainConfig: chainConfig, + } +} + +// ReportDBMetrics has nothing to report for dump +func (sdi *StateDiffIndexer) ReportDBMetrics(time.Duration, <-chan bool) {} + +// PushBlock pushes and indexes block data in sql, except state & storage nodes (includes header, uncles, transactions & receipts) +// Returns an initiated DB transaction which must be Closed via defer to commit or rollback +func (sdi *StateDiffIndexer) PushBlock(block *types.Block, receipts types.Receipts, totalDifficulty *big.Int) (interfaces.Batch, error) { + start, t := time.Now(), time.Now() + blockHash := block.Hash() + blockHashStr := blockHash.String() + height := block.NumberU64() + traceMsg := fmt.Sprintf("indexer stats for statediff at %d with hash %s:\r\n", height, blockHashStr) + transactions := block.Transactions() + // Derive any missing fields + if err := receipts.DeriveFields(sdi.chainConfig, blockHash, height, transactions); err != nil { + return nil, err + } + + // Generate the block iplds + headerNode, uncleNodes, txNodes, txTrieNodes, rctNodes, rctTrieNodes, logTrieNodes, logLeafNodeCIDs, rctLeafNodeCIDs, err := ipld2.FromBlockAndReceipts(block, receipts) + if err != nil { + return nil, fmt.Errorf("error creating IPLD nodes from block and receipts: %v", err) + } + + if len(txNodes) != len(rctNodes) || len(rctNodes) != len(rctLeafNodeCIDs) { + return nil, fmt.Errorf("expected number of transactions (%d), receipts (%d), and receipt trie leaf nodes (%d) to be equal", len(txNodes), len(rctNodes), len(rctLeafNodeCIDs)) + } + if len(txTrieNodes) != len(rctTrieNodes) { + return nil, fmt.Errorf("expected number of tx trie (%d) and rct trie (%d) nodes to be equal", len(txTrieNodes), len(rctTrieNodes)) + } + + // Calculate reward + var reward *big.Int + // in PoA networks block reward is 0 + if sdi.chainConfig.Clique != nil { + reward = big.NewInt(0) + } else { + reward = shared.CalcEthBlockReward(block.Header(), block.Uncles(), block.Transactions(), receipts) + } + t = time.Now() + + blockTx := &BatchTx{ + BlockNumber: block.Number().String(), + dump: sdi.dump, + iplds: make(chan models.IPLDModel), + quit: make(chan struct{}), + ipldCache: models.IPLDBatch{}, + submit: func(self *BatchTx, err error) error { + close(self.quit) + close(self.iplds) + tDiff := time.Since(t) + metrics.IndexerMetrics.StateStoreCodeProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("state, storage, and code storage processing time: %s\r\n", tDiff.String()) + t = time.Now() + if err := self.flush(); err != nil { + traceMsg += fmt.Sprintf(" TOTAL PROCESSING DURATION: %s\r\n", time.Since(start).String()) + log.Debug(traceMsg) + return err + } + tDiff = time.Since(t) + metrics.IndexerMetrics.PostgresCommitTimer.Update(tDiff) + traceMsg += fmt.Sprintf("postgres transaction commit duration: %s\r\n", tDiff.String()) + traceMsg += fmt.Sprintf(" TOTAL PROCESSING DURATION: %s\r\n", time.Since(start).String()) + log.Debug(traceMsg) + return err + }, + } + go blockTx.cache() + + tDiff := time.Since(t) + metrics.IndexerMetrics.FreePostgresTimer.Update(tDiff) + + traceMsg += fmt.Sprintf("time spent waiting for free postgres tx: %s:\r\n", tDiff.String()) + t = time.Now() + + // Publish and index header, collect headerID + var headerID string + headerID, err = sdi.processHeader(blockTx, block.Header(), headerNode, reward, totalDifficulty) + if err != nil { + return nil, err + } + tDiff = time.Since(t) + metrics.IndexerMetrics.HeaderProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("header processing time: %s\r\n", tDiff.String()) + t = time.Now() + // Publish and index uncles + err = sdi.processUncles(blockTx, headerID, block.Number(), uncleNodes) + if err != nil { + return nil, err + } + tDiff = time.Since(t) + metrics.IndexerMetrics.UncleProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("uncle processing time: %s\r\n", tDiff.String()) + t = time.Now() + // Publish and index receipts and txs + err = sdi.processReceiptsAndTxs(blockTx, processArgs{ + headerID: headerID, + blockNumber: block.Number(), + receipts: receipts, + txs: transactions, + rctNodes: rctNodes, + rctTrieNodes: rctTrieNodes, + txNodes: txNodes, + txTrieNodes: txTrieNodes, + logTrieNodes: logTrieNodes, + logLeafNodeCIDs: logLeafNodeCIDs, + rctLeafNodeCIDs: rctLeafNodeCIDs, + }) + if err != nil { + return nil, err + } + tDiff = time.Since(t) + metrics.IndexerMetrics.TxAndRecProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("tx and receipt processing time: %s\r\n", tDiff.String()) + t = time.Now() + + return blockTx, err +} + +// processHeader publishes and indexes a header IPLD in Postgres +// it returns the headerID +func (sdi *StateDiffIndexer) processHeader(tx *BatchTx, header *types.Header, headerNode node.Node, reward, td *big.Int) (string, error) { + tx.cacheIPLD(headerNode) + + headerID := header.Hash().String() + mod := models.HeaderModel{ + CID: headerNode.Cid().String(), + MhKey: shared.MultihashKeyFromCID(headerNode.Cid()), + ParentHash: header.ParentHash.String(), + BlockNumber: header.Number.String(), + BlockHash: headerID, + TotalDifficulty: td.String(), + Reward: reward.String(), + Bloom: header.Bloom.Bytes(), + StateRoot: header.Root.String(), + RctRoot: header.ReceiptHash.String(), + TxRoot: header.TxHash.String(), + UncleRoot: header.UncleHash.String(), + Timestamp: header.Time, + Coinbase: header.Coinbase.String(), + } + _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", mod) + return headerID, err +} + +// processUncles publishes and indexes uncle IPLDs in Postgres +func (sdi *StateDiffIndexer) processUncles(tx *BatchTx, headerID string, blockNumber *big.Int, uncleNodes []*ipld2.EthHeader) error { + // publish and index uncles + for _, uncleNode := range uncleNodes { + tx.cacheIPLD(uncleNode) + var uncleReward *big.Int + // in PoA networks uncle reward is 0 + if sdi.chainConfig.Clique != nil { + uncleReward = big.NewInt(0) + } else { + uncleReward = shared.CalcUncleMinerReward(blockNumber.Uint64(), uncleNode.Number.Uint64()) + } + uncle := models.UncleModel{ + BlockNumber: blockNumber.String(), + HeaderID: headerID, + CID: uncleNode.Cid().String(), + MhKey: shared.MultihashKeyFromCID(uncleNode.Cid()), + ParentHash: uncleNode.ParentHash.String(), + BlockHash: uncleNode.Hash().String(), + Reward: uncleReward.String(), + } + if _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", uncle); err != nil { + return err + } + } + return nil +} + +// processArgs bundles arguments to processReceiptsAndTxs +type processArgs struct { + headerID string + blockNumber *big.Int + receipts types.Receipts + txs types.Transactions + rctNodes []*ipld2.EthReceipt + rctTrieNodes []*ipld2.EthRctTrie + txNodes []*ipld2.EthTx + txTrieNodes []*ipld2.EthTxTrie + logTrieNodes [][]node.Node + logLeafNodeCIDs [][]cid.Cid + rctLeafNodeCIDs []cid.Cid +} + +// processReceiptsAndTxs publishes and indexes receipt and transaction IPLDs in Postgres +func (sdi *StateDiffIndexer) processReceiptsAndTxs(tx *BatchTx, args processArgs) error { + // Process receipts and txs + signer := types.MakeSigner(sdi.chainConfig, args.blockNumber) + for i, receipt := range args.receipts { + for _, logTrieNode := range args.logTrieNodes[i] { + tx.cacheIPLD(logTrieNode) + } + txNode := args.txNodes[i] + tx.cacheIPLD(txNode) + + // Indexing + // index tx + trx := args.txs[i] + trxID := trx.Hash().String() + + var val string + if trx.Value() != nil { + val = trx.Value().String() + } + + // derive sender for the tx that corresponds with this receipt + from, err := types.Sender(signer, trx) + if err != nil { + return fmt.Errorf("error deriving tx sender: %v", err) + } + txModel := models.TxModel{ + BlockNumber: args.blockNumber.String(), + HeaderID: args.headerID, + Dst: shared.HandleZeroAddrPointer(trx.To()), + Src: shared.HandleZeroAddr(from), + TxHash: trxID, + Index: int64(i), + Data: trx.Data(), + CID: txNode.Cid().String(), + MhKey: shared.MultihashKeyFromCID(txNode.Cid()), + Type: trx.Type(), + Value: val, + } + if _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", txModel); err != nil { + return err + } + + // index access list if this is one + for j, accessListElement := range trx.AccessList() { + storageKeys := make([]string, len(accessListElement.StorageKeys)) + for k, storageKey := range accessListElement.StorageKeys { + storageKeys[k] = storageKey.Hex() + } + accessListElementModel := models.AccessListElementModel{ + BlockNumber: args.blockNumber.String(), + TxID: trxID, + Index: int64(j), + Address: accessListElement.Address.Hex(), + StorageKeys: storageKeys, + } + if _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", accessListElementModel); err != nil { + return err + } + } + + // this is the contract address if this receipt is for a contract creation tx + contract := shared.HandleZeroAddr(receipt.ContractAddress) + var contractHash string + if contract != "" { + contractHash = crypto.Keccak256Hash(common.HexToAddress(contract).Bytes()).String() + } + + // index the receipt + if !args.rctLeafNodeCIDs[i].Defined() { + return fmt.Errorf("invalid receipt leaf node cid") + } + + rctModel := &models.ReceiptModel{ + BlockNumber: args.blockNumber.String(), + HeaderID: args.headerID, + TxID: trxID, + Contract: contract, + ContractHash: contractHash, + LeafCID: args.rctLeafNodeCIDs[i].String(), + LeafMhKey: shared.MultihashKeyFromCID(args.rctLeafNodeCIDs[i]), + LogRoot: args.rctNodes[i].LogRoot.String(), + } + if len(receipt.PostState) == 0 { + rctModel.PostStatus = receipt.Status + } else { + rctModel.PostState = common.Bytes2Hex(receipt.PostState) + } + + if _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", rctModel); err != nil { + return err + } + + logDataSet := make([]*models.LogsModel, len(receipt.Logs)) + for idx, l := range receipt.Logs { + topicSet := make([]string, 4) + for ti, topic := range l.Topics { + topicSet[ti] = topic.Hex() + } + + if !args.logLeafNodeCIDs[i][idx].Defined() { + return fmt.Errorf("invalid log cid") + } + + logDataSet[idx] = &models.LogsModel{ + BlockNumber: args.blockNumber.String(), + HeaderID: args.headerID, + ReceiptID: trxID, + Address: l.Address.String(), + Index: int64(l.Index), + Data: l.Data, + LeafCID: args.logLeafNodeCIDs[i][idx].String(), + LeafMhKey: shared.MultihashKeyFromCID(args.logLeafNodeCIDs[i][idx]), + Topic0: topicSet[0], + Topic1: topicSet[1], + Topic2: topicSet[2], + Topic3: topicSet[3], + } + } + + if _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", logDataSet); err != nil { + return err + } + } + + // publish trie nodes, these aren't indexed directly + for i, n := range args.txTrieNodes { + tx.cacheIPLD(n) + tx.cacheIPLD(args.rctTrieNodes[i]) + } + + return nil +} + +// PushStateNode publishes and indexes a state diff node object (including any child storage nodes) in the IPLD sql +func (sdi *StateDiffIndexer) PushStateNode(batch interfaces.Batch, stateNode sdtypes.StateNode, headerID string) error { + tx, ok := batch.(*BatchTx) + if !ok { + return fmt.Errorf("dump: batch is expected to be of type %T, got %T", &BatchTx{}, batch) + } + // publish the state node + var stateModel models.StateNodeModel + if stateNode.NodeType == sdtypes.Removed { + // short circuit if it is a Removed node + // this assumes the db has been initialized and a public.blocks entry for the Removed node is present + stateModel = models.StateNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + Path: stateNode.Path, + StateKey: common.BytesToHash(stateNode.LeafKey).String(), + CID: shared.RemovedNodeStateCID, + MhKey: shared.RemovedNodeMhKey, + NodeType: stateNode.NodeType.Int(), + } + } else { + stateCIDStr, stateMhKey, err := tx.cacheRaw(ipld2.MEthStateTrie, multihash.KECCAK_256, stateNode.NodeValue) + if err != nil { + return fmt.Errorf("error generating and cacheing state node IPLD: %v", err) + } + stateModel = models.StateNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + Path: stateNode.Path, + StateKey: common.BytesToHash(stateNode.LeafKey).String(), + CID: stateCIDStr, + MhKey: stateMhKey, + NodeType: stateNode.NodeType.Int(), + } + } + + // index the state node, collect the stateID to reference by FK + if _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", stateModel); err != nil { + return err + } + + // if we have a leaf, decode and index the account data + if stateNode.NodeType == sdtypes.Leaf { + var i []interface{} + if err := rlp.DecodeBytes(stateNode.NodeValue, &i); err != nil { + return fmt.Errorf("error decoding state leaf node rlp: %s", err.Error()) + } + if len(i) != 2 { + return fmt.Errorf("eth IPLDPublisher expected state leaf node rlp to decode into two elements") + } + var account types.StateAccount + if err := rlp.DecodeBytes(i[1].([]byte), &account); err != nil { + return fmt.Errorf("error decoding state account rlp: %s", err.Error()) + } + accountModel := models.StateAccountModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + StatePath: stateNode.Path, + Balance: account.Balance.String(), + Nonce: account.Nonce, + CodeHash: account.CodeHash, + StorageRoot: account.Root.String(), + } + if _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", accountModel); err != nil { + return err + } + } + + // if there are any storage nodes associated with this node, publish and index them + for _, storageNode := range stateNode.StorageNodes { + if storageNode.NodeType == sdtypes.Removed { + // short circuit if it is a Removed node + // this assumes the db has been initialized and a public.blocks entry for the Removed node is present + storageModel := models.StorageNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + StatePath: stateNode.Path, + Path: storageNode.Path, + StorageKey: common.BytesToHash(storageNode.LeafKey).String(), + CID: shared.RemovedNodeStorageCID, + MhKey: shared.RemovedNodeMhKey, + NodeType: storageNode.NodeType.Int(), + } + if _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", storageModel); err != nil { + return err + } + continue + } + storageCIDStr, storageMhKey, err := tx.cacheRaw(ipld2.MEthStorageTrie, multihash.KECCAK_256, storageNode.NodeValue) + if err != nil { + return fmt.Errorf("error generating and cacheing storage node IPLD: %v", err) + } + storageModel := models.StorageNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + StatePath: stateNode.Path, + Path: storageNode.Path, + StorageKey: common.BytesToHash(storageNode.LeafKey).String(), + CID: storageCIDStr, + MhKey: storageMhKey, + NodeType: storageNode.NodeType.Int(), + } + if _, err := fmt.Fprintf(sdi.dump, "%+v\r\n", storageModel); err != nil { + return err + } + } + + return nil +} + +// PushCodeAndCodeHash publishes code and codehash pairs to the ipld sql +func (sdi *StateDiffIndexer) PushCodeAndCodeHash(batch interfaces.Batch, codeAndCodeHash sdtypes.CodeAndCodeHash) error { + tx, ok := batch.(*BatchTx) + if !ok { + return fmt.Errorf("dump: batch is expected to be of type %T, got %T", &BatchTx{}, batch) + } + // codec doesn't matter since db key is multihash-based + mhKey, err := shared.MultihashKeyFromKeccak256(codeAndCodeHash.Hash) + if err != nil { + return fmt.Errorf("error deriving multihash key from codehash: %v", err) + } + tx.cacheDirect(mhKey, codeAndCodeHash.Code) + return nil +} + +// Close satisfies io.Closer +func (sdi *StateDiffIndexer) Close() error { + return sdi.dump.Close() +} + +// LoadWatchedAddresses satisfies the interfaces.StateDiffIndexer interface +func (sdi *StateDiffIndexer) LoadWatchedAddresses() ([]common.Address, error) { + return nil, nil +} + +// InsertWatchedAddresses satisfies the interfaces.StateDiffIndexer interface +func (sdi *StateDiffIndexer) InsertWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) error { + return nil +} + +// RemoveWatchedAddresses satisfies the interfaces.StateDiffIndexer interface +func (sdi *StateDiffIndexer) RemoveWatchedAddresses(args []sdtypes.WatchAddressArg) error { + return nil +} + +// SetWatchedAddresses satisfies the interfaces.StateDiffIndexer interface +func (sdi *StateDiffIndexer) SetWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) error { + return nil +} + +// ClearWatchedAddresses satisfies the interfaces.StateDiffIndexer interface +func (sdi *StateDiffIndexer) ClearWatchedAddresses() error { + return nil +} diff --git a/statediff/indexer/database/file/batch_tx.go b/statediff/indexer/database/file/batch_tx.go new file mode 100644 index 000000000..d38bd1211 --- /dev/null +++ b/statediff/indexer/database/file/batch_tx.go @@ -0,0 +1,29 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file + +// BatchTx wraps a void with the state necessary for building the tx concurrently during trie difference iteration +type BatchTx struct { + BlockNumber string + + submit func(blockTx *BatchTx, err error) error +} + +// Submit satisfies indexer.AtomicTx +func (tx *BatchTx) Submit(err error) error { + return tx.submit(tx, err) +} diff --git a/statediff/indexer/database/file/config.go b/statediff/indexer/database/file/config.go new file mode 100644 index 000000000..a3623e0fa --- /dev/null +++ b/statediff/indexer/database/file/config.go @@ -0,0 +1,84 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file + +import ( + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/statediff/indexer/node" + "github.com/ethereum/go-ethereum/statediff/indexer/shared" +) + +// FileMode to explicitly type the mode of file writer we are using +type FileMode string + +const ( + CSV FileMode = "CSV" + SQL FileMode = "SQL" + Unknown FileMode = "Unknown" +) + +// ResolveFileMode resolves a FileMode from a provided string +func ResolveFileMode(str string) (FileMode, error) { + switch strings.ToLower(str) { + case "csv": + return CSV, nil + case "sql": + return SQL, nil + default: + return Unknown, fmt.Errorf("unrecognized file type string: %s", str) + } +} + +// Config holds params for writing out CSV or SQL files +type Config struct { + Mode FileMode + OutputDir string + FilePath string + WatchedAddressesFilePath string + NodeInfo node.Info +} + +// Type satisfies interfaces.Config +func (c Config) Type() shared.DBType { + return shared.FILE +} + +var nodeInfo = node.Info{ + GenesisBlock: "0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3", + NetworkID: "1", + ChainID: 1, + ID: "mockNodeID", + ClientName: "go-ethereum", +} + +// CSVTestConfig config for unit tests +var CSVTestConfig = Config{ + Mode: CSV, + OutputDir: "./statediffing_test", + WatchedAddressesFilePath: "./statediffing_watched_addresses_test_file.csv", + NodeInfo: nodeInfo, +} + +// SQLTestConfig config for unit tests +var SQLTestConfig = Config{ + Mode: SQL, + FilePath: "./statediffing_test_file.sql", + WatchedAddressesFilePath: "./statediffing_watched_addresses_test_file.sql", + NodeInfo: nodeInfo, +} diff --git a/statediff/indexer/database/file/csv_indexer_legacy_test.go b/statediff/indexer/database/file/csv_indexer_legacy_test.go new file mode 100644 index 000000000..55350a912 --- /dev/null +++ b/statediff/indexer/database/file/csv_indexer_legacy_test.go @@ -0,0 +1,118 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file_test + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/file/types" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/test" + "github.com/ethereum/go-ethereum/statediff/indexer/test_helpers" +) + +const dbDirectory = "/file_indexer" +const pgCopyStatement = `COPY %s FROM '%s' CSV` + +func setupLegacyCSVIndexer(t *testing.T) { + if _, err := os.Stat(file.CSVTestConfig.OutputDir); !errors.Is(err, os.ErrNotExist) { + err := os.RemoveAll(file.CSVTestConfig.OutputDir) + require.NoError(t, err) + } + + ind, err = file.NewStateDiffIndexer(context.Background(), test.LegacyConfig, file.CSVTestConfig) + require.NoError(t, err) + + db, err = postgres.SetupSQLXDB() + if err != nil { + t.Fatal(err) + } +} + +func setupLegacyCSV(t *testing.T) { + setupLegacyCSVIndexer(t) + test.SetupLegacyTestData(t, ind) +} + +func dumpCSVFileData(t *testing.T) { + outputDir := filepath.Join(dbDirectory, file.CSVTestConfig.OutputDir) + workingDir, err := os.Getwd() + require.NoError(t, err) + + localOutputDir := filepath.Join(workingDir, file.CSVTestConfig.OutputDir) + + for _, tbl := range file.Tables { + err := test_helpers.DedupFile(file.TableFilePath(localOutputDir, tbl.Name)) + require.NoError(t, err) + + var stmt string + varcharColumns := tbl.VarcharColumns() + if len(varcharColumns) > 0 { + stmt = fmt.Sprintf( + pgCopyStatement+" FORCE NOT NULL %s", + tbl.Name, + file.TableFilePath(outputDir, tbl.Name), + strings.Join(varcharColumns, ", "), + ) + } else { + stmt = fmt.Sprintf(pgCopyStatement, tbl.Name, file.TableFilePath(outputDir, tbl.Name)) + } + + _, err = db.Exec(context.Background(), stmt) + require.NoError(t, err) + } +} + +func resetAndDumpWatchedAddressesCSVFileData(t *testing.T) { + test_helpers.TearDownDB(t, db) + + outputFilePath := filepath.Join(dbDirectory, file.CSVTestConfig.WatchedAddressesFilePath) + stmt := fmt.Sprintf(pgCopyStatement, types.TableWatchedAddresses.Name, outputFilePath) + + _, err = db.Exec(context.Background(), stmt) + require.NoError(t, err) +} + +func tearDownCSV(t *testing.T) { + test_helpers.TearDownDB(t, db) + require.NoError(t, db.Close()) + + require.NoError(t, os.RemoveAll(file.CSVTestConfig.OutputDir)) + + if err := os.Remove(file.CSVTestConfig.WatchedAddressesFilePath); !errors.Is(err, os.ErrNotExist) { + require.NoError(t, err) + } +} + +func TestLegacyCSVFileIndexer(t *testing.T) { + t.Run("Publish and index header IPLDs", func(t *testing.T) { + setupLegacyCSV(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestLegacyIndexer(t, db) + }) +} diff --git a/statediff/indexer/database/file/csv_indexer_test.go b/statediff/indexer/database/file/csv_indexer_test.go new file mode 100644 index 000000000..81f425acb --- /dev/null +++ b/statediff/indexer/database/file/csv_indexer_test.go @@ -0,0 +1,255 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file_test + +import ( + "context" + "errors" + "math/big" + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" + "github.com/ethereum/go-ethereum/statediff/indexer/test" +) + +func setupCSVIndexer(t *testing.T) { + file.CSVTestConfig.OutputDir = "./statediffing_test" + + if _, err := os.Stat(file.CSVTestConfig.OutputDir); !errors.Is(err, os.ErrNotExist) { + err := os.RemoveAll(file.CSVTestConfig.OutputDir) + require.NoError(t, err) + } + + if _, err := os.Stat(file.CSVTestConfig.WatchedAddressesFilePath); !errors.Is(err, os.ErrNotExist) { + err := os.Remove(file.CSVTestConfig.WatchedAddressesFilePath) + require.NoError(t, err) + } + + ind, err = file.NewStateDiffIndexer(context.Background(), mocks.TestConfig, file.CSVTestConfig) + require.NoError(t, err) + + db, err = postgres.SetupSQLXDB() + if err != nil { + t.Fatal(err) + } +} + +func setupCSV(t *testing.T) { + setupCSVIndexer(t) + test.SetupTestData(t, ind) +} + +func setupCSVNonCanonical(t *testing.T) { + setupCSVIndexer(t) + test.SetupTestDataNonCanonical(t, ind) +} + +func TestCSVFileIndexer(t *testing.T) { + t.Run("Publish and index header IPLDs in a single tx", func(t *testing.T) { + setupCSV(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexHeaderIPLDs(t, db) + }) + + t.Run("Publish and index transaction IPLDs in a single tx", func(t *testing.T) { + setupCSV(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexTransactionIPLDs(t, db) + }) + + t.Run("Publish and index log IPLDs for multiple receipt of a specific block", func(t *testing.T) { + setupCSV(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexLogIPLDs(t, db) + }) + + t.Run("Publish and index receipt IPLDs in a single tx", func(t *testing.T) { + setupCSV(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexReceiptIPLDs(t, db) + }) + + t.Run("Publish and index state IPLDs in a single tx", func(t *testing.T) { + setupCSV(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexStateIPLDs(t, db) + }) + + t.Run("Publish and index storage IPLDs in a single tx", func(t *testing.T) { + setupCSV(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexStorageIPLDs(t, db) + }) +} + +func TestCSVFileIndexerNonCanonical(t *testing.T) { + t.Run("Publish and index header", func(t *testing.T) { + setupCSVNonCanonical(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexHeaderNonCanonical(t, db) + }) + + t.Run("Publish and index transactions", func(t *testing.T) { + setupCSVNonCanonical(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexTransactionsNonCanonical(t, db) + }) + + t.Run("Publish and index receipts", func(t *testing.T) { + setupCSVNonCanonical(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexReceiptsNonCanonical(t, db) + }) + + t.Run("Publish and index logs", func(t *testing.T) { + setupCSVNonCanonical(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexLogsNonCanonical(t, db) + }) + + t.Run("Publish and index state nodes", func(t *testing.T) { + setupCSVNonCanonical(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexStateNonCanonical(t, db) + }) + + t.Run("Publish and index storage nodes", func(t *testing.T) { + setupCSVNonCanonical(t) + dumpCSVFileData(t) + defer tearDownCSV(t) + + test.TestPublishAndIndexStorageNonCanonical(t, db) + }) +} + +func TestCSVFileWatchAddressMethods(t *testing.T) { + setupCSVIndexer(t) + defer tearDownCSV(t) + + t.Run("Load watched addresses (empty table)", func(t *testing.T) { + test.TestLoadEmptyWatchedAddresses(t, ind) + }) + + t.Run("Insert watched addresses", func(t *testing.T) { + args := mocks.GetInsertWatchedAddressesArgs() + err = ind.InsertWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt1))) + require.NoError(t, err) + + resetAndDumpWatchedAddressesCSVFileData(t) + + test.TestInsertWatchedAddresses(t, db) + }) + + t.Run("Insert watched addresses (some already watched)", func(t *testing.T) { + args := mocks.GetInsertAlreadyWatchedAddressesArgs() + err = ind.InsertWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt2))) + require.NoError(t, err) + + resetAndDumpWatchedAddressesCSVFileData(t) + + test.TestInsertAlreadyWatchedAddresses(t, db) + }) + + t.Run("Remove watched addresses", func(t *testing.T) { + args := mocks.GetRemoveWatchedAddressesArgs() + err = ind.RemoveWatchedAddresses(args) + require.NoError(t, err) + + resetAndDumpWatchedAddressesCSVFileData(t) + + test.TestRemoveWatchedAddresses(t, db) + }) + + t.Run("Remove watched addresses (some non-watched)", func(t *testing.T) { + args := mocks.GetRemoveNonWatchedAddressesArgs() + err = ind.RemoveWatchedAddresses(args) + require.NoError(t, err) + + resetAndDumpWatchedAddressesCSVFileData(t) + + test.TestRemoveNonWatchedAddresses(t, db) + }) + + t.Run("Set watched addresses", func(t *testing.T) { + args := mocks.GetSetWatchedAddressesArgs() + err = ind.SetWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt2))) + require.NoError(t, err) + + resetAndDumpWatchedAddressesCSVFileData(t) + + test.TestSetWatchedAddresses(t, db) + }) + + t.Run("Set watched addresses (some already watched)", func(t *testing.T) { + args := mocks.GetSetAlreadyWatchedAddressesArgs() + err = ind.SetWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt3))) + require.NoError(t, err) + + resetAndDumpWatchedAddressesCSVFileData(t) + + test.TestSetAlreadyWatchedAddresses(t, db) + }) + + t.Run("Load watched addresses", func(t *testing.T) { + test.TestLoadWatchedAddresses(t, ind) + }) + + t.Run("Clear watched addresses", func(t *testing.T) { + err = ind.ClearWatchedAddresses() + require.NoError(t, err) + + resetAndDumpWatchedAddressesCSVFileData(t) + + test.TestClearWatchedAddresses(t, db) + }) + + t.Run("Clear watched addresses (empty table)", func(t *testing.T) { + err = ind.ClearWatchedAddresses() + require.NoError(t, err) + + resetAndDumpWatchedAddressesCSVFileData(t) + + test.TestClearEmptyWatchedAddresses(t, db) + }) +} diff --git a/statediff/indexer/database/file/csv_writer.go b/statediff/indexer/database/file/csv_writer.go new file mode 100644 index 000000000..f099ca9b0 --- /dev/null +++ b/statediff/indexer/database/file/csv_writer.go @@ -0,0 +1,457 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file + +import ( + "encoding/csv" + "errors" + "fmt" + "math/big" + "os" + "path/filepath" + "strconv" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + + blockstore "github.com/ipfs/go-ipfs-blockstore" + dshelp "github.com/ipfs/go-ipfs-ds-help" + node "github.com/ipfs/go-ipld-format" + "github.com/thoas/go-funk" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/statediff/indexer/database/file/types" + "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + nodeinfo "github.com/ethereum/go-ethereum/statediff/indexer/node" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +var ( + Tables = []*types.Table{ + &types.TableIPLDBlock, + &types.TableNodeInfo, + &types.TableHeader, + &types.TableStateNode, + &types.TableStorageNode, + &types.TableUncle, + &types.TableTransaction, + &types.TableAccessListElement, + &types.TableReceipt, + &types.TableLog, + &types.TableStateAccount, + } +) + +type tableRow struct { + table types.Table + values []interface{} +} + +type CSVWriter struct { + // dir containing output files + dir string + + writers fileWriters + watchedAddressesWriter fileWriter + + rows chan tableRow + flushChan chan struct{} + flushFinished chan struct{} + quitChan chan struct{} + doneChan chan struct{} +} + +type fileWriter struct { + *csv.Writer + file *os.File +} + +// fileWriters wraps the file writers for each output table +type fileWriters map[string]fileWriter + +func newFileWriter(path string) (ret fileWriter, err error) { + file, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + if err != nil { + return + } + + ret = fileWriter{ + Writer: csv.NewWriter(file), + file: file, + } + + return +} + +func makeFileWriters(dir string, tables []*types.Table) (fileWriters, error) { + if err := os.MkdirAll(dir, 0755); err != nil { + return nil, err + } + writers := fileWriters{} + for _, tbl := range tables { + w, err := newFileWriter(TableFilePath(dir, tbl.Name)) + if err != nil { + return nil, err + } + writers[tbl.Name] = w + } + return writers, nil +} + +func (tx fileWriters) write(tbl *types.Table, args ...interface{}) error { + row := tbl.ToCsvRow(args...) + return tx[tbl.Name].Write(row) +} + +func (tx fileWriters) close() error { + for _, w := range tx { + err := w.file.Close() + if err != nil { + return err + } + } + return nil +} + +func (tx fileWriters) flush() error { + for _, w := range tx { + w.Flush() + if err := w.Error(); err != nil { + return err + } + } + return nil +} + +func NewCSVWriter(path string, watchedAddressesFilePath string) (*CSVWriter, error) { + if err := os.MkdirAll(path, 0777); err != nil { + return nil, fmt.Errorf("unable to make MkdirAll for path: %s err: %s", path, err) + } + + writers, err := makeFileWriters(path, Tables) + if err != nil { + return nil, err + } + + watchedAddressesWriter, err := newFileWriter(watchedAddressesFilePath) + if err != nil { + return nil, err + } + + csvWriter := &CSVWriter{ + writers: writers, + watchedAddressesWriter: watchedAddressesWriter, + dir: path, + rows: make(chan tableRow), + flushChan: make(chan struct{}), + flushFinished: make(chan struct{}), + quitChan: make(chan struct{}), + doneChan: make(chan struct{}), + } + return csvWriter, nil +} + +func (csw *CSVWriter) Loop() { + go func() { + defer close(csw.doneChan) + for { + select { + case row := <-csw.rows: + err := csw.writers.write(&row.table, row.values...) + if err != nil { + panic(fmt.Sprintf("error writing csv buffer: %v", err)) + } + case <-csw.quitChan: + if err := csw.writers.flush(); err != nil { + panic(fmt.Sprintf("error writing csv buffer to file: %v", err)) + } + return + case <-csw.flushChan: + if err := csw.writers.flush(); err != nil { + panic(fmt.Sprintf("error writing csv buffer to file: %v", err)) + } + csw.flushFinished <- struct{}{} + } + } + }() +} + +// Flush sends a flush signal to the looping process +func (csw *CSVWriter) Flush() { + csw.flushChan <- struct{}{} + <-csw.flushFinished +} + +func TableFilePath(dir, name string) string { return filepath.Join(dir, name+".csv") } + +// Close satisfies io.Closer +func (csw *CSVWriter) Close() error { + close(csw.quitChan) + <-csw.doneChan + close(csw.rows) + close(csw.flushChan) + close(csw.flushFinished) + return csw.writers.close() +} + +func (csw *CSVWriter) upsertNode(node nodeinfo.Info) { + var values []interface{} + values = append(values, node.GenesisBlock, node.NetworkID, node.ID, node.ClientName, node.ChainID) + csw.rows <- tableRow{types.TableNodeInfo, values} +} + +func (csw *CSVWriter) upsertIPLD(ipld models.IPLDModel) { + var values []interface{} + values = append(values, ipld.BlockNumber, ipld.Key, ipld.Data) + csw.rows <- tableRow{types.TableIPLDBlock, values} +} + +func (csw *CSVWriter) upsertIPLDDirect(blockNumber, key string, value []byte) { + csw.upsertIPLD(models.IPLDModel{ + BlockNumber: blockNumber, + Key: key, + Data: value, + }) +} + +func (csw *CSVWriter) upsertIPLDNode(blockNumber string, i node.Node) { + csw.upsertIPLD(models.IPLDModel{ + BlockNumber: blockNumber, + Key: blockstore.BlockPrefix.String() + dshelp.MultihashToDsKey(i.Cid().Hash()).String(), + Data: i.RawData(), + }) +} + +func (csw *CSVWriter) upsertIPLDRaw(blockNumber string, codec, mh uint64, raw []byte) (string, string, error) { + c, err := ipld.RawdataToCid(codec, raw, mh) + if err != nil { + return "", "", err + } + prefixedKey := blockstore.BlockPrefix.String() + dshelp.MultihashToDsKey(c.Hash()).String() + csw.upsertIPLD(models.IPLDModel{ + BlockNumber: blockNumber, + Key: prefixedKey, + Data: raw, + }) + return c.String(), prefixedKey, err +} + +func (csw *CSVWriter) upsertHeaderCID(header models.HeaderModel) { + var values []interface{} + values = append(values, header.BlockNumber, header.BlockHash, header.ParentHash, header.CID, + header.TotalDifficulty, header.NodeID, header.Reward, header.StateRoot, header.TxRoot, + header.RctRoot, header.UncleRoot, header.Bloom, strconv.FormatUint(header.Timestamp, 10), header.MhKey, 1, header.Coinbase) + csw.rows <- tableRow{types.TableHeader, values} + metrics.IndexerMetrics.BlocksCounter.Inc(1) +} + +func (csw *CSVWriter) upsertUncleCID(uncle models.UncleModel) { + var values []interface{} + values = append(values, uncle.BlockNumber, uncle.BlockHash, uncle.HeaderID, uncle.ParentHash, uncle.CID, + uncle.Reward, uncle.MhKey) + csw.rows <- tableRow{types.TableUncle, values} +} + +func (csw *CSVWriter) upsertTransactionCID(transaction models.TxModel) { + var values []interface{} + values = append(values, transaction.BlockNumber, transaction.HeaderID, transaction.TxHash, transaction.CID, transaction.Dst, + transaction.Src, transaction.Index, transaction.MhKey, transaction.Data, transaction.Type, transaction.Value) + csw.rows <- tableRow{types.TableTransaction, values} + metrics.IndexerMetrics.TransactionsCounter.Inc(1) +} + +func (csw *CSVWriter) upsertAccessListElement(accessListElement models.AccessListElementModel) { + var values []interface{} + values = append(values, accessListElement.BlockNumber, accessListElement.TxID, accessListElement.Index, accessListElement.Address, accessListElement.StorageKeys) + csw.rows <- tableRow{types.TableAccessListElement, values} + metrics.IndexerMetrics.AccessListEntriesCounter.Inc(1) +} + +func (csw *CSVWriter) upsertReceiptCID(rct *models.ReceiptModel) { + var values []interface{} + values = append(values, rct.BlockNumber, rct.HeaderID, rct.TxID, rct.LeafCID, rct.Contract, rct.ContractHash, rct.LeafMhKey, + rct.PostState, rct.PostStatus, rct.LogRoot) + csw.rows <- tableRow{types.TableReceipt, values} + metrics.IndexerMetrics.ReceiptsCounter.Inc(1) +} + +func (csw *CSVWriter) upsertLogCID(logs []*models.LogsModel) { + for _, l := range logs { + var values []interface{} + values = append(values, l.BlockNumber, l.HeaderID, l.LeafCID, l.LeafMhKey, l.ReceiptID, l.Address, l.Index, l.Topic0, + l.Topic1, l.Topic2, l.Topic3, l.Data) + csw.rows <- tableRow{types.TableLog, values} + metrics.IndexerMetrics.LogsCounter.Inc(1) + } +} + +func (csw *CSVWriter) upsertStateCID(stateNode models.StateNodeModel) { + var stateKey string + if stateNode.StateKey != nullHash.String() { + stateKey = stateNode.StateKey + } + + var values []interface{} + values = append(values, stateNode.BlockNumber, stateNode.HeaderID, stateKey, stateNode.CID, stateNode.Path, + stateNode.NodeType, true, stateNode.MhKey) + csw.rows <- tableRow{types.TableStateNode, values} +} + +func (csw *CSVWriter) upsertStateAccount(stateAccount models.StateAccountModel) { + var values []interface{} + values = append(values, stateAccount.BlockNumber, stateAccount.HeaderID, stateAccount.StatePath, stateAccount.Balance, + strconv.FormatUint(stateAccount.Nonce, 10), stateAccount.CodeHash, stateAccount.StorageRoot) + csw.rows <- tableRow{types.TableStateAccount, values} +} + +func (csw *CSVWriter) upsertStorageCID(storageCID models.StorageNodeModel) { + var storageKey string + if storageCID.StorageKey != nullHash.String() { + storageKey = storageCID.StorageKey + } + + var values []interface{} + values = append(values, storageCID.BlockNumber, storageCID.HeaderID, storageCID.StatePath, storageKey, storageCID.CID, + storageCID.Path, storageCID.NodeType, true, storageCID.MhKey) + csw.rows <- tableRow{types.TableStorageNode, values} +} + +// LoadWatchedAddresses loads watched addresses from a file +func (csw *CSVWriter) loadWatchedAddresses() ([]common.Address, error) { + watchedAddressesFilePath := csw.watchedAddressesWriter.file.Name() + // load csv rows from watched addresses file + rows, err := loadWatchedAddressesRows(watchedAddressesFilePath) + if err != nil { + return nil, err + } + + // extract addresses from the csv rows + watchedAddresses := funk.Map(rows, func(row []string) common.Address { + // first column is for address in eth_meta.watched_addresses + addressString := row[0] + + return common.HexToAddress(addressString) + }).([]common.Address) + + return watchedAddresses, nil +} + +// InsertWatchedAddresses inserts the given addresses in a file +func (csw *CSVWriter) insertWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) error { + // load csv rows from watched addresses file + watchedAddresses, err := csw.loadWatchedAddresses() + if err != nil { + return err + } + + // append rows for new addresses to existing csv file + for _, arg := range args { + // ignore if already watched + if funk.Contains(watchedAddresses, common.HexToAddress(arg.Address)) { + continue + } + + var values []interface{} + values = append(values, arg.Address, strconv.FormatUint(arg.CreatedAt, 10), currentBlockNumber.String(), "0") + row := types.TableWatchedAddresses.ToCsvRow(values...) + + // writing directly instead of using rows channel as it needs to be flushed immediately + err = csw.watchedAddressesWriter.Write(row) + if err != nil { + return err + } + } + + // watched addresses need to be flushed immediately to the file to keep them in sync with in-memory watched addresses + csw.watchedAddressesWriter.Flush() + err = csw.watchedAddressesWriter.Error() + if err != nil { + return err + } + + return nil +} + +// RemoveWatchedAddresses removes the given watched addresses from a file +func (csw *CSVWriter) removeWatchedAddresses(args []sdtypes.WatchAddressArg) error { + // load csv rows from watched addresses file + watchedAddressesFilePath := csw.watchedAddressesWriter.file.Name() + rows, err := loadWatchedAddressesRows(watchedAddressesFilePath) + if err != nil { + return err + } + + // get rid of rows having addresses to be removed + filteredRows := funk.Filter(rows, func(row []string) bool { + return !funk.Contains(args, func(arg sdtypes.WatchAddressArg) bool { + // Compare first column in table for address + return arg.Address == row[0] + }) + }).([][]string) + + return dumpWatchedAddressesRows(csw.watchedAddressesWriter, filteredRows) +} + +// SetWatchedAddresses clears and inserts the given addresses in a file +func (csw *CSVWriter) setWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) error { + var rows [][]string + for _, arg := range args { + row := types.TableWatchedAddresses.ToCsvRow(arg.Address, strconv.FormatUint(arg.CreatedAt, 10), currentBlockNumber.String(), "0") + rows = append(rows, row) + } + + return dumpWatchedAddressesRows(csw.watchedAddressesWriter, rows) +} + +// loadCSVWatchedAddresses loads csv rows from the given file +func loadWatchedAddressesRows(filePath string) ([][]string, error) { + file, err := os.Open(filePath) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return [][]string{}, nil + } + + return nil, fmt.Errorf("error opening watched addresses file: %v", err) + } + + defer file.Close() + reader := csv.NewReader(file) + + return reader.ReadAll() +} + +// dumpWatchedAddressesRows dumps csv rows to the given file +func dumpWatchedAddressesRows(watchedAddressesWriter fileWriter, filteredRows [][]string) error { + file := watchedAddressesWriter.file + file.Close() + + file, err := os.Create(file.Name()) + if err != nil { + return fmt.Errorf("error creating watched addresses file: %v", err) + } + + watchedAddressesWriter.Writer = csv.NewWriter(file) + watchedAddressesWriter.file = file + + for _, row := range filteredRows { + watchedAddressesWriter.Write(row) + } + + watchedAddressesWriter.Flush() + + return nil +} diff --git a/statediff/indexer/database/file/helpers.go b/statediff/indexer/database/file/helpers.go new file mode 100644 index 000000000..dc635110c --- /dev/null +++ b/statediff/indexer/database/file/helpers.go @@ -0,0 +1,60 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file + +import "bytes" + +// formatPostgresStringArray parses an array of strings into the proper Postgres string representation of that array +func formatPostgresStringArray(a []string) string { + if a == nil { + return "" + } + + if n := len(a); n > 0 { + // There will be at least two curly brackets, 2*N bytes of quotes, + // and N-1 bytes of delimiters. + b := make([]byte, 1, 1+3*n) + b[0] = '{' + + b = appendArrayQuotedBytes(b, []byte(a[0])) + for i := 1; i < n; i++ { + b = append(b, ',') + b = appendArrayQuotedBytes(b, []byte(a[i])) + } + + return string(append(b, '}')) + } + + return "{}" +} + +func appendArrayQuotedBytes(b, v []byte) []byte { + b = append(b, '"') + for { + i := bytes.IndexAny(v, `"\`) + if i < 0 { + b = append(b, v...) + break + } + if i > 0 { + b = append(b, v[:i]...) + } + b = append(b, '\\', v[i]) + v = v[i+1:] + } + return append(b, '"') +} diff --git a/statediff/indexer/database/file/indexer.go b/statediff/indexer/database/file/indexer.go new file mode 100644 index 000000000..86c64862c --- /dev/null +++ b/statediff/indexer/database/file/indexer.go @@ -0,0 +1,573 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file + +import ( + "context" + "errors" + "fmt" + "math/big" + "os" + "sync" + "sync/atomic" + "time" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + ipld2 "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + "github.com/ethereum/go-ethereum/statediff/indexer/shared" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +const defaultCSVOutputDir = "./statediff_output" +const defaultSQLFilePath = "./statediff.sql" +const defaultWatchedAddressesCSVFilePath = "./statediff-watched-addresses.csv" +const defaultWatchedAddressesSQLFilePath = "./statediff-watched-addresses.sql" + +const watchedAddressesInsert = "INSERT INTO eth_meta.watched_addresses (address, created_at, watched_at) VALUES ('%s', '%d', '%d') ON CONFLICT (address) DO NOTHING;" + +var _ interfaces.StateDiffIndexer = &StateDiffIndexer{} + +// StateDiffIndexer satisfies the indexer.StateDiffIndexer interface for ethereum statediff objects on top of a void +type StateDiffIndexer struct { + fileWriter FileWriter + chainConfig *params.ChainConfig + nodeID string + wg *sync.WaitGroup + removedCacheFlag *uint32 +} + +// NewStateDiffIndexer creates a void implementation of interfaces.StateDiffIndexer +func NewStateDiffIndexer(ctx context.Context, chainConfig *params.ChainConfig, config Config) (*StateDiffIndexer, error) { + var err error + var writer FileWriter + + watchedAddressesFilePath := config.WatchedAddressesFilePath + + switch config.Mode { + case CSV: + outputDir := config.OutputDir + if outputDir == "" { + outputDir = defaultCSVOutputDir + } + + if _, err := os.Stat(outputDir); !errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("cannot create output directory, directory (%s) already exists", outputDir) + } + log.Info("Writing statediff CSV files to directory", "file", outputDir) + + if watchedAddressesFilePath == "" { + watchedAddressesFilePath = defaultWatchedAddressesCSVFilePath + } + log.Info("Writing watched addresses to file", "file", watchedAddressesFilePath) + + writer, err = NewCSVWriter(outputDir, watchedAddressesFilePath) + if err != nil { + return nil, err + } + case SQL: + filePath := config.FilePath + if filePath == "" { + filePath = defaultSQLFilePath + } + if _, err := os.Stat(filePath); !errors.Is(err, os.ErrNotExist) { + return nil, fmt.Errorf("cannot create file, file (%s) already exists", filePath) + } + file, err := os.Create(filePath) + if err != nil { + return nil, fmt.Errorf("unable to create file (%s), err: %v", filePath, err) + } + log.Info("Writing statediff SQL statements to file", "file", filePath) + + if watchedAddressesFilePath == "" { + watchedAddressesFilePath = defaultWatchedAddressesSQLFilePath + } + log.Info("Writing watched addresses to file", "file", watchedAddressesFilePath) + + writer = NewSQLWriter(file, watchedAddressesFilePath) + default: + return nil, fmt.Errorf("unrecognized file mode: %s", config.Mode) + } + + wg := new(sync.WaitGroup) + writer.Loop() + writer.upsertNode(config.NodeInfo) + + return &StateDiffIndexer{ + fileWriter: writer, + chainConfig: chainConfig, + nodeID: config.NodeInfo.ID, + wg: wg, + }, nil +} + +// ReportDBMetrics has nothing to report for dump +func (sdi *StateDiffIndexer) ReportDBMetrics(time.Duration, <-chan bool) {} + +// PushBlock pushes and indexes block data in sql, except state & storage nodes (includes header, uncles, transactions & receipts) +// Returns an initiated DB transaction which must be Closed via defer to commit or rollback +func (sdi *StateDiffIndexer) PushBlock(block *types.Block, receipts types.Receipts, totalDifficulty *big.Int) (interfaces.Batch, error) { + sdi.removedCacheFlag = new(uint32) + start, t := time.Now(), time.Now() + blockHash := block.Hash() + blockHashStr := blockHash.String() + height := block.NumberU64() + traceMsg := fmt.Sprintf("indexer stats for statediff at %d with hash %s:\r\n", height, blockHashStr) + transactions := block.Transactions() + // Derive any missing fields + if err := receipts.DeriveFields(sdi.chainConfig, blockHash, height, transactions); err != nil { + return nil, err + } + + // Generate the block iplds + headerNode, uncleNodes, txNodes, txTrieNodes, rctNodes, rctTrieNodes, logTrieNodes, logLeafNodeCIDs, rctLeafNodeCIDs, err := ipld2.FromBlockAndReceipts(block, receipts) + if err != nil { + return nil, fmt.Errorf("error creating IPLD nodes from block and receipts: %v", err) + } + + if len(txNodes) != len(rctNodes) || len(rctNodes) != len(rctLeafNodeCIDs) { + return nil, fmt.Errorf("expected number of transactions (%d), receipts (%d), and receipt trie leaf nodes (%d) to be equal", len(txNodes), len(rctNodes), len(rctLeafNodeCIDs)) + } + if len(txTrieNodes) != len(rctTrieNodes) { + return nil, fmt.Errorf("expected number of tx trie (%d) and rct trie (%d) nodes to be equal", len(txTrieNodes), len(rctTrieNodes)) + } + + // Calculate reward + var reward *big.Int + // in PoA networks block reward is 0 + if sdi.chainConfig.Clique != nil { + reward = big.NewInt(0) + } else { + reward = shared.CalcEthBlockReward(block.Header(), block.Uncles(), block.Transactions(), receipts) + } + t = time.Now() + + blockTx := &BatchTx{ + BlockNumber: block.Number().String(), + submit: func(self *BatchTx, err error) error { + tDiff := time.Since(t) + metrics.IndexerMetrics.StateStoreCodeProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("state, storage, and code storage processing time: %s\r\n", tDiff.String()) + t = time.Now() + sdi.fileWriter.Flush() + tDiff = time.Since(t) + metrics.IndexerMetrics.PostgresCommitTimer.Update(tDiff) + traceMsg += fmt.Sprintf("postgres transaction commit duration: %s\r\n", tDiff.String()) + traceMsg += fmt.Sprintf(" TOTAL PROCESSING DURATION: %s\r\n", time.Since(start).String()) + log.Debug(traceMsg) + return err + }, + } + tDiff := time.Since(t) + metrics.IndexerMetrics.FreePostgresTimer.Update(tDiff) + traceMsg += fmt.Sprintf("time spent waiting for free postgres tx: %s:\r\n", tDiff.String()) + t = time.Now() + + // write header, collect headerID + headerID := sdi.processHeader(block.Header(), headerNode, reward, totalDifficulty) + tDiff = time.Since(t) + metrics.IndexerMetrics.HeaderProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("header processing time: %s\r\n", tDiff.String()) + t = time.Now() + + // write uncles + sdi.processUncles(headerID, block.Number(), uncleNodes) + tDiff = time.Since(t) + metrics.IndexerMetrics.UncleProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("uncle processing time: %s\r\n", tDiff.String()) + t = time.Now() + + // write receipts and txs + err = sdi.processReceiptsAndTxs(processArgs{ + headerID: headerID, + blockNumber: block.Number(), + receipts: receipts, + txs: transactions, + rctNodes: rctNodes, + rctTrieNodes: rctTrieNodes, + txNodes: txNodes, + txTrieNodes: txTrieNodes, + logTrieNodes: logTrieNodes, + logLeafNodeCIDs: logLeafNodeCIDs, + rctLeafNodeCIDs: rctLeafNodeCIDs, + }) + if err != nil { + return nil, err + } + tDiff = time.Since(t) + metrics.IndexerMetrics.TxAndRecProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("tx and receipt processing time: %s\r\n", tDiff.String()) + t = time.Now() + + return blockTx, err +} + +// processHeader write a header IPLD insert SQL stmt to a file +// it returns the headerID +func (sdi *StateDiffIndexer) processHeader(header *types.Header, headerNode node.Node, reward, td *big.Int) string { + sdi.fileWriter.upsertIPLDNode(header.Number.String(), headerNode) + + var baseFee *string + if header.BaseFee != nil { + baseFee = new(string) + *baseFee = header.BaseFee.String() + } + headerID := header.Hash().String() + sdi.fileWriter.upsertHeaderCID(models.HeaderModel{ + NodeID: sdi.nodeID, + CID: headerNode.Cid().String(), + MhKey: shared.MultihashKeyFromCID(headerNode.Cid()), + ParentHash: header.ParentHash.String(), + BlockNumber: header.Number.String(), + BlockHash: headerID, + TotalDifficulty: td.String(), + Reward: reward.String(), + Bloom: header.Bloom.Bytes(), + StateRoot: header.Root.String(), + RctRoot: header.ReceiptHash.String(), + TxRoot: header.TxHash.String(), + UncleRoot: header.UncleHash.String(), + Timestamp: header.Time, + Coinbase: header.Coinbase.String(), + }) + return headerID +} + +// processUncles writes uncle IPLD insert SQL stmts to a file +func (sdi *StateDiffIndexer) processUncles(headerID string, blockNumber *big.Int, uncleNodes []*ipld2.EthHeader) { + // publish and index uncles + for _, uncleNode := range uncleNodes { + sdi.fileWriter.upsertIPLDNode(blockNumber.String(), uncleNode) + var uncleReward *big.Int + // in PoA networks uncle reward is 0 + if sdi.chainConfig.Clique != nil { + uncleReward = big.NewInt(0) + } else { + uncleReward = shared.CalcUncleMinerReward(blockNumber.Uint64(), uncleNode.Number.Uint64()) + } + sdi.fileWriter.upsertUncleCID(models.UncleModel{ + BlockNumber: blockNumber.String(), + HeaderID: headerID, + CID: uncleNode.Cid().String(), + MhKey: shared.MultihashKeyFromCID(uncleNode.Cid()), + ParentHash: uncleNode.ParentHash.String(), + BlockHash: uncleNode.Hash().String(), + Reward: uncleReward.String(), + }) + } +} + +// processArgs bundles arguments to processReceiptsAndTxs +type processArgs struct { + headerID string + blockNumber *big.Int + receipts types.Receipts + txs types.Transactions + rctNodes []*ipld2.EthReceipt + rctTrieNodes []*ipld2.EthRctTrie + txNodes []*ipld2.EthTx + txTrieNodes []*ipld2.EthTxTrie + logTrieNodes [][]node.Node + logLeafNodeCIDs [][]cid.Cid + rctLeafNodeCIDs []cid.Cid +} + +// processReceiptsAndTxs writes receipt and tx IPLD insert SQL stmts to a file +func (sdi *StateDiffIndexer) processReceiptsAndTxs(args processArgs) error { + // Process receipts and txs + signer := types.MakeSigner(sdi.chainConfig, args.blockNumber) + for i, receipt := range args.receipts { + for _, logTrieNode := range args.logTrieNodes[i] { + sdi.fileWriter.upsertIPLDNode(args.blockNumber.String(), logTrieNode) + } + txNode := args.txNodes[i] + sdi.fileWriter.upsertIPLDNode(args.blockNumber.String(), txNode) + + // index tx + trx := args.txs[i] + txID := trx.Hash().String() + + var val string + if trx.Value() != nil { + val = trx.Value().String() + } + + // derive sender for the tx that corresponds with this receipt + from, err := types.Sender(signer, trx) + if err != nil { + return fmt.Errorf("error deriving tx sender: %v", err) + } + txModel := models.TxModel{ + BlockNumber: args.blockNumber.String(), + HeaderID: args.headerID, + Dst: shared.HandleZeroAddrPointer(trx.To()), + Src: shared.HandleZeroAddr(from), + TxHash: txID, + Index: int64(i), + Data: trx.Data(), + CID: txNode.Cid().String(), + MhKey: shared.MultihashKeyFromCID(txNode.Cid()), + Type: trx.Type(), + Value: val, + } + sdi.fileWriter.upsertTransactionCID(txModel) + + // index access list if this is one + for j, accessListElement := range trx.AccessList() { + storageKeys := make([]string, len(accessListElement.StorageKeys)) + for k, storageKey := range accessListElement.StorageKeys { + storageKeys[k] = storageKey.Hex() + } + accessListElementModel := models.AccessListElementModel{ + BlockNumber: args.blockNumber.String(), + TxID: txID, + Index: int64(j), + Address: accessListElement.Address.Hex(), + StorageKeys: storageKeys, + } + sdi.fileWriter.upsertAccessListElement(accessListElementModel) + } + + // this is the contract address if this receipt is for a contract creation tx + contract := shared.HandleZeroAddr(receipt.ContractAddress) + var contractHash string + if contract != "" { + contractHash = crypto.Keccak256Hash(common.HexToAddress(contract).Bytes()).String() + } + + // index receipt + if !args.rctLeafNodeCIDs[i].Defined() { + return fmt.Errorf("invalid receipt leaf node cid") + } + + rctModel := &models.ReceiptModel{ + BlockNumber: args.blockNumber.String(), + HeaderID: args.headerID, + TxID: txID, + Contract: contract, + ContractHash: contractHash, + LeafCID: args.rctLeafNodeCIDs[i].String(), + LeafMhKey: shared.MultihashKeyFromCID(args.rctLeafNodeCIDs[i]), + LogRoot: args.rctNodes[i].LogRoot.String(), + } + if len(receipt.PostState) == 0 { + rctModel.PostStatus = receipt.Status + } else { + rctModel.PostState = common.Bytes2Hex(receipt.PostState) + } + sdi.fileWriter.upsertReceiptCID(rctModel) + + // index logs + logDataSet := make([]*models.LogsModel, len(receipt.Logs)) + for idx, l := range receipt.Logs { + topicSet := make([]string, 4) + for ti, topic := range l.Topics { + topicSet[ti] = topic.Hex() + } + + if !args.logLeafNodeCIDs[i][idx].Defined() { + return fmt.Errorf("invalid log cid") + } + + logDataSet[idx] = &models.LogsModel{ + BlockNumber: args.blockNumber.String(), + HeaderID: args.headerID, + ReceiptID: txID, + Address: l.Address.String(), + Index: int64(l.Index), + Data: l.Data, + LeafCID: args.logLeafNodeCIDs[i][idx].String(), + LeafMhKey: shared.MultihashKeyFromCID(args.logLeafNodeCIDs[i][idx]), + Topic0: topicSet[0], + Topic1: topicSet[1], + Topic2: topicSet[2], + Topic3: topicSet[3], + } + } + sdi.fileWriter.upsertLogCID(logDataSet) + } + + // publish trie nodes, these aren't indexed directly + for i, n := range args.txTrieNodes { + sdi.fileWriter.upsertIPLDNode(args.blockNumber.String(), n) + sdi.fileWriter.upsertIPLDNode(args.blockNumber.String(), args.rctTrieNodes[i]) + } + + return nil +} + +// PushStateNode writes a state diff node object (including any child storage nodes) IPLD insert SQL stmt to a file +func (sdi *StateDiffIndexer) PushStateNode(batch interfaces.Batch, stateNode sdtypes.StateNode, headerID string) error { + tx, ok := batch.(*BatchTx) + if !ok { + return fmt.Errorf("file: batch is expected to be of type %T, got %T", &BatchTx{}, batch) + } + // publish the state node + var stateModel models.StateNodeModel + if stateNode.NodeType == sdtypes.Removed { + if atomic.LoadUint32(sdi.removedCacheFlag) == 0 { + atomic.StoreUint32(sdi.removedCacheFlag, 1) + sdi.fileWriter.upsertIPLDDirect(tx.BlockNumber, shared.RemovedNodeMhKey, []byte{}) + } + stateModel = models.StateNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + Path: stateNode.Path, + StateKey: common.BytesToHash(stateNode.LeafKey).String(), + CID: shared.RemovedNodeStateCID, + MhKey: shared.RemovedNodeMhKey, + NodeType: stateNode.NodeType.Int(), + } + } else { + stateCIDStr, stateMhKey, err := sdi.fileWriter.upsertIPLDRaw(tx.BlockNumber, ipld2.MEthStateTrie, multihash.KECCAK_256, stateNode.NodeValue) + if err != nil { + return fmt.Errorf("error generating and cacheing state node IPLD: %v", err) + } + stateModel = models.StateNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + Path: stateNode.Path, + StateKey: common.BytesToHash(stateNode.LeafKey).String(), + CID: stateCIDStr, + MhKey: stateMhKey, + NodeType: stateNode.NodeType.Int(), + } + } + + // index the state node + sdi.fileWriter.upsertStateCID(stateModel) + + // if we have a leaf, decode and index the account data + if stateNode.NodeType == sdtypes.Leaf { + var i []interface{} + if err := rlp.DecodeBytes(stateNode.NodeValue, &i); err != nil { + return fmt.Errorf("error decoding state leaf node rlp: %s", err.Error()) + } + if len(i) != 2 { + return fmt.Errorf("eth IPLDPublisher expected state leaf node rlp to decode into two elements") + } + var account types.StateAccount + if err := rlp.DecodeBytes(i[1].([]byte), &account); err != nil { + return fmt.Errorf("error decoding state account rlp: %s", err.Error()) + } + accountModel := models.StateAccountModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + StatePath: stateNode.Path, + Balance: account.Balance.String(), + Nonce: account.Nonce, + CodeHash: account.CodeHash, + StorageRoot: account.Root.String(), + } + sdi.fileWriter.upsertStateAccount(accountModel) + } + + // if there are any storage nodes associated with this node, publish and index them + for _, storageNode := range stateNode.StorageNodes { + if storageNode.NodeType == sdtypes.Removed { + if atomic.LoadUint32(sdi.removedCacheFlag) == 0 { + atomic.StoreUint32(sdi.removedCacheFlag, 1) + sdi.fileWriter.upsertIPLDDirect(tx.BlockNumber, shared.RemovedNodeMhKey, []byte{}) + } + storageModel := models.StorageNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + StatePath: stateNode.Path, + Path: storageNode.Path, + StorageKey: common.BytesToHash(storageNode.LeafKey).String(), + CID: shared.RemovedNodeStorageCID, + MhKey: shared.RemovedNodeMhKey, + NodeType: storageNode.NodeType.Int(), + } + sdi.fileWriter.upsertStorageCID(storageModel) + continue + } + storageCIDStr, storageMhKey, err := sdi.fileWriter.upsertIPLDRaw(tx.BlockNumber, ipld2.MEthStorageTrie, multihash.KECCAK_256, storageNode.NodeValue) + if err != nil { + return fmt.Errorf("error generating and cacheing storage node IPLD: %v", err) + } + storageModel := models.StorageNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + StatePath: stateNode.Path, + Path: storageNode.Path, + StorageKey: common.BytesToHash(storageNode.LeafKey).String(), + CID: storageCIDStr, + MhKey: storageMhKey, + NodeType: storageNode.NodeType.Int(), + } + sdi.fileWriter.upsertStorageCID(storageModel) + } + + return nil +} + +// PushCodeAndCodeHash writes code and codehash pairs insert SQL stmts to a file +func (sdi *StateDiffIndexer) PushCodeAndCodeHash(batch interfaces.Batch, codeAndCodeHash sdtypes.CodeAndCodeHash) error { + tx, ok := batch.(*BatchTx) + if !ok { + return fmt.Errorf("file: batch is expected to be of type %T, got %T", &BatchTx{}, batch) + } + // codec doesn't matter since db key is multihash-based + mhKey, err := shared.MultihashKeyFromKeccak256(codeAndCodeHash.Hash) + if err != nil { + return fmt.Errorf("error deriving multihash key from codehash: %v", err) + } + sdi.fileWriter.upsertIPLDDirect(tx.BlockNumber, mhKey, codeAndCodeHash.Code) + return nil +} + +// Close satisfies io.Closer +func (sdi *StateDiffIndexer) Close() error { + return sdi.fileWriter.Close() +} + +// LoadWatchedAddresses loads watched addresses from a file +func (sdi *StateDiffIndexer) LoadWatchedAddresses() ([]common.Address, error) { + return sdi.fileWriter.loadWatchedAddresses() +} + +// InsertWatchedAddresses inserts the given addresses in a file +func (sdi *StateDiffIndexer) InsertWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) error { + return sdi.fileWriter.insertWatchedAddresses(args, currentBlockNumber) +} + +// RemoveWatchedAddresses removes the given watched addresses from a file +func (sdi *StateDiffIndexer) RemoveWatchedAddresses(args []sdtypes.WatchAddressArg) error { + return sdi.fileWriter.removeWatchedAddresses(args) +} + +// SetWatchedAddresses clears and inserts the given addresses in a file +func (sdi *StateDiffIndexer) SetWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) error { + return sdi.fileWriter.setWatchedAddresses(args, currentBlockNumber) +} + +// ClearWatchedAddresses clears all the watched addresses from a file +func (sdi *StateDiffIndexer) ClearWatchedAddresses() error { + return sdi.SetWatchedAddresses([]sdtypes.WatchAddressArg{}, big.NewInt(0)) +} diff --git a/statediff/indexer/database/file/interfaces.go b/statediff/indexer/database/file/interfaces.go new file mode 100644 index 000000000..271257dce --- /dev/null +++ b/statediff/indexer/database/file/interfaces.go @@ -0,0 +1,60 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file + +import ( + "math/big" + + node "github.com/ipfs/go-ipld-format" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + nodeinfo "github.com/ethereum/go-ethereum/statediff/indexer/node" + "github.com/ethereum/go-ethereum/statediff/types" +) + +// Writer interface required by the file indexer +type FileWriter interface { + // Methods used to control the writer + Loop() + Close() error + Flush() + + // Methods to upsert ethereum data model objects + upsertNode(node nodeinfo.Info) + upsertHeaderCID(header models.HeaderModel) + upsertUncleCID(uncle models.UncleModel) + upsertTransactionCID(transaction models.TxModel) + upsertAccessListElement(accessListElement models.AccessListElementModel) + upsertReceiptCID(rct *models.ReceiptModel) + upsertLogCID(logs []*models.LogsModel) + upsertStateCID(stateNode models.StateNodeModel) + upsertStateAccount(stateAccount models.StateAccountModel) + upsertStorageCID(storageCID models.StorageNodeModel) + upsertIPLD(ipld models.IPLDModel) + + // Methods to upsert IPLD in different ways + upsertIPLDDirect(blockNumber, key string, value []byte) + upsertIPLDNode(blockNumber string, i node.Node) + upsertIPLDRaw(blockNumber string, codec, mh uint64, raw []byte) (string, string, error) + + // Methods to read and write watched addresses + loadWatchedAddresses() ([]common.Address, error) + insertWatchedAddresses(args []types.WatchAddressArg, currentBlockNumber *big.Int) error + removeWatchedAddresses(args []types.WatchAddressArg) error + setWatchedAddresses(args []types.WatchAddressArg, currentBlockNumber *big.Int) error +} diff --git a/statediff/indexer/database/file/mainnet_tests/indexer_test.go b/statediff/indexer/database/file/mainnet_tests/indexer_test.go new file mode 100644 index 000000000..392fb2ee3 --- /dev/null +++ b/statediff/indexer/database/file/mainnet_tests/indexer_test.go @@ -0,0 +1,112 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package mainnet_tests + +import ( + "context" + "errors" + "fmt" + "math/big" + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/test" + "github.com/ethereum/go-ethereum/statediff/indexer/test_helpers" +) + +var ( + err error + db sql.Database + ind interfaces.StateDiffIndexer + chainConf = params.MainnetChainConfig +) + +func init() { + if os.Getenv("MODE") != "statediff" { + fmt.Println("Skipping statediff test") + os.Exit(0) + } + if os.Getenv("STATEDIFF_DB") != "file" { + fmt.Println("Skipping statediff .sql file writing mode test") + os.Exit(0) + } +} + +func TestPushBlockAndState(t *testing.T) { + conf := test_helpers.GetTestConfig() + + for _, blockNumber := range test_helpers.ProblemBlocks { + conf.BlockNumber = big.NewInt(blockNumber) + tb, trs, err := test_helpers.TestBlockAndReceipts(conf) + require.NoError(t, err) + + testPushBlockAndState(t, tb, trs) + } + + testBlock, testReceipts, err := test_helpers.TestBlockAndReceiptsFromEnv(conf) + require.NoError(t, err) + + testPushBlockAndState(t, testBlock, testReceipts) +} + +func testPushBlockAndState(t *testing.T, block *types.Block, receipts types.Receipts) { + t.Run("Test PushBlock and PushStateNode", func(t *testing.T) { + setupMainnetIndexer(t) + defer dumpData(t) + defer tearDown(t) + + test.TestBlock(t, ind, block, receipts) + }) +} + +func setupMainnetIndexer(t *testing.T) { + if _, err := os.Stat(file.CSVTestConfig.FilePath); !errors.Is(err, os.ErrNotExist) { + err := os.Remove(file.CSVTestConfig.FilePath) + require.NoError(t, err) + } + + ind, err = file.NewStateDiffIndexer(context.Background(), chainConf, file.CSVTestConfig) + require.NoError(t, err) + + db, err = postgres.SetupSQLXDB() + if err != nil { + t.Fatal(err) + } +} + +func dumpData(t *testing.T) { + sqlFileBytes, err := os.ReadFile(file.CSVTestConfig.FilePath) + require.NoError(t, err) + + _, err = db.Exec(context.Background(), string(sqlFileBytes)) + require.NoError(t, err) +} + +func tearDown(t *testing.T) { + test_helpers.TearDownDB(t, db) + require.NoError(t, db.Close()) + + require.NoError(t, os.Remove(file.CSVTestConfig.FilePath)) +} diff --git a/statediff/indexer/database/file/sql_indexer_legacy_test.go b/statediff/indexer/database/file/sql_indexer_legacy_test.go new file mode 100644 index 000000000..02ced177e --- /dev/null +++ b/statediff/indexer/database/file/sql_indexer_legacy_test.go @@ -0,0 +1,101 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file_test + +import ( + "context" + "errors" + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/test" + "github.com/ethereum/go-ethereum/statediff/indexer/test_helpers" +) + +var ( + db sql.Database + err error + ind interfaces.StateDiffIndexer +) + +func setupLegacySQLIndexer(t *testing.T) { + if _, err := os.Stat(file.SQLTestConfig.FilePath); !errors.Is(err, os.ErrNotExist) { + err := os.Remove(file.SQLTestConfig.FilePath) + require.NoError(t, err) + } + + ind, err = file.NewStateDiffIndexer(context.Background(), test.LegacyConfig, file.SQLTestConfig) + require.NoError(t, err) + + db, err = postgres.SetupSQLXDB() + if err != nil { + t.Fatal(err) + } +} + +func setupLegacySQL(t *testing.T) { + setupLegacySQLIndexer(t) + test.SetupLegacyTestData(t, ind) +} + +func dumpFileData(t *testing.T) { + err := test_helpers.DedupFile(file.SQLTestConfig.FilePath) + require.NoError(t, err) + + sqlFileBytes, err := os.ReadFile(file.SQLTestConfig.FilePath) + require.NoError(t, err) + + _, err = db.Exec(context.Background(), string(sqlFileBytes)) + require.NoError(t, err) +} + +func resetAndDumpWatchedAddressesFileData(t *testing.T) { + test_helpers.TearDownDB(t, db) + + sqlFileBytes, err := os.ReadFile(file.SQLTestConfig.WatchedAddressesFilePath) + require.NoError(t, err) + + _, err = db.Exec(context.Background(), string(sqlFileBytes)) + require.NoError(t, err) +} + +func tearDown(t *testing.T) { + test_helpers.TearDownDB(t, db) + require.NoError(t, db.Close()) + + require.NoError(t, os.Remove(file.SQLTestConfig.FilePath)) + + if err := os.Remove(file.SQLTestConfig.WatchedAddressesFilePath); !errors.Is(err, os.ErrNotExist) { + require.NoError(t, err) + } +} + +func TestLegacySQLFileIndexer(t *testing.T) { + t.Run("Publish and index header IPLDs", func(t *testing.T) { + setupLegacySQL(t) + dumpFileData(t) + defer tearDown(t) + + test.TestLegacyIndexer(t, db) + }) +} diff --git a/statediff/indexer/database/file/sql_indexer_test.go b/statediff/indexer/database/file/sql_indexer_test.go new file mode 100644 index 000000000..0a73a8c47 --- /dev/null +++ b/statediff/indexer/database/file/sql_indexer_test.go @@ -0,0 +1,253 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file_test + +import ( + "context" + "errors" + "math/big" + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" + "github.com/ethereum/go-ethereum/statediff/indexer/test" +) + +func setupIndexer(t *testing.T) { + if _, err := os.Stat(file.SQLTestConfig.FilePath); !errors.Is(err, os.ErrNotExist) { + err := os.Remove(file.SQLTestConfig.FilePath) + require.NoError(t, err) + } + + if _, err := os.Stat(file.SQLTestConfig.WatchedAddressesFilePath); !errors.Is(err, os.ErrNotExist) { + err := os.Remove(file.SQLTestConfig.WatchedAddressesFilePath) + require.NoError(t, err) + } + + ind, err = file.NewStateDiffIndexer(context.Background(), mocks.TestConfig, file.SQLTestConfig) + require.NoError(t, err) + + db, err = postgres.SetupSQLXDB() + if err != nil { + t.Fatal(err) + } +} + +func setup(t *testing.T) { + setupIndexer(t) + test.SetupTestData(t, ind) +} + +func setupSQLNonCanonical(t *testing.T) { + setupIndexer(t) + test.SetupTestDataNonCanonical(t, ind) +} + +func TestSQLFileIndexer(t *testing.T) { + t.Run("Publish and index header IPLDs in a single tx", func(t *testing.T) { + setup(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexHeaderIPLDs(t, db) + }) + + t.Run("Publish and index transaction IPLDs in a single tx", func(t *testing.T) { + setup(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexTransactionIPLDs(t, db) + }) + + t.Run("Publish and index log IPLDs for multiple receipt of a specific block", func(t *testing.T) { + setup(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexLogIPLDs(t, db) + }) + + t.Run("Publish and index receipt IPLDs in a single tx", func(t *testing.T) { + setup(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexReceiptIPLDs(t, db) + }) + + t.Run("Publish and index state IPLDs in a single tx", func(t *testing.T) { + setup(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexStateIPLDs(t, db) + }) + + t.Run("Publish and index storage IPLDs in a single tx", func(t *testing.T) { + setup(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexStorageIPLDs(t, db) + }) +} + +func TestSQLFileIndexerNonCanonical(t *testing.T) { + t.Run("Publish and index header", func(t *testing.T) { + setupSQLNonCanonical(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexHeaderNonCanonical(t, db) + }) + + t.Run("Publish and index transactions", func(t *testing.T) { + setupSQLNonCanonical(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexTransactionsNonCanonical(t, db) + }) + + t.Run("Publish and index receipts", func(t *testing.T) { + setupSQLNonCanonical(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexReceiptsNonCanonical(t, db) + }) + + t.Run("Publish and index logs", func(t *testing.T) { + setupSQLNonCanonical(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexLogsNonCanonical(t, db) + }) + + t.Run("Publish and index state nodes", func(t *testing.T) { + setupSQLNonCanonical(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexStateNonCanonical(t, db) + }) + + t.Run("Publish and index storage nodes", func(t *testing.T) { + setupSQLNonCanonical(t) + dumpFileData(t) + defer tearDown(t) + + test.TestPublishAndIndexStorageNonCanonical(t, db) + }) +} + +func TestSQLFileWatchAddressMethods(t *testing.T) { + setupIndexer(t) + defer tearDown(t) + + t.Run("Load watched addresses (empty table)", func(t *testing.T) { + test.TestLoadEmptyWatchedAddresses(t, ind) + }) + + t.Run("Insert watched addresses", func(t *testing.T) { + args := mocks.GetInsertWatchedAddressesArgs() + err = ind.InsertWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt1))) + require.NoError(t, err) + + resetAndDumpWatchedAddressesFileData(t) + + test.TestInsertWatchedAddresses(t, db) + }) + + t.Run("Insert watched addresses (some already watched)", func(t *testing.T) { + args := mocks.GetInsertAlreadyWatchedAddressesArgs() + err = ind.InsertWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt2))) + require.NoError(t, err) + + resetAndDumpWatchedAddressesFileData(t) + + test.TestInsertAlreadyWatchedAddresses(t, db) + }) + + t.Run("Remove watched addresses", func(t *testing.T) { + args := mocks.GetRemoveWatchedAddressesArgs() + err = ind.RemoveWatchedAddresses(args) + require.NoError(t, err) + + resetAndDumpWatchedAddressesFileData(t) + + test.TestRemoveWatchedAddresses(t, db) + }) + + t.Run("Remove watched addresses (some non-watched)", func(t *testing.T) { + args := mocks.GetRemoveNonWatchedAddressesArgs() + err = ind.RemoveWatchedAddresses(args) + require.NoError(t, err) + + resetAndDumpWatchedAddressesFileData(t) + + test.TestRemoveNonWatchedAddresses(t, db) + }) + + t.Run("Set watched addresses", func(t *testing.T) { + args := mocks.GetSetWatchedAddressesArgs() + err = ind.SetWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt2))) + require.NoError(t, err) + + resetAndDumpWatchedAddressesFileData(t) + + test.TestSetWatchedAddresses(t, db) + }) + + t.Run("Set watched addresses (some already watched)", func(t *testing.T) { + args := mocks.GetSetAlreadyWatchedAddressesArgs() + err = ind.SetWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt3))) + require.NoError(t, err) + + resetAndDumpWatchedAddressesFileData(t) + + test.TestSetAlreadyWatchedAddresses(t, db) + }) + + t.Run("Load watched addresses", func(t *testing.T) { + test.TestLoadWatchedAddresses(t, ind) + }) + + t.Run("Clear watched addresses", func(t *testing.T) { + err = ind.ClearWatchedAddresses() + require.NoError(t, err) + + resetAndDumpWatchedAddressesFileData(t) + + test.TestClearWatchedAddresses(t, db) + }) + + t.Run("Clear watched addresses (empty table)", func(t *testing.T) { + err = ind.ClearWatchedAddresses() + require.NoError(t, err) + + resetAndDumpWatchedAddressesFileData(t) + + test.TestClearEmptyWatchedAddresses(t, db) + }) +} diff --git a/statediff/indexer/database/file/sql_writer.go b/statediff/indexer/database/file/sql_writer.go new file mode 100644 index 000000000..6098a8cb5 --- /dev/null +++ b/statediff/indexer/database/file/sql_writer.go @@ -0,0 +1,431 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package file + +import ( + "bufio" + "errors" + "fmt" + "io" + "math/big" + "os" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + + blockstore "github.com/ipfs/go-ipfs-blockstore" + dshelp "github.com/ipfs/go-ipfs-ds-help" + node "github.com/ipfs/go-ipld-format" + pg_query "github.com/pganalyze/pg_query_go/v2" + "github.com/thoas/go-funk" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + nodeinfo "github.com/ethereum/go-ethereum/statediff/indexer/node" + "github.com/ethereum/go-ethereum/statediff/types" +) + +var ( + nullHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000") + pipeSize = 65336 // min(linuxPipeSize, macOSPipeSize) + writeBufferSize = pipeSize * 16 * 96 +) + +// SQLWriter writes sql statements to a file +type SQLWriter struct { + wc io.WriteCloser + stmts chan []byte + collatedStmt []byte + collationIndex int + + flushChan chan struct{} + flushFinished chan struct{} + quitChan chan struct{} + doneChan chan struct{} + + watchedAddressesFilePath string +} + +// NewSQLWriter creates a new pointer to a Writer +func NewSQLWriter(wc io.WriteCloser, watchedAddressesFilePath string) *SQLWriter { + return &SQLWriter{ + wc: wc, + stmts: make(chan []byte), + collatedStmt: make([]byte, writeBufferSize), + flushChan: make(chan struct{}), + flushFinished: make(chan struct{}), + quitChan: make(chan struct{}), + doneChan: make(chan struct{}), + watchedAddressesFilePath: watchedAddressesFilePath, + } +} + +// Loop enables concurrent writes to the underlying os.File +// since os.File does not buffer, it utilizes an internal buffer that is the size of a unix pipe +// by using copy() and tracking the index/size of the buffer, we require only the initial memory allocation +func (sqw *SQLWriter) Loop() { + sqw.collationIndex = 0 + go func() { + defer close(sqw.doneChan) + var l int + for { + select { + case stmt := <-sqw.stmts: + l = len(stmt) + if sqw.collationIndex+l > writeBufferSize { + if err := sqw.flush(); err != nil { + panic(fmt.Sprintf("error writing sql stmts buffer to file: %v", err)) + } + if l > writeBufferSize { + if _, err := sqw.wc.Write(stmt); err != nil { + panic(fmt.Sprintf("error writing large sql stmt to file: %v", err)) + } + continue + } + } + copy(sqw.collatedStmt[sqw.collationIndex:sqw.collationIndex+l], stmt) + sqw.collationIndex += l + case <-sqw.quitChan: + if err := sqw.flush(); err != nil { + panic(fmt.Sprintf("error writing sql stmts buffer to file: %v", err)) + } + return + case <-sqw.flushChan: + if err := sqw.flush(); err != nil { + panic(fmt.Sprintf("error writing sql stmts buffer to file: %v", err)) + } + sqw.flushFinished <- struct{}{} + } + } + }() +} + +// Close satisfies io.Closer +func (sqw *SQLWriter) Close() error { + close(sqw.quitChan) + <-sqw.doneChan + close(sqw.stmts) + close(sqw.flushChan) + close(sqw.flushFinished) + return sqw.wc.Close() +} + +// Flush sends a flush signal to the looping process +func (sqw *SQLWriter) Flush() { + sqw.flushChan <- struct{}{} + <-sqw.flushFinished +} + +func (sqw *SQLWriter) flush() error { + if _, err := sqw.wc.Write(sqw.collatedStmt[0:sqw.collationIndex]); err != nil { + return err + } + sqw.collationIndex = 0 + return nil +} + +const ( + nodeInsert = "INSERT INTO nodes (genesis_block, network_id, node_id, client_name, chain_id) VALUES " + + "('%s', '%s', '%s', '%s', %d);\n" + + ipldInsert = "INSERT INTO public.blocks (block_number, key, data) VALUES ('%s', '%s', '\\x%x');\n" + + headerInsert = "INSERT INTO eth.header_cids (block_number, block_hash, parent_hash, cid, td, node_id, reward, " + + "state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated, coinbase) VALUES " + + "('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '\\x%x', %d, '%s', %d, '%s');\n" + + uncleInsert = "INSERT INTO eth.uncle_cids (block_number, block_hash, header_id, parent_hash, cid, reward, mh_key) VALUES " + + "('%s', '%s', '%s', '%s', '%s', '%s', '%s');\n" + + txInsert = "INSERT INTO eth.transaction_cids (block_number, header_id, tx_hash, cid, dst, src, index, mh_key, tx_data, tx_type, " + + "value) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '\\x%x', %d, '%s');\n" + + alInsert = "INSERT INTO eth.access_list_elements (block_number, tx_id, index, address, storage_keys) VALUES " + + "('%s', '%s', %d, '%s', '%s');\n" + + rctInsert = "INSERT INTO eth.receipt_cids (block_number, header_id, tx_id, leaf_cid, contract, contract_hash, leaf_mh_key, post_state, " + + "post_status, log_root) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, '%s');\n" + + logInsert = "INSERT INTO eth.log_cids (block_number, header_id, leaf_cid, leaf_mh_key, rct_id, address, index, topic0, topic1, topic2, " + + "topic3, log_data) VALUES ('%s', '%s', '%s', '%s', '%s', '%s', %d, '%s', '%s', '%s', '%s', '\\x%x');\n" + + stateInsert = "INSERT INTO eth.state_cids (block_number, header_id, state_leaf_key, cid, state_path, node_type, diff, mh_key) " + + "VALUES ('%s', '%s', '%s', '%s', '\\x%x', %d, %t, '%s');\n" + + accountInsert = "INSERT INTO eth.state_accounts (block_number, header_id, state_path, balance, nonce, code_hash, storage_root) " + + "VALUES ('%s', '%s', '\\x%x', '%s', %d, '\\x%x', '%s');\n" + + storageInsert = "INSERT INTO eth.storage_cids (block_number, header_id, state_path, storage_leaf_key, cid, storage_path, " + + "node_type, diff, mh_key) VALUES ('%s', '%s', '\\x%x', '%s', '%s', '\\x%x', %d, %t, '%s');\n" +) + +func (sqw *SQLWriter) upsertNode(node nodeinfo.Info) { + sqw.stmts <- []byte(fmt.Sprintf(nodeInsert, node.GenesisBlock, node.NetworkID, node.ID, node.ClientName, node.ChainID)) +} + +func (sqw *SQLWriter) upsertIPLD(ipld models.IPLDModel) { + sqw.stmts <- []byte(fmt.Sprintf(ipldInsert, ipld.BlockNumber, ipld.Key, ipld.Data)) +} + +func (sqw *SQLWriter) upsertIPLDDirect(blockNumber, key string, value []byte) { + sqw.upsertIPLD(models.IPLDModel{ + BlockNumber: blockNumber, + Key: key, + Data: value, + }) +} + +func (sqw *SQLWriter) upsertIPLDNode(blockNumber string, i node.Node) { + sqw.upsertIPLD(models.IPLDModel{ + BlockNumber: blockNumber, + Key: blockstore.BlockPrefix.String() + dshelp.MultihashToDsKey(i.Cid().Hash()).String(), + Data: i.RawData(), + }) +} + +func (sqw *SQLWriter) upsertIPLDRaw(blockNumber string, codec, mh uint64, raw []byte) (string, string, error) { + c, err := ipld.RawdataToCid(codec, raw, mh) + if err != nil { + return "", "", err + } + prefixedKey := blockstore.BlockPrefix.String() + dshelp.MultihashToDsKey(c.Hash()).String() + sqw.upsertIPLD(models.IPLDModel{ + BlockNumber: blockNumber, + Key: prefixedKey, + Data: raw, + }) + return c.String(), prefixedKey, err +} + +func (sqw *SQLWriter) upsertHeaderCID(header models.HeaderModel) { + stmt := fmt.Sprintf(headerInsert, header.BlockNumber, header.BlockHash, header.ParentHash, header.CID, + header.TotalDifficulty, header.NodeID, header.Reward, header.StateRoot, header.TxRoot, + header.RctRoot, header.UncleRoot, header.Bloom, header.Timestamp, header.MhKey, 1, header.Coinbase) + sqw.stmts <- []byte(stmt) + metrics.IndexerMetrics.BlocksCounter.Inc(1) +} + +func (sqw *SQLWriter) upsertUncleCID(uncle models.UncleModel) { + sqw.stmts <- []byte(fmt.Sprintf(uncleInsert, uncle.BlockNumber, uncle.BlockHash, uncle.HeaderID, uncle.ParentHash, uncle.CID, + uncle.Reward, uncle.MhKey)) +} + +func (sqw *SQLWriter) upsertTransactionCID(transaction models.TxModel) { + sqw.stmts <- []byte(fmt.Sprintf(txInsert, transaction.BlockNumber, transaction.HeaderID, transaction.TxHash, transaction.CID, transaction.Dst, + transaction.Src, transaction.Index, transaction.MhKey, transaction.Data, transaction.Type, transaction.Value)) + metrics.IndexerMetrics.TransactionsCounter.Inc(1) +} + +func (sqw *SQLWriter) upsertAccessListElement(accessListElement models.AccessListElementModel) { + sqw.stmts <- []byte(fmt.Sprintf(alInsert, accessListElement.BlockNumber, accessListElement.TxID, accessListElement.Index, accessListElement.Address, + formatPostgresStringArray(accessListElement.StorageKeys))) + metrics.IndexerMetrics.AccessListEntriesCounter.Inc(1) +} + +func (sqw *SQLWriter) upsertReceiptCID(rct *models.ReceiptModel) { + sqw.stmts <- []byte(fmt.Sprintf(rctInsert, rct.BlockNumber, rct.HeaderID, rct.TxID, rct.LeafCID, rct.Contract, rct.ContractHash, rct.LeafMhKey, + rct.PostState, rct.PostStatus, rct.LogRoot)) + metrics.IndexerMetrics.ReceiptsCounter.Inc(1) +} + +func (sqw *SQLWriter) upsertLogCID(logs []*models.LogsModel) { + for _, l := range logs { + sqw.stmts <- []byte(fmt.Sprintf(logInsert, l.BlockNumber, l.HeaderID, l.LeafCID, l.LeafMhKey, l.ReceiptID, l.Address, l.Index, l.Topic0, + l.Topic1, l.Topic2, l.Topic3, l.Data)) + metrics.IndexerMetrics.LogsCounter.Inc(1) + } +} + +func (sqw *SQLWriter) upsertStateCID(stateNode models.StateNodeModel) { + var stateKey string + if stateNode.StateKey != nullHash.String() { + stateKey = stateNode.StateKey + } + sqw.stmts <- []byte(fmt.Sprintf(stateInsert, stateNode.BlockNumber, stateNode.HeaderID, stateKey, stateNode.CID, stateNode.Path, + stateNode.NodeType, true, stateNode.MhKey)) +} + +func (sqw *SQLWriter) upsertStateAccount(stateAccount models.StateAccountModel) { + sqw.stmts <- []byte(fmt.Sprintf(accountInsert, stateAccount.BlockNumber, stateAccount.HeaderID, stateAccount.StatePath, stateAccount.Balance, + stateAccount.Nonce, stateAccount.CodeHash, stateAccount.StorageRoot)) +} + +func (sqw *SQLWriter) upsertStorageCID(storageCID models.StorageNodeModel) { + var storageKey string + if storageCID.StorageKey != nullHash.String() { + storageKey = storageCID.StorageKey + } + sqw.stmts <- []byte(fmt.Sprintf(storageInsert, storageCID.BlockNumber, storageCID.HeaderID, storageCID.StatePath, storageKey, storageCID.CID, + storageCID.Path, storageCID.NodeType, true, storageCID.MhKey)) +} + +// LoadWatchedAddresses loads watched addresses from a file +func (sqw *SQLWriter) loadWatchedAddresses() ([]common.Address, error) { + // load sql statements from watched addresses file + stmts, err := loadWatchedAddressesStatements(sqw.watchedAddressesFilePath) + if err != nil { + return nil, err + } + + // extract addresses from the sql statements + watchedAddresses := []common.Address{} + for _, stmt := range stmts { + addressString, err := parseWatchedAddressStatement(stmt) + if err != nil { + return nil, err + } + watchedAddresses = append(watchedAddresses, common.HexToAddress(addressString)) + } + + return watchedAddresses, nil +} + +// InsertWatchedAddresses inserts the given addresses in a file +func (sqw *SQLWriter) insertWatchedAddresses(args []types.WatchAddressArg, currentBlockNumber *big.Int) error { + // load sql statements from watched addresses file + stmts, err := loadWatchedAddressesStatements(sqw.watchedAddressesFilePath) + if err != nil { + return err + } + + // get already watched addresses + var watchedAddresses []string + for _, stmt := range stmts { + addressString, err := parseWatchedAddressStatement(stmt) + if err != nil { + return err + } + + watchedAddresses = append(watchedAddresses, addressString) + } + + // append statements for new addresses to existing statements + for _, arg := range args { + // ignore if already watched + if funk.Contains(watchedAddresses, arg.Address) { + continue + } + + stmt := fmt.Sprintf(watchedAddressesInsert, arg.Address, arg.CreatedAt, currentBlockNumber.Uint64()) + stmts = append(stmts, stmt) + } + + return dumpWatchedAddressesStatements(sqw.watchedAddressesFilePath, stmts) +} + +// RemoveWatchedAddresses removes the given watched addresses from a file +func (sqw *SQLWriter) removeWatchedAddresses(args []types.WatchAddressArg) error { + // load sql statements from watched addresses file + stmts, err := loadWatchedAddressesStatements(sqw.watchedAddressesFilePath) + if err != nil { + return err + } + + // get rid of statements having addresses to be removed + var filteredStmts []string + for _, stmt := range stmts { + addressString, err := parseWatchedAddressStatement(stmt) + if err != nil { + return err + } + + toRemove := funk.Contains(args, func(arg types.WatchAddressArg) bool { + return arg.Address == addressString + }) + + if !toRemove { + filteredStmts = append(filteredStmts, stmt) + } + } + + return dumpWatchedAddressesStatements(sqw.watchedAddressesFilePath, filteredStmts) +} + +// SetWatchedAddresses clears and inserts the given addresses in a file +func (sqw *SQLWriter) setWatchedAddresses(args []types.WatchAddressArg, currentBlockNumber *big.Int) error { + var stmts []string + for _, arg := range args { + stmt := fmt.Sprintf(watchedAddressesInsert, arg.Address, arg.CreatedAt, currentBlockNumber.Uint64()) + stmts = append(stmts, stmt) + } + + return dumpWatchedAddressesStatements(sqw.watchedAddressesFilePath, stmts) +} + +// loadWatchedAddressesStatements loads sql statements from the given file in a string slice +func loadWatchedAddressesStatements(filePath string) ([]string, error) { + file, err := os.Open(filePath) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return []string{}, nil + } + + return nil, fmt.Errorf("error opening watched addresses file: %v", err) + } + defer file.Close() + + stmts := []string{} + scanner := bufio.NewScanner(file) + for scanner.Scan() { + stmts = append(stmts, scanner.Text()) + } + + if err := scanner.Err(); err != nil { + return nil, fmt.Errorf("error loading watched addresses: %v", err) + } + + return stmts, nil +} + +// dumpWatchedAddressesStatements dumps sql statements to the given file +func dumpWatchedAddressesStatements(filePath string, stmts []string) error { + file, err := os.Create(filePath) + if err != nil { + return fmt.Errorf("error creating watched addresses file: %v", err) + } + defer file.Close() + + for _, stmt := range stmts { + _, err := file.Write([]byte(stmt + "\n")) + if err != nil { + return fmt.Errorf("error inserting watched_addresses entry: %v", err) + } + } + + return nil +} + +// parseWatchedAddressStatement parses given sql insert statement to extract the address argument +func parseWatchedAddressStatement(stmt string) (string, error) { + parseResult, err := pg_query.Parse(stmt) + if err != nil { + return "", fmt.Errorf("error parsing sql stmt: %v", err) + } + + // extract address argument from parse output for a SQL statement of form + // "INSERT INTO eth_meta.watched_addresses (address, created_at, watched_at) + // VALUES ('0xabc', '123', '130') ON CONFLICT (address) DO NOTHING;" + addressString := parseResult.Stmts[0].Stmt.GetInsertStmt(). + SelectStmt.GetSelectStmt(). + ValuesLists[0].GetList(). + Items[0].GetAConst(). + GetVal(). + GetString_(). + Str + + return addressString, nil +} diff --git a/statediff/indexer/database/file/types/schema.go b/statediff/indexer/database/file/types/schema.go new file mode 100644 index 000000000..ea0daefd6 --- /dev/null +++ b/statediff/indexer/database/file/types/schema.go @@ -0,0 +1,186 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +var TableIPLDBlock = Table{ + `public.blocks`, + []column{ + {name: "block_number", dbType: bigint}, + {name: "key", dbType: text}, + {name: "data", dbType: bytea}, + }, +} + +var TableNodeInfo = Table{ + Name: `public.nodes`, + Columns: []column{ + {name: "genesis_block", dbType: varchar}, + {name: "network_id", dbType: varchar}, + {name: "node_id", dbType: varchar}, + {name: "client_name", dbType: varchar}, + {name: "chain_id", dbType: integer}, + }, +} + +var TableHeader = Table{ + "eth.header_cids", + []column{ + {name: "block_number", dbType: bigint}, + {name: "block_hash", dbType: varchar}, + {name: "parent_hash", dbType: varchar}, + {name: "cid", dbType: text}, + {name: "td", dbType: numeric}, + {name: "node_id", dbType: varchar}, + {name: "reward", dbType: numeric}, + {name: "state_root", dbType: varchar}, + {name: "tx_root", dbType: varchar}, + {name: "receipt_root", dbType: varchar}, + {name: "uncle_root", dbType: varchar}, + {name: "bloom", dbType: bytea}, + {name: "timestamp", dbType: numeric}, + {name: "mh_key", dbType: text}, + {name: "times_validated", dbType: integer}, + {name: "coinbase", dbType: varchar}, + }, +} + +var TableStateNode = Table{ + "eth.state_cids", + []column{ + {name: "block_number", dbType: bigint}, + {name: "header_id", dbType: varchar}, + {name: "state_leaf_key", dbType: varchar}, + {name: "cid", dbType: text}, + {name: "state_path", dbType: bytea}, + {name: "node_type", dbType: integer}, + {name: "diff", dbType: boolean}, + {name: "mh_key", dbType: text}, + }, +} + +var TableStorageNode = Table{ + "eth.storage_cids", + []column{ + {name: "block_number", dbType: bigint}, + {name: "header_id", dbType: varchar}, + {name: "state_path", dbType: bytea}, + {name: "storage_leaf_key", dbType: varchar}, + {name: "cid", dbType: text}, + {name: "storage_path", dbType: bytea}, + {name: "node_type", dbType: integer}, + {name: "diff", dbType: boolean}, + {name: "mh_key", dbType: text}, + }, +} + +var TableUncle = Table{ + "eth.uncle_cids", + []column{ + {name: "block_number", dbType: bigint}, + {name: "block_hash", dbType: varchar}, + {name: "header_id", dbType: varchar}, + {name: "parent_hash", dbType: varchar}, + {name: "cid", dbType: text}, + {name: "reward", dbType: numeric}, + {name: "mh_key", dbType: text}, + }, +} + +var TableTransaction = Table{ + "eth.transaction_cids", + []column{ + {name: "block_number", dbType: bigint}, + {name: "header_id", dbType: varchar}, + {name: "tx_hash", dbType: varchar}, + {name: "cid", dbType: text}, + {name: "dst", dbType: varchar}, + {name: "src", dbType: varchar}, + {name: "index", dbType: integer}, + {name: "mh_key", dbType: text}, + {name: "tx_data", dbType: bytea}, + {name: "tx_type", dbType: integer}, + {name: "value", dbType: numeric}, + }, +} + +var TableAccessListElement = Table{ + "eth.access_list_elements", + []column{ + {name: "block_number", dbType: bigint}, + {name: "tx_id", dbType: varchar}, + {name: "index", dbType: integer}, + {name: "address", dbType: varchar}, + {name: "storage_keys", dbType: varchar, isArray: true}, + }, +} + +var TableReceipt = Table{ + "eth.receipt_cids", + []column{ + {name: "block_number", dbType: bigint}, + {name: "header_id", dbType: varchar}, + {name: "tx_id", dbType: varchar}, + {name: "leaf_cid", dbType: text}, + {name: "contract", dbType: varchar}, + {name: "contract_hash", dbType: varchar}, + {name: "leaf_mh_key", dbType: text}, + {name: "post_state", dbType: varchar}, + {name: "post_status", dbType: integer}, + {name: "log_root", dbType: varchar}, + }, +} + +var TableLog = Table{ + "eth.log_cids", + []column{ + {name: "block_number", dbType: bigint}, + {name: "header_id", dbType: varchar}, + {name: "leaf_cid", dbType: text}, + {name: "leaf_mh_key", dbType: text}, + {name: "rct_id", dbType: varchar}, + {name: "address", dbType: varchar}, + {name: "index", dbType: integer}, + {name: "topic0", dbType: varchar}, + {name: "topic1", dbType: varchar}, + {name: "topic2", dbType: varchar}, + {name: "topic3", dbType: varchar}, + {name: "log_data", dbType: bytea}, + }, +} + +var TableStateAccount = Table{ + "eth.state_accounts", + []column{ + {name: "block_number", dbType: bigint}, + {name: "header_id", dbType: varchar}, + {name: "state_path", dbType: bytea}, + {name: "balance", dbType: numeric}, + {name: "nonce", dbType: bigint}, + {name: "code_hash", dbType: bytea}, + {name: "storage_root", dbType: varchar}, + }, +} + +var TableWatchedAddresses = Table{ + "eth_meta.watched_addresses", + []column{ + {name: "address", dbType: varchar}, + {name: "created_at", dbType: bigint}, + {name: "watched_at", dbType: bigint}, + {name: "last_filled_at", dbType: bigint}, + }, +} diff --git a/statediff/indexer/database/file/types/table.go b/statediff/indexer/database/file/types/table.go new file mode 100644 index 000000000..d7fd5af6c --- /dev/null +++ b/statediff/indexer/database/file/types/table.go @@ -0,0 +1,104 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "fmt" + "strings" + + "github.com/thoas/go-funk" +) + +type colType int + +const ( + integer colType = iota + boolean + bigint + numeric + bytea + varchar + text +) + +type column struct { + name string + dbType colType + isArray bool +} +type Table struct { + Name string + Columns []column +} + +func (tbl *Table) ToCsvRow(args ...interface{}) []string { + var row []string + for i, col := range tbl.Columns { + value := col.dbType.formatter()(args[i]) + + if col.isArray { + valueList := funk.Map(args[i], col.dbType.formatter()).([]string) + value = fmt.Sprintf("{%s}", strings.Join(valueList, ",")) + } + + row = append(row, value) + } + return row +} + +func (tbl *Table) VarcharColumns() []string { + columns := funk.Filter(tbl.Columns, func(col column) bool { + return col.dbType == varchar + }).([]column) + + columnNames := funk.Map(columns, func(col column) string { + return col.name + }).([]string) + + return columnNames +} + +type colfmt = func(interface{}) string + +func sprintf(f string) colfmt { + return func(x interface{}) string { return fmt.Sprintf(f, x) } +} + +func (typ colType) formatter() colfmt { + switch typ { + case integer: + return sprintf("%d") + case boolean: + return func(x interface{}) string { + if x.(bool) { + return "t" + } + return "f" + } + case bigint: + return sprintf("%s") + case numeric: + return sprintf("%s") + case bytea: + return sprintf(`\x%x`) + case varchar: + return sprintf("%s") + case text: + return sprintf("%s") + } + panic("unreachable") +} diff --git a/statediff/indexer/database/metrics/metrics.go b/statediff/indexer/database/metrics/metrics.go new file mode 100644 index 000000000..550dd238e --- /dev/null +++ b/statediff/indexer/database/metrics/metrics.go @@ -0,0 +1,263 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package metrics + +import ( + "fmt" + "strings" + "time" + + "github.com/ethereum/go-ethereum/log" + + "github.com/ethereum/go-ethereum/metrics" +) + +const ( + namespace = "statediff" +) + +var ( + IndexerMetrics = RegisterIndexerMetrics(metrics.DefaultRegistry) + DBMetrics = RegisterDBMetrics(metrics.DefaultRegistry) +) + +// Build a fully qualified metric name +func metricName(subsystem, name string) string { + if name == "" { + return "" + } + parts := []string{namespace, name} + if subsystem != "" { + parts = []string{namespace, subsystem, name} + } + // Prometheus uses _ but geth metrics uses / and replaces + return strings.Join(parts, "/") +} + +type IndexerMetricsHandles struct { + // The total number of processed BlocksCounter + BlocksCounter metrics.Counter + // The total number of processed transactions + TransactionsCounter metrics.Counter + // The total number of processed receipts + ReceiptsCounter metrics.Counter + // The total number of processed logs + LogsCounter metrics.Counter + // The total number of access list entries processed + AccessListEntriesCounter metrics.Counter + // Time spent waiting for free postgres tx + FreePostgresTimer metrics.Timer + // Postgres transaction commit duration + PostgresCommitTimer metrics.Timer + // Header processing time + HeaderProcessingTimer metrics.Timer + // Uncle processing time + UncleProcessingTimer metrics.Timer + // Tx and receipt processing time + TxAndRecProcessingTimer metrics.Timer + // State, storage, and code combined processing time + StateStoreCodeProcessingTimer metrics.Timer + + // Fine-grained code timers + BuildStateDiffWithIntermediateStateNodesTimer metrics.Timer + BuildStateDiffWithoutIntermediateStateNodesTimer metrics.Timer + CreatedAndUpdatedStateWithIntermediateNodesTimer metrics.Timer + DeletedOrUpdatedStateTimer metrics.Timer + BuildAccountUpdatesTimer metrics.Timer + BuildAccountCreationsTimer metrics.Timer + ResolveNodeTimer metrics.Timer + SortKeysTimer metrics.Timer + FindIntersectionTimer metrics.Timer + OutputTimer metrics.Timer + CodeOutputTimer metrics.Timer + DifferenceIteratorNextTimer metrics.Timer + DifferenceIteratorCounter metrics.Counter + DeletedOrUpdatedStorageTimer metrics.Timer + CreatedAndUpdatedStorageTimer metrics.Timer + BuildStorageNodesIncrementalTimer metrics.Timer + BuildStateTrieObjectTimer metrics.Timer + BuildStateTrieTimer metrics.Timer + BuildStateDiffObjectTimer metrics.Timer + WriteStateDiffObjectTimer metrics.Timer + CreatedAndUpdatedStateTimer metrics.Timer + BuildStorageNodesEventualTimer metrics.Timer + BuildStorageNodesFromTrieTimer metrics.Timer + BuildRemovedAccountStorageNodesTimer metrics.Timer + BuildRemovedStorageNodesFromTrieTimer metrics.Timer + IsWatchedAddressTimer metrics.Timer +} + +func RegisterIndexerMetrics(reg metrics.Registry) IndexerMetricsHandles { + ctx := IndexerMetricsHandles{ + BlocksCounter: metrics.NewCounter(), + TransactionsCounter: metrics.NewCounter(), + ReceiptsCounter: metrics.NewCounter(), + LogsCounter: metrics.NewCounter(), + AccessListEntriesCounter: metrics.NewCounter(), + FreePostgresTimer: metrics.NewTimer(), + PostgresCommitTimer: metrics.NewTimer(), + HeaderProcessingTimer: metrics.NewTimer(), + UncleProcessingTimer: metrics.NewTimer(), + TxAndRecProcessingTimer: metrics.NewTimer(), + StateStoreCodeProcessingTimer: metrics.NewTimer(), + BuildStateDiffWithIntermediateStateNodesTimer: metrics.NewTimer(), + BuildStateDiffWithoutIntermediateStateNodesTimer: metrics.NewTimer(), + CreatedAndUpdatedStateWithIntermediateNodesTimer: metrics.NewTimer(), + DeletedOrUpdatedStateTimer: metrics.NewTimer(), + BuildAccountUpdatesTimer: metrics.NewTimer(), + BuildAccountCreationsTimer: metrics.NewTimer(), + ResolveNodeTimer: metrics.NewTimer(), + SortKeysTimer: metrics.NewTimer(), + FindIntersectionTimer: metrics.NewTimer(), + OutputTimer: metrics.NewTimer(), + CodeOutputTimer: metrics.NewTimer(), + DifferenceIteratorNextTimer: metrics.NewTimer(), + DifferenceIteratorCounter: metrics.NewCounter(), + DeletedOrUpdatedStorageTimer: metrics.NewTimer(), + CreatedAndUpdatedStorageTimer: metrics.NewTimer(), + BuildStorageNodesIncrementalTimer: metrics.NewTimer(), + BuildStateTrieObjectTimer: metrics.NewTimer(), + BuildStateTrieTimer: metrics.NewTimer(), + BuildStateDiffObjectTimer: metrics.NewTimer(), + WriteStateDiffObjectTimer: metrics.NewTimer(), + CreatedAndUpdatedStateTimer: metrics.NewTimer(), + BuildStorageNodesEventualTimer: metrics.NewTimer(), + BuildStorageNodesFromTrieTimer: metrics.NewTimer(), + BuildRemovedAccountStorageNodesTimer: metrics.NewTimer(), + BuildRemovedStorageNodesFromTrieTimer: metrics.NewTimer(), + IsWatchedAddressTimer: metrics.NewTimer(), + } + subsys := "indexer" + reg.Register(metricName(subsys, "blocks"), ctx.BlocksCounter) + reg.Register(metricName(subsys, "transactions"), ctx.TransactionsCounter) + reg.Register(metricName(subsys, "receipts"), ctx.ReceiptsCounter) + reg.Register(metricName(subsys, "logs"), ctx.LogsCounter) + reg.Register(metricName(subsys, "access_list_entries"), ctx.AccessListEntriesCounter) + reg.Register(metricName(subsys, "t_free_postgres"), ctx.FreePostgresTimer) + reg.Register(metricName(subsys, "t_postgres_commit"), ctx.PostgresCommitTimer) + reg.Register(metricName(subsys, "t_header_processing"), ctx.HeaderProcessingTimer) + reg.Register(metricName(subsys, "t_uncle_processing"), ctx.UncleProcessingTimer) + reg.Register(metricName(subsys, "t_tx_receipt_processing"), ctx.TxAndRecProcessingTimer) + reg.Register(metricName(subsys, "t_state_store_code_processing"), ctx.StateStoreCodeProcessingTimer) + reg.Register(metricName(subsys, "t_build_statediff_with_intermediate_state_nodes"), ctx.BuildStateDiffWithIntermediateStateNodesTimer) + reg.Register(metricName(subsys, "t_build_statediff_without_intermediate_state_nodes"), ctx.BuildStateDiffWithoutIntermediateStateNodesTimer) + reg.Register(metricName(subsys, "t_created_and_update_state_with_intermediate_nodes"), ctx.CreatedAndUpdatedStateWithIntermediateNodesTimer) + reg.Register(metricName(subsys, "t_deleted_or_updated_state"), ctx.DeletedOrUpdatedStateTimer) + reg.Register(metricName(subsys, "t_build_account_updates"), ctx.BuildAccountUpdatesTimer) + reg.Register(metricName(subsys, "t_build_account_creations"), ctx.BuildAccountCreationsTimer) + reg.Register(metricName(subsys, "t_resolve_node"), ctx.ResolveNodeTimer) + reg.Register(metricName(subsys, "t_sort_keys"), ctx.SortKeysTimer) + reg.Register(metricName(subsys, "t_find_intersection"), ctx.FindIntersectionTimer) + reg.Register(metricName(subsys, "t_output_fn"), ctx.OutputTimer) + reg.Register(metricName(subsys, "t_code_output_fn"), ctx.CodeOutputTimer) + reg.Register(metricName(subsys, "t_difference_iterator_next"), ctx.DifferenceIteratorNextTimer) + reg.Register(metricName(subsys, "difference_iterator_counter"), ctx.DifferenceIteratorCounter) + reg.Register(metricName(subsys, "t_created_and_updated_storage"), ctx.CreatedAndUpdatedStorageTimer) + reg.Register(metricName(subsys, "t_deleted_or_updated_storage"), ctx.DeletedOrUpdatedStorageTimer) + reg.Register(metricName(subsys, "t_build_storage_nodes_incremental"), ctx.BuildStorageNodesIncrementalTimer) + reg.Register(metricName(subsys, "t_build_state_trie_object"), ctx.BuildStateTrieObjectTimer) + reg.Register(metricName(subsys, "t_build_state_trie"), ctx.BuildStateTrieTimer) + reg.Register(metricName(subsys, "t_build_statediff_object"), ctx.BuildStateDiffObjectTimer) + reg.Register(metricName(subsys, "t_write_statediff_object"), ctx.WriteStateDiffObjectTimer) + reg.Register(metricName(subsys, "t_created_and_updated_state"), ctx.CreatedAndUpdatedStateTimer) + reg.Register(metricName(subsys, "t_build_storage_nodes_eventual"), ctx.BuildStorageNodesEventualTimer) + reg.Register(metricName(subsys, "t_build_storage_nodes_from_trie"), ctx.BuildStorageNodesFromTrieTimer) + reg.Register(metricName(subsys, "t_build_removed_accounts_storage_nodes"), ctx.BuildRemovedAccountStorageNodesTimer) + reg.Register(metricName(subsys, "t_build_removed_storage_nodes_from_trie"), ctx.BuildRemovedStorageNodesFromTrieTimer) + reg.Register(metricName(subsys, "t_is_watched_address"), ctx.IsWatchedAddressTimer) + + log.Debug("Registering statediff indexer metrics.") + return ctx +} + +type dbMetricsHandles struct { + // Maximum number of open connections to the sql + maxOpen metrics.Gauge + // The number of established connections both in use and idle + open metrics.Gauge + // The number of connections currently in use + inUse metrics.Gauge + // The number of idle connections + idle metrics.Gauge + // The total number of connections waited for + waitedFor metrics.Counter + // The total time blocked waiting for a new connection + blockedMilliseconds metrics.Counter + // The total number of connections closed due to SetMaxIdleConns + closedMaxIdle metrics.Counter + // The total number of connections closed due to SetConnMaxLifetime + closedMaxLifetime metrics.Counter +} + +func RegisterDBMetrics(reg metrics.Registry) dbMetricsHandles { + ctx := dbMetricsHandles{ + maxOpen: metrics.NewGauge(), + open: metrics.NewGauge(), + inUse: metrics.NewGauge(), + idle: metrics.NewGauge(), + waitedFor: metrics.NewCounter(), + blockedMilliseconds: metrics.NewCounter(), + closedMaxIdle: metrics.NewCounter(), + closedMaxLifetime: metrics.NewCounter(), + } + subsys := "connections" + reg.Register(metricName(subsys, "max_open"), ctx.maxOpen) + reg.Register(metricName(subsys, "open"), ctx.open) + reg.Register(metricName(subsys, "in_use"), ctx.inUse) + reg.Register(metricName(subsys, "idle"), ctx.idle) + reg.Register(metricName(subsys, "waited_for"), ctx.waitedFor) + reg.Register(metricName(subsys, "blocked_milliseconds"), ctx.blockedMilliseconds) + reg.Register(metricName(subsys, "closed_max_idle"), ctx.closedMaxIdle) + reg.Register(metricName(subsys, "closed_max_lifetime"), ctx.closedMaxLifetime) + + log.Debug("Registering statediff DB metrics.") + return ctx +} + +// DbStats interface to accommodate different concrete sql stats types +type DbStats interface { + MaxOpen() int64 + Open() int64 + InUse() int64 + Idle() int64 + WaitCount() int64 + WaitDuration() time.Duration + MaxIdleClosed() int64 + MaxLifetimeClosed() int64 +} + +func (met *dbMetricsHandles) Update(stats DbStats) { + met.maxOpen.Update(stats.MaxOpen()) + met.open.Update(stats.Open()) + met.inUse.Update(stats.InUse()) + met.idle.Update(stats.Idle()) + met.waitedFor.Inc(stats.WaitCount()) + met.blockedMilliseconds.Inc(stats.WaitDuration().Milliseconds()) + met.closedMaxIdle.Inc(stats.MaxIdleClosed()) + met.closedMaxLifetime.Inc(stats.MaxLifetimeClosed()) +} + +func ReportAndUpdateDuration(msg string, start time.Time, logger log.Logger, timer metrics.Timer) { + since := UpdateDuration(start, timer) + logger.Debug(fmt.Sprintf("%s duration=%dms", msg, since.Milliseconds())) +} + +func UpdateDuration(start time.Time, timer metrics.Timer) time.Duration { + since := time.Since(start) + timer.Update(since) + return since +} diff --git a/statediff/indexer/database/sql/batch_tx.go b/statediff/indexer/database/sql/batch_tx.go new file mode 100644 index 000000000..5f9d09b25 --- /dev/null +++ b/statediff/indexer/database/sql/batch_tx.go @@ -0,0 +1,144 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package sql + +import ( + "context" + "sync" + "sync/atomic" + + blockstore "github.com/ipfs/go-ipfs-blockstore" + dshelp "github.com/ipfs/go-ipfs-ds-help" + node "github.com/ipfs/go-ipld-format" + "github.com/lib/pq" + + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + "github.com/ethereum/go-ethereum/statediff/indexer/models" +) + +const startingCacheCapacity = 1024 * 24 + +// BatchTx wraps a sql tx with the state necessary for building the tx concurrently during trie difference iteration +type BatchTx struct { + BlockNumber string + ctx context.Context + dbtx Tx + stm string + quit chan struct{} + iplds chan models.IPLDModel + ipldCache models.IPLDBatch + removedCacheFlag *uint32 + // Tracks expected cache size and ensures cache is caught up before flush + cacheWg sync.WaitGroup + + submit func(blockTx *BatchTx, err error) error +} + +// Submit satisfies indexer.AtomicTx +func (tx *BatchTx) Submit(err error) error { + return tx.submit(tx, err) +} + +func (tx *BatchTx) flush() error { + tx.cacheWg.Wait() + _, err := tx.dbtx.Exec(tx.ctx, tx.stm, pq.Array(tx.ipldCache.BlockNumbers), pq.Array(tx.ipldCache.Keys), + pq.Array(tx.ipldCache.Values)) + if err != nil { + log.Debug(insertError{"public.blocks", err, tx.stm, + struct { + blockNumbers []string + keys []string + values [][]byte + }{ + tx.ipldCache.BlockNumbers, + tx.ipldCache.Keys, + tx.ipldCache.Values, + }}.Error()) + return insertError{"public.blocks", err, tx.stm, "too many arguments; use debug mode for full list"} + } + tx.ipldCache = models.IPLDBatch{} + return nil +} + +// run in background goroutine to synchronize concurrent appends to the ipldCache +func (tx *BatchTx) cache() { + for { + select { + case i := <-tx.iplds: + tx.ipldCache.BlockNumbers = append(tx.ipldCache.BlockNumbers, i.BlockNumber) + tx.ipldCache.Keys = append(tx.ipldCache.Keys, i.Key) + tx.ipldCache.Values = append(tx.ipldCache.Values, i.Data) + tx.cacheWg.Done() + case <-tx.quit: + tx.ipldCache = models.IPLDBatch{} + return + } + } +} + +func (tx *BatchTx) cacheDirect(key string, value []byte) { + tx.cacheWg.Add(1) + tx.iplds <- models.IPLDModel{ + BlockNumber: tx.BlockNumber, + Key: key, + Data: value, + } +} + +func (tx *BatchTx) cacheIPLD(i node.Node) { + tx.cacheWg.Add(1) + tx.iplds <- models.IPLDModel{ + BlockNumber: tx.BlockNumber, + Key: blockstore.BlockPrefix.String() + dshelp.MultihashToDsKey(i.Cid().Hash()).String(), + Data: i.RawData(), + } +} + +func (tx *BatchTx) cacheRaw(codec, mh uint64, raw []byte) (string, string, error) { + c, err := ipld.RawdataToCid(codec, raw, mh) + if err != nil { + return "", "", err + } + prefixedKey := blockstore.BlockPrefix.String() + dshelp.MultihashToDsKey(c.Hash()).String() + tx.cacheWg.Add(1) + tx.iplds <- models.IPLDModel{ + BlockNumber: tx.BlockNumber, + Key: prefixedKey, + Data: raw, + } + return c.String(), prefixedKey, err +} + +func (tx *BatchTx) cacheRemoved(key string, value []byte) { + if atomic.LoadUint32(tx.removedCacheFlag) == 0 { + atomic.StoreUint32(tx.removedCacheFlag, 1) + tx.cacheWg.Add(1) + tx.iplds <- models.IPLDModel{ + BlockNumber: tx.BlockNumber, + Key: key, + Data: value, + } + } +} + +// rollback sql transaction and log any error +func rollback(ctx context.Context, tx Tx) { + if err := tx.Rollback(ctx); err != nil { + log.Error(err.Error()) + } +} diff --git a/statediff/indexer/database/sql/indexer.go b/statediff/indexer/database/sql/indexer.go new file mode 100644 index 000000000..66893ce2a --- /dev/null +++ b/statediff/indexer/database/sql/indexer.go @@ -0,0 +1,671 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +// Package sql provides an interface for pushing and indexing IPLD objects into a sql database +// Metrics for reporting processing and connection stats are defined in ./metrics.go + +package sql + +import ( + "context" + "fmt" + "math/big" + "time" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + metrics2 "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + ipld2 "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + "github.com/ethereum/go-ethereum/statediff/indexer/shared" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +var _ interfaces.StateDiffIndexer = &StateDiffIndexer{} + +// StateDiffIndexer satisfies the indexer.StateDiffIndexer interface for ethereum statediff objects on top of an SQL sql +type StateDiffIndexer struct { + ctx context.Context + chainConfig *params.ChainConfig + dbWriter *Writer +} + +// NewStateDiffIndexer creates a sql implementation of interfaces.StateDiffIndexer +func NewStateDiffIndexer(ctx context.Context, chainConfig *params.ChainConfig, db Database) (*StateDiffIndexer, error) { + return &StateDiffIndexer{ + ctx: ctx, + chainConfig: chainConfig, + dbWriter: NewWriter(db), + }, nil +} + +// ReportDBMetrics is a reporting function to run as goroutine +func (sdi *StateDiffIndexer) ReportDBMetrics(delay time.Duration, quit <-chan bool) { + if !metrics.Enabled { + return + } + ticker := time.NewTicker(delay) + go func() { + for { + select { + case <-ticker.C: + metrics2.DBMetrics.Update(sdi.dbWriter.db.Stats()) + case <-quit: + ticker.Stop() + return + } + } + }() +} + +// PushBlock pushes and indexes block data in sql, except state & storage nodes (includes header, uncles, transactions & receipts) +// Returns an initiated DB transaction which must be Closed via defer to commit or rollback +func (sdi *StateDiffIndexer) PushBlock(block *types.Block, receipts types.Receipts, totalDifficulty *big.Int) (interfaces.Batch, error) { + start, t := time.Now(), time.Now() + blockHash := block.Hash() + blockHashStr := blockHash.String() + height := block.NumberU64() + traceMsg := fmt.Sprintf("indexer stats for statediff at %d with hash %s:\r\n", height, blockHashStr) + transactions := block.Transactions() + // Derive any missing fields + if err := receipts.DeriveFields(sdi.chainConfig, blockHash, height, transactions); err != nil { + return nil, err + } + + // Generate the block iplds + headerNode, uncleNodes, txNodes, txTrieNodes, rctNodes, rctTrieNodes, logTrieNodes, logLeafNodeCIDs, rctLeafNodeCIDs, err := ipld2.FromBlockAndReceipts(block, receipts) + if err != nil { + return nil, fmt.Errorf("error creating IPLD nodes from block and receipts: %v", err) + } + + if len(txNodes) != len(rctNodes) || len(rctNodes) != len(rctLeafNodeCIDs) { + return nil, fmt.Errorf("expected number of transactions (%d), receipts (%d), and receipt trie leaf nodes (%d) to be equal", len(txNodes), len(rctNodes), len(rctLeafNodeCIDs)) + } + if len(txTrieNodes) != len(rctTrieNodes) { + return nil, fmt.Errorf("expected number of tx trie (%d) and rct trie (%d) nodes to be equal", len(txTrieNodes), len(rctTrieNodes)) + } + + // Calculate reward + var reward *big.Int + // in PoA networks block reward is 0 + if sdi.chainConfig.Clique != nil { + reward = big.NewInt(0) + } else { + reward = shared.CalcEthBlockReward(block.Header(), block.Uncles(), block.Transactions(), receipts) + } + t = time.Now() + + // Begin new DB tx for everything + tx := NewDelayedTx(sdi.dbWriter.db) + defer func() { + if p := recover(); p != nil { + rollback(sdi.ctx, tx) + panic(p) + } else if err != nil { + rollback(sdi.ctx, tx) + } + }() + blockTx := &BatchTx{ + removedCacheFlag: new(uint32), + ctx: sdi.ctx, + BlockNumber: block.Number().String(), + stm: sdi.dbWriter.db.InsertIPLDsStm(), + iplds: make(chan models.IPLDModel), + quit: make(chan struct{}), + ipldCache: models.IPLDBatch{ + BlockNumbers: make([]string, 0, startingCacheCapacity), + Keys: make([]string, 0, startingCacheCapacity), + Values: make([][]byte, 0, startingCacheCapacity), + }, + dbtx: tx, + // handle transaction commit or rollback for any return case + submit: func(self *BatchTx, err error) error { + defer func() { + close(self.quit) + close(self.iplds) + }() + if p := recover(); p != nil { + log.Info("panic detected before tx submission, rolling back the tx", "panic", p) + rollback(sdi.ctx, tx) + panic(p) + } else if err != nil { + log.Info("error detected before tx submission, rolling back the tx", "error", err) + rollback(sdi.ctx, tx) + } else { + tDiff := time.Since(t) + metrics2.IndexerMetrics.StateStoreCodeProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("state, storage, and code storage processing time: %s\r\n", tDiff.String()) + t = time.Now() + if err := self.flush(); err != nil { + rollback(sdi.ctx, tx) + traceMsg += fmt.Sprintf(" TOTAL PROCESSING DURATION: %s\r\n", time.Since(start).String()) + log.Debug(traceMsg) + return err + } + err = tx.Commit(sdi.ctx) + tDiff = time.Since(t) + metrics2.IndexerMetrics.PostgresCommitTimer.Update(tDiff) + traceMsg += fmt.Sprintf("postgres transaction commit duration: %s\r\n", tDiff.String()) + } + traceMsg += fmt.Sprintf(" TOTAL PROCESSING DURATION: %s\r\n", time.Since(start).String()) + log.Debug(traceMsg) + return err + }, + } + go blockTx.cache() + + tDiff := time.Since(t) + metrics2.IndexerMetrics.FreePostgresTimer.Update(tDiff) + + traceMsg += fmt.Sprintf("time spent waiting for free postgres tx: %s:\r\n", tDiff.String()) + t = time.Now() + + // Publish and index header, collect headerID + var headerID string + headerID, err = sdi.processHeader(blockTx, block.Header(), headerNode, reward, totalDifficulty) + if err != nil { + return nil, err + } + tDiff = time.Since(t) + metrics2.IndexerMetrics.HeaderProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("header processing time: %s\r\n", tDiff.String()) + t = time.Now() + // Publish and index uncles + err = sdi.processUncles(blockTx, headerID, block.Number(), uncleNodes) + if err != nil { + return nil, err + } + tDiff = time.Since(t) + metrics2.IndexerMetrics.UncleProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("uncle processing time: %s\r\n", tDiff.String()) + t = time.Now() + // Publish and index receipts and txs + err = sdi.processReceiptsAndTxs(blockTx, processArgs{ + headerID: headerID, + blockNumber: block.Number(), + receipts: receipts, + txs: transactions, + rctNodes: rctNodes, + rctTrieNodes: rctTrieNodes, + txNodes: txNodes, + txTrieNodes: txTrieNodes, + logTrieNodes: logTrieNodes, + logLeafNodeCIDs: logLeafNodeCIDs, + rctLeafNodeCIDs: rctLeafNodeCIDs, + }) + if err != nil { + return nil, err + } + tDiff = time.Since(t) + metrics2.IndexerMetrics.TxAndRecProcessingTimer.Update(tDiff) + traceMsg += fmt.Sprintf("tx and receipt processing time: %s\r\n", tDiff.String()) + t = time.Now() + + return blockTx, err +} + +// processHeader publishes and indexes a header IPLD in Postgres +// it returns the headerID +func (sdi *StateDiffIndexer) processHeader(tx *BatchTx, header *types.Header, headerNode node.Node, reward, td *big.Int) (string, error) { + tx.cacheIPLD(headerNode) + + var baseFee *string + if header.BaseFee != nil { + baseFee = new(string) + *baseFee = header.BaseFee.String() + } + headerID := header.Hash().String() + // index header + return headerID, sdi.dbWriter.upsertHeaderCID(tx.dbtx, models.HeaderModel{ + CID: headerNode.Cid().String(), + MhKey: shared.MultihashKeyFromCID(headerNode.Cid()), + ParentHash: header.ParentHash.String(), + BlockNumber: header.Number.String(), + BlockHash: headerID, + TotalDifficulty: td.String(), + Reward: reward.String(), + Bloom: header.Bloom.Bytes(), + StateRoot: header.Root.String(), + RctRoot: header.ReceiptHash.String(), + TxRoot: header.TxHash.String(), + UncleRoot: header.UncleHash.String(), + Timestamp: header.Time, + Coinbase: header.Coinbase.String(), + }) +} + +// processUncles publishes and indexes uncle IPLDs in Postgres +func (sdi *StateDiffIndexer) processUncles(tx *BatchTx, headerID string, blockNumber *big.Int, uncleNodes []*ipld2.EthHeader) error { + // publish and index uncles + for _, uncleNode := range uncleNodes { + tx.cacheIPLD(uncleNode) + var uncleReward *big.Int + // in PoA networks uncle reward is 0 + if sdi.chainConfig.Clique != nil { + uncleReward = big.NewInt(0) + } else { + uncleReward = shared.CalcUncleMinerReward(blockNumber.Uint64(), uncleNode.Number.Uint64()) + } + uncle := models.UncleModel{ + BlockNumber: blockNumber.String(), + HeaderID: headerID, + CID: uncleNode.Cid().String(), + MhKey: shared.MultihashKeyFromCID(uncleNode.Cid()), + ParentHash: uncleNode.ParentHash.String(), + BlockHash: uncleNode.Hash().String(), + Reward: uncleReward.String(), + } + if err := sdi.dbWriter.upsertUncleCID(tx.dbtx, uncle); err != nil { + return err + } + } + return nil +} + +// processArgs bundles arguments to processReceiptsAndTxs +type processArgs struct { + headerID string + blockNumber *big.Int + receipts types.Receipts + txs types.Transactions + rctNodes []*ipld2.EthReceipt + rctTrieNodes []*ipld2.EthRctTrie + txNodes []*ipld2.EthTx + txTrieNodes []*ipld2.EthTxTrie + logTrieNodes [][]node.Node + logLeafNodeCIDs [][]cid.Cid + rctLeafNodeCIDs []cid.Cid +} + +// processReceiptsAndTxs publishes and indexes receipt and transaction IPLDs in Postgres +func (sdi *StateDiffIndexer) processReceiptsAndTxs(tx *BatchTx, args processArgs) error { + // Process receipts and txs + signer := types.MakeSigner(sdi.chainConfig, args.blockNumber) + for i, receipt := range args.receipts { + for _, logTrieNode := range args.logTrieNodes[i] { + tx.cacheIPLD(logTrieNode) + } + txNode := args.txNodes[i] + tx.cacheIPLD(txNode) + + // index tx + trx := args.txs[i] + txID := trx.Hash().String() + + var val string + if trx.Value() != nil { + val = trx.Value().String() + } + + // derive sender for the tx that corresponds with this receipt + from, err := types.Sender(signer, trx) + if err != nil { + return fmt.Errorf("error deriving tx sender: %v", err) + } + txModel := models.TxModel{ + BlockNumber: args.blockNumber.String(), + HeaderID: args.headerID, + Dst: shared.HandleZeroAddrPointer(trx.To()), + Src: shared.HandleZeroAddr(from), + TxHash: txID, + Index: int64(i), + Data: trx.Data(), + CID: txNode.Cid().String(), + MhKey: shared.MultihashKeyFromCID(txNode.Cid()), + Type: trx.Type(), + Value: val, + } + if err := sdi.dbWriter.upsertTransactionCID(tx.dbtx, txModel); err != nil { + return err + } + + // index access list if this is one + for j, accessListElement := range trx.AccessList() { + storageKeys := make([]string, len(accessListElement.StorageKeys)) + for k, storageKey := range accessListElement.StorageKeys { + storageKeys[k] = storageKey.Hex() + } + accessListElementModel := models.AccessListElementModel{ + BlockNumber: args.blockNumber.String(), + TxID: txID, + Index: int64(j), + Address: accessListElement.Address.Hex(), + StorageKeys: storageKeys, + } + if err := sdi.dbWriter.upsertAccessListElement(tx.dbtx, accessListElementModel); err != nil { + return err + } + } + + // this is the contract address if this receipt is for a contract creation tx + contract := shared.HandleZeroAddr(receipt.ContractAddress) + var contractHash string + if contract != "" { + contractHash = crypto.Keccak256Hash(common.HexToAddress(contract).Bytes()).String() + } + + // index receipt + if !args.rctLeafNodeCIDs[i].Defined() { + return fmt.Errorf("invalid receipt leaf node cid") + } + + rctModel := &models.ReceiptModel{ + BlockNumber: args.blockNumber.String(), + HeaderID: args.headerID, + TxID: txID, + Contract: contract, + ContractHash: contractHash, + LeafCID: args.rctLeafNodeCIDs[i].String(), + LeafMhKey: shared.MultihashKeyFromCID(args.rctLeafNodeCIDs[i]), + LogRoot: args.rctNodes[i].LogRoot.String(), + } + if len(receipt.PostState) == 0 { + rctModel.PostStatus = receipt.Status + } else { + rctModel.PostState = common.Bytes2Hex(receipt.PostState) + } + + if err := sdi.dbWriter.upsertReceiptCID(tx.dbtx, rctModel); err != nil { + return err + } + + // index logs + logDataSet := make([]*models.LogsModel, len(receipt.Logs)) + for idx, l := range receipt.Logs { + topicSet := make([]string, 4) + for ti, topic := range l.Topics { + topicSet[ti] = topic.Hex() + } + + if !args.logLeafNodeCIDs[i][idx].Defined() { + return fmt.Errorf("invalid log cid") + } + + logDataSet[idx] = &models.LogsModel{ + BlockNumber: args.blockNumber.String(), + HeaderID: args.headerID, + ReceiptID: txID, + Address: l.Address.String(), + Index: int64(l.Index), + Data: l.Data, + LeafCID: args.logLeafNodeCIDs[i][idx].String(), + LeafMhKey: shared.MultihashKeyFromCID(args.logLeafNodeCIDs[i][idx]), + Topic0: topicSet[0], + Topic1: topicSet[1], + Topic2: topicSet[2], + Topic3: topicSet[3], + } + } + + if err := sdi.dbWriter.upsertLogCID(tx.dbtx, logDataSet); err != nil { + return err + } + } + + // publish trie nodes, these aren't indexed directly + for i, n := range args.txTrieNodes { + tx.cacheIPLD(n) + tx.cacheIPLD(args.rctTrieNodes[i]) + } + + return nil +} + +// PushStateNode publishes and indexes a state diff node object (including any child storage nodes) in the IPLD sql +func (sdi *StateDiffIndexer) PushStateNode(batch interfaces.Batch, stateNode sdtypes.StateNode, headerID string) error { + tx, ok := batch.(*BatchTx) + if !ok { + return fmt.Errorf("sql: batch is expected to be of type %T, got %T", &BatchTx{}, batch) + } + // publish the state node + var stateModel models.StateNodeModel + if stateNode.NodeType == sdtypes.Removed { + tx.cacheRemoved(shared.RemovedNodeMhKey, []byte{}) + stateModel = models.StateNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + Path: stateNode.Path, + StateKey: common.BytesToHash(stateNode.LeafKey).String(), + CID: shared.RemovedNodeStateCID, + MhKey: shared.RemovedNodeMhKey, + NodeType: stateNode.NodeType.Int(), + } + } else { + stateCIDStr, stateMhKey, err := tx.cacheRaw(ipld2.MEthStateTrie, multihash.KECCAK_256, stateNode.NodeValue) + if err != nil { + return fmt.Errorf("error generating and cacheing state node IPLD: %v", err) + } + stateModel = models.StateNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + Path: stateNode.Path, + StateKey: common.BytesToHash(stateNode.LeafKey).String(), + CID: stateCIDStr, + MhKey: stateMhKey, + NodeType: stateNode.NodeType.Int(), + } + } + + // index the state node + if err := sdi.dbWriter.upsertStateCID(tx.dbtx, stateModel); err != nil { + return err + } + + // if we have a leaf, decode and index the account data + if stateNode.NodeType == sdtypes.Leaf { + var i []interface{} + if err := rlp.DecodeBytes(stateNode.NodeValue, &i); err != nil { + return fmt.Errorf("error decoding state leaf node rlp: %s", err.Error()) + } + if len(i) != 2 { + return fmt.Errorf("eth IPLDPublisher expected state leaf node rlp to decode into two elements") + } + var account types.StateAccount + if err := rlp.DecodeBytes(i[1].([]byte), &account); err != nil { + return fmt.Errorf("error decoding state account rlp: %s", err.Error()) + } + accountModel := models.StateAccountModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + StatePath: stateNode.Path, + Balance: account.Balance.String(), + Nonce: account.Nonce, + CodeHash: account.CodeHash, + StorageRoot: account.Root.String(), + } + if err := sdi.dbWriter.upsertStateAccount(tx.dbtx, accountModel); err != nil { + return err + } + } + + // if there are any storage nodes associated with this node, publish and index them + for _, storageNode := range stateNode.StorageNodes { + if storageNode.NodeType == sdtypes.Removed { + tx.cacheRemoved(shared.RemovedNodeMhKey, []byte{}) + storageModel := models.StorageNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + StatePath: stateNode.Path, + Path: storageNode.Path, + StorageKey: common.BytesToHash(storageNode.LeafKey).String(), + CID: shared.RemovedNodeStorageCID, + MhKey: shared.RemovedNodeMhKey, + NodeType: storageNode.NodeType.Int(), + } + if err := sdi.dbWriter.upsertStorageCID(tx.dbtx, storageModel); err != nil { + return err + } + continue + } + storageCIDStr, storageMhKey, err := tx.cacheRaw(ipld2.MEthStorageTrie, multihash.KECCAK_256, storageNode.NodeValue) + if err != nil { + return fmt.Errorf("error generating and cacheing storage node IPLD: %v", err) + } + storageModel := models.StorageNodeModel{ + BlockNumber: tx.BlockNumber, + HeaderID: headerID, + StatePath: stateNode.Path, + Path: storageNode.Path, + StorageKey: common.BytesToHash(storageNode.LeafKey).String(), + CID: storageCIDStr, + MhKey: storageMhKey, + NodeType: storageNode.NodeType.Int(), + } + if err := sdi.dbWriter.upsertStorageCID(tx.dbtx, storageModel); err != nil { + return err + } + } + + return nil +} + +// PushCodeAndCodeHash publishes code and codehash pairs to the ipld sql +func (sdi *StateDiffIndexer) PushCodeAndCodeHash(batch interfaces.Batch, codeAndCodeHash sdtypes.CodeAndCodeHash) error { + tx, ok := batch.(*BatchTx) + if !ok { + return fmt.Errorf("sql: batch is expected to be of type %T, got %T", &BatchTx{}, batch) + } + // codec doesn't matter since db key is multihash-based + mhKey, err := shared.MultihashKeyFromKeccak256(codeAndCodeHash.Hash) + if err != nil { + return fmt.Errorf("error deriving multihash key from codehash: %v", err) + } + tx.cacheDirect(mhKey, codeAndCodeHash.Code) + return nil +} + +// Close satisfies io.Closer +func (sdi *StateDiffIndexer) Close() error { + return sdi.dbWriter.Close() +} + +// Update the known gaps table with the gap information. + +// LoadWatchedAddresses reads watched addresses from the database +func (sdi *StateDiffIndexer) LoadWatchedAddresses() ([]common.Address, error) { + addressStrings := make([]string, 0) + pgStr := "SELECT address FROM eth_meta.watched_addresses" + err := sdi.dbWriter.db.Select(sdi.ctx, &addressStrings, pgStr) + if err != nil { + return nil, fmt.Errorf("error loading watched addresses: %v", err) + } + + watchedAddresses := []common.Address{} + for _, addressString := range addressStrings { + watchedAddresses = append(watchedAddresses, common.HexToAddress(addressString)) + } + + return watchedAddresses, nil +} + +// InsertWatchedAddresses inserts the given addresses in the database +func (sdi *StateDiffIndexer) InsertWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) (err error) { + tx := NewDelayedTx(sdi.dbWriter.db) + defer func() { + if p := recover(); p != nil { + rollback(sdi.ctx, tx) + panic(p) + } else if err != nil { + rollback(sdi.ctx, tx) + } else { + err = tx.Commit(sdi.ctx) + } + }() + + for _, arg := range args { + _, err = tx.Exec(sdi.ctx, `INSERT INTO eth_meta.watched_addresses (address, created_at, watched_at) VALUES ($1, $2, $3) ON CONFLICT (address) DO NOTHING`, + arg.Address, arg.CreatedAt, currentBlockNumber.Uint64()) + if err != nil { + return fmt.Errorf("error inserting watched_addresses entry: %v", err) + } + } + + return err +} + +// RemoveWatchedAddresses removes the given watched addresses from the database +func (sdi *StateDiffIndexer) RemoveWatchedAddresses(args []sdtypes.WatchAddressArg) (err error) { + tx := NewDelayedTx(sdi.dbWriter.db) + defer func() { + if p := recover(); p != nil { + rollback(sdi.ctx, tx) + panic(p) + } else if err != nil { + rollback(sdi.ctx, tx) + } else { + err = tx.Commit(sdi.ctx) + } + }() + + for _, arg := range args { + _, err = tx.Exec(sdi.ctx, `DELETE FROM eth_meta.watched_addresses WHERE address = $1`, arg.Address) + if err != nil { + return fmt.Errorf("error removing watched_addresses entry: %v", err) + } + } + + return err +} + +// SetWatchedAddresses clears and inserts the given addresses in the database +func (sdi *StateDiffIndexer) SetWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) (err error) { + tx := NewDelayedTx(sdi.dbWriter.db) + defer func() { + if p := recover(); p != nil { + rollback(sdi.ctx, tx) + panic(p) + } else if err != nil { + rollback(sdi.ctx, tx) + } else { + err = tx.Commit(sdi.ctx) + } + }() + + _, err = tx.Exec(sdi.ctx, `DELETE FROM eth_meta.watched_addresses`) + if err != nil { + return fmt.Errorf("error setting watched_addresses table: %v", err) + } + + for _, arg := range args { + _, err = tx.Exec(sdi.ctx, `INSERT INTO eth_meta.watched_addresses (address, created_at, watched_at) VALUES ($1, $2, $3) ON CONFLICT (address) DO NOTHING`, + arg.Address, arg.CreatedAt, currentBlockNumber.Uint64()) + if err != nil { + return fmt.Errorf("error setting watched_addresses table: %v", err) + } + } + + return err +} + +// ClearWatchedAddresses clears all the watched addresses from the database +func (sdi *StateDiffIndexer) ClearWatchedAddresses() error { + _, err := sdi.dbWriter.db.Exec(sdi.ctx, `DELETE FROM eth_meta.watched_addresses`) + if err != nil { + return fmt.Errorf("error clearing watched_addresses table: %v", err) + } + + return nil +} diff --git a/statediff/indexer/database/sql/indexer_shared_test.go b/statediff/indexer/database/sql/indexer_shared_test.go new file mode 100644 index 000000000..13fd0c026 --- /dev/null +++ b/statediff/indexer/database/sql/indexer_shared_test.go @@ -0,0 +1,28 @@ +package sql_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/test_helpers" +) + +var ( + db sql.Database + err error + ind interfaces.StateDiffIndexer +) + +func checkTxClosure(t *testing.T, idle, inUse, open int64) { + require.Equal(t, idle, db.Stats().Idle()) + require.Equal(t, inUse, db.Stats().InUse()) + require.Equal(t, open, db.Stats().Open()) +} + +func tearDown(t *testing.T) { + test_helpers.TearDownDB(t, db) + require.NoError(t, ind.Close()) +} diff --git a/statediff/indexer/database/sql/interfaces.go b/statediff/indexer/database/sql/interfaces.go new file mode 100644 index 000000000..1e7278db6 --- /dev/null +++ b/statediff/indexer/database/sql/interfaces.go @@ -0,0 +1,77 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package sql + +import ( + "context" + "io" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" +) + +// Database interfaces required by the sql indexer +type Database interface { + Driver + Statements +} + +// Driver interface has all the methods required by a driver implementation to support the sql indexer +type Driver interface { + QueryRow(ctx context.Context, sql string, args ...interface{}) ScannableRow + Exec(ctx context.Context, sql string, args ...interface{}) (Result, error) + Select(ctx context.Context, dest interface{}, query string, args ...interface{}) error + Get(ctx context.Context, dest interface{}, query string, args ...interface{}) error + Begin(ctx context.Context) (Tx, error) + Stats() metrics.DbStats + NodeID() string + Context() context.Context + io.Closer +} + +// Statements interface to accommodate different SQL query syntax +type Statements interface { + InsertHeaderStm() string + InsertUncleStm() string + InsertTxStm() string + InsertAccessListElementStm() string + InsertRctStm() string + InsertLogStm() string + InsertStateStm() string + InsertAccountStm() string + InsertStorageStm() string + InsertIPLDStm() string + InsertIPLDsStm() string + InsertKnownGapsStm() string +} + +// Tx interface to accommodate different concrete SQL transaction types +type Tx interface { + QueryRow(ctx context.Context, sql string, args ...interface{}) ScannableRow + Exec(ctx context.Context, sql string, args ...interface{}) (Result, error) + Commit(ctx context.Context) error + Rollback(ctx context.Context) error +} + +// ScannableRow interface to accommodate different concrete row types +type ScannableRow interface { + Scan(dest ...interface{}) error +} + +// Result interface to accommodate different concrete result types +type Result interface { + RowsAffected() (int64, error) +} diff --git a/statediff/indexer/database/sql/lazy_tx.go b/statediff/indexer/database/sql/lazy_tx.go new file mode 100644 index 000000000..922bf84a0 --- /dev/null +++ b/statediff/indexer/database/sql/lazy_tx.go @@ -0,0 +1,55 @@ +package sql + +import ( + "context" +) + +type DelayedTx struct { + cache []cachedStmt + db Database +} +type cachedStmt struct { + sql string + args []interface{} +} + +func NewDelayedTx(db Database) *DelayedTx { + return &DelayedTx{db: db} +} + +func (tx *DelayedTx) QueryRow(ctx context.Context, sql string, args ...interface{}) ScannableRow { + return tx.db.QueryRow(ctx, sql, args...) +} + +func (tx *DelayedTx) Exec(ctx context.Context, sql string, args ...interface{}) (Result, error) { + tx.cache = append(tx.cache, cachedStmt{sql, args}) + return nil, nil +} + +func (tx *DelayedTx) Commit(ctx context.Context) error { + base, err := tx.db.Begin(ctx) + if err != nil { + return err + } + defer func() { + if p := recover(); p != nil { + rollback(ctx, base) + panic(p) + } else if err != nil { + rollback(ctx, base) + } + }() + for _, stmt := range tx.cache { + _, err := base.Exec(ctx, stmt.sql, stmt.args...) + if err != nil { + return err + } + } + tx.cache = nil + return base.Commit(ctx) +} + +func (tx *DelayedTx) Rollback(ctx context.Context) error { + tx.cache = nil + return nil +} diff --git a/statediff/indexer/database/sql/mainnet_tests/indexer_test.go b/statediff/indexer/database/sql/mainnet_tests/indexer_test.go new file mode 100644 index 000000000..ce57a74ac --- /dev/null +++ b/statediff/indexer/database/sql/mainnet_tests/indexer_test.go @@ -0,0 +1,95 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package mainnet_tests + +import ( + "context" + "fmt" + "math/big" + "os" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/test" + "github.com/ethereum/go-ethereum/statediff/indexer/test_helpers" +) + +var ( + err error + db sql.Database + ind interfaces.StateDiffIndexer + chainConf = params.MainnetChainConfig +) + +func init() { + if os.Getenv("MODE") != "statediff" { + fmt.Println("Skipping statediff test") + os.Exit(0) + } +} + +func TestMainnetIndexer(t *testing.T) { + conf := test_helpers.GetTestConfig() + + for _, blockNumber := range test_helpers.ProblemBlocks { + conf.BlockNumber = big.NewInt(blockNumber) + tb, trs, err := test_helpers.TestBlockAndReceipts(conf) + require.NoError(t, err) + + testPushBlockAndState(t, tb, trs) + } + + testBlock, testReceipts, err := test_helpers.TestBlockAndReceiptsFromEnv(conf) + require.NoError(t, err) + + testPushBlockAndState(t, testBlock, testReceipts) +} + +func testPushBlockAndState(t *testing.T, block *types.Block, receipts types.Receipts) { + t.Run("Test PushBlock and PushStateNode", func(t *testing.T) { + setupMainnetIndexer(t) + defer checkTxClosure(t, 0, 0, 0) + defer tearDown(t) + + test.TestBlock(t, ind, block, receipts) + }) +} + +func setupMainnetIndexer(t *testing.T) { + db, err = postgres.SetupSQLXDB() + if err != nil { + t.Fatal(err) + } + ind, err = sql.NewStateDiffIndexer(context.Background(), chainConf, db) +} + +func checkTxClosure(t *testing.T, idle, inUse, open int64) { + require.Equal(t, idle, db.Stats().Idle()) + require.Equal(t, inUse, db.Stats().InUse()) + require.Equal(t, open, db.Stats().Open()) +} + +func tearDown(t *testing.T) { + test_helpers.TearDownDB(t, db) + require.NoError(t, ind.Close()) +} diff --git a/statediff/indexer/database/sql/pgx_indexer_legacy_test.go b/statediff/indexer/database/sql/pgx_indexer_legacy_test.go new file mode 100644 index 000000000..292548b75 --- /dev/null +++ b/statediff/indexer/database/sql/pgx_indexer_legacy_test.go @@ -0,0 +1,52 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package sql_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/test" +) + +func setupLegacyPGXIndexer(t *testing.T) { + db, err = postgres.SetupPGXDB() + if err != nil { + t.Fatal(err) + } + ind, err = sql.NewStateDiffIndexer(context.Background(), test.LegacyConfig, db) + require.NoError(t, err) +} + +func setupLegacyPGX(t *testing.T) { + setupLegacyPGXIndexer(t) + test.SetupLegacyTestData(t, ind) +} + +func TestLegacyPGXIndexer(t *testing.T) { + t.Run("Publish and index header IPLDs", func(t *testing.T) { + setupLegacyPGX(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestLegacyIndexer(t, db) + }) +} diff --git a/statediff/indexer/database/sql/pgx_indexer_test.go b/statediff/indexer/database/sql/pgx_indexer_test.go new file mode 100644 index 000000000..1dbf2dfa0 --- /dev/null +++ b/statediff/indexer/database/sql/pgx_indexer_test.go @@ -0,0 +1,227 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package sql_test + +import ( + "context" + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" + "github.com/ethereum/go-ethereum/statediff/indexer/test" +) + +func setupPGXIndexer(t *testing.T) { + db, err = postgres.SetupPGXDB() + if err != nil { + t.Fatal(err) + } + ind, err = sql.NewStateDiffIndexer(context.Background(), mocks.TestConfig, db) + require.NoError(t, err) +} + +func setupPGX(t *testing.T) { + setupPGXIndexer(t) + test.SetupTestData(t, ind) +} + +func setupPGXNonCanonical(t *testing.T) { + setupPGXIndexer(t) + test.SetupTestDataNonCanonical(t, ind) +} + +// Test indexer for a canonical block +func TestPGXIndexer(t *testing.T) { + t.Run("Publish and index header IPLDs in a single tx", func(t *testing.T) { + setupPGX(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexHeaderIPLDs(t, db) + }) + + t.Run("Publish and index transaction IPLDs in a single tx", func(t *testing.T) { + setupPGX(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexTransactionIPLDs(t, db) + }) + + t.Run("Publish and index log IPLDs for multiple receipt of a specific block", func(t *testing.T) { + setupPGX(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexLogIPLDs(t, db) + }) + + t.Run("Publish and index receipt IPLDs in a single tx", func(t *testing.T) { + setupPGX(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexReceiptIPLDs(t, db) + }) + + t.Run("Publish and index state IPLDs in a single tx", func(t *testing.T) { + setupPGX(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexStateIPLDs(t, db) + }) + + t.Run("Publish and index storage IPLDs in a single tx", func(t *testing.T) { + setupPGX(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexStorageIPLDs(t, db) + }) +} + +// Test indexer for a canonical + a non-canonical block at London height + a non-canonical block at London height + 1 +func TestPGXIndexerNonCanonical(t *testing.T) { + t.Run("Publish and index header", func(t *testing.T) { + setupPGXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexHeaderNonCanonical(t, db) + }) + + t.Run("Publish and index transactions", func(t *testing.T) { + setupPGXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexTransactionsNonCanonical(t, db) + }) + + t.Run("Publish and index receipts", func(t *testing.T) { + setupPGXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexReceiptsNonCanonical(t, db) + }) + + t.Run("Publish and index logs", func(t *testing.T) { + setupPGXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexLogsNonCanonical(t, db) + }) + + t.Run("Publish and index state nodes", func(t *testing.T) { + setupPGXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexStateNonCanonical(t, db) + }) + + t.Run("Publish and index storage nodes", func(t *testing.T) { + setupPGXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + test.TestPublishAndIndexStorageNonCanonical(t, db) + }) +} + +func TestPGXWatchAddressMethods(t *testing.T) { + setupPGXIndexer(t) + defer tearDown(t) + defer checkTxClosure(t, 1, 0, 1) + + t.Run("Load watched addresses (empty table)", func(t *testing.T) { + test.TestLoadEmptyWatchedAddresses(t, ind) + }) + + t.Run("Insert watched addresses", func(t *testing.T) { + args := mocks.GetInsertWatchedAddressesArgs() + err = ind.InsertWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt1))) + require.NoError(t, err) + + test.TestInsertWatchedAddresses(t, db) + }) + + t.Run("Insert watched addresses (some already watched)", func(t *testing.T) { + args := mocks.GetInsertAlreadyWatchedAddressesArgs() + err = ind.InsertWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt2))) + require.NoError(t, err) + + test.TestInsertAlreadyWatchedAddresses(t, db) + }) + + t.Run("Remove watched addresses", func(t *testing.T) { + args := mocks.GetRemoveWatchedAddressesArgs() + err = ind.RemoveWatchedAddresses(args) + require.NoError(t, err) + + test.TestRemoveWatchedAddresses(t, db) + }) + + t.Run("Remove watched addresses (some non-watched)", func(t *testing.T) { + args := mocks.GetRemoveNonWatchedAddressesArgs() + err = ind.RemoveWatchedAddresses(args) + require.NoError(t, err) + + test.TestRemoveNonWatchedAddresses(t, db) + }) + + t.Run("Set watched addresses", func(t *testing.T) { + args := mocks.GetSetWatchedAddressesArgs() + err = ind.SetWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt2))) + require.NoError(t, err) + + test.TestSetWatchedAddresses(t, db) + }) + + t.Run("Set watched addresses (some already watched)", func(t *testing.T) { + args := mocks.GetSetAlreadyWatchedAddressesArgs() + err = ind.SetWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt3))) + require.NoError(t, err) + + test.TestSetAlreadyWatchedAddresses(t, db) + }) + + t.Run("Load watched addresses", func(t *testing.T) { + test.TestLoadWatchedAddresses(t, ind) + }) + + t.Run("Clear watched addresses", func(t *testing.T) { + err = ind.ClearWatchedAddresses() + require.NoError(t, err) + + test.TestClearWatchedAddresses(t, db) + }) + + t.Run("Clear watched addresses (empty table)", func(t *testing.T) { + err = ind.ClearWatchedAddresses() + require.NoError(t, err) + + test.TestClearEmptyWatchedAddresses(t, db) + }) +} diff --git a/statediff/indexer/database/sql/postgres/config.go b/statediff/indexer/database/sql/postgres/config.go new file mode 100644 index 000000000..b5cdc02ab --- /dev/null +++ b/statediff/indexer/database/sql/postgres/config.go @@ -0,0 +1,102 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres + +import ( + "fmt" + "strings" + "time" + + "github.com/ethereum/go-ethereum/statediff/indexer/shared" +) + +// DriverType to explicitly type the kind of sql driver we are using +type DriverType string + +const ( + PGX DriverType = "PGX" + SQLX DriverType = "SQLX" + Unknown DriverType = "Unknown" +) + +// ResolveDriverType resolves a DriverType from a provided string +func ResolveDriverType(str string) (DriverType, error) { + switch strings.ToLower(str) { + case "pgx", "pgxpool": + return PGX, nil + case "sqlx": + return SQLX, nil + default: + return Unknown, fmt.Errorf("unrecognized driver type string: %s", str) + } +} + +// DefaultConfig are default parameters for connecting to a Postgres sql +var DefaultConfig = Config{ + Hostname: "localhost", + Port: 8077, + DatabaseName: "vulcanize_testing", + Username: "vdbm", + Password: "password", +} + +// Config holds params for a Postgres db +type Config struct { + // conn string params + Hostname string + Port int + DatabaseName string + Username string + Password string + + // conn settings + MaxConns int + MaxIdle int + MinConns int + MaxConnIdleTime time.Duration + MaxConnLifetime time.Duration + ConnTimeout time.Duration + LogStatements bool + + // node info params + ID string + ClientName string + + // driver type + Driver DriverType + + // toggle on/off upserts + Upsert bool +} + +// Type satisfies interfaces.Config +func (c Config) Type() shared.DBType { + return shared.POSTGRES +} + +// DbConnectionString constructs and returns the connection string from the config +func (c Config) DbConnectionString() string { + if len(c.Username) > 0 && len(c.Password) > 0 { + return fmt.Sprintf("postgresql://%s:%s@%s:%d/%s?sslmode=disable", + c.Username, c.Password, c.Hostname, c.Port, c.DatabaseName) + } + if len(c.Username) > 0 && len(c.Password) == 0 { + return fmt.Sprintf("postgresql://%s@%s:%d/%s?sslmode=disable", + c.Username, c.Hostname, c.Port, c.DatabaseName) + } + return fmt.Sprintf("postgresql://%s:%d/%s?sslmode=disable", c.Hostname, c.Port, c.DatabaseName) +} diff --git a/statediff/indexer/database/sql/postgres/database.go b/statediff/indexer/database/sql/postgres/database.go new file mode 100644 index 000000000..27f89ab83 --- /dev/null +++ b/statediff/indexer/database/sql/postgres/database.go @@ -0,0 +1,123 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres + +import "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + +var _ sql.Database = &DB{} + +const ( + createNodeStm = `INSERT INTO nodes (genesis_block, network_id, node_id, client_name, chain_id) VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (node_id) DO NOTHING` +) + +// NewPostgresDB returns a postgres.DB using the provided driver +func NewPostgresDB(driver sql.Driver, upsert bool) *DB { + return &DB{upsert, driver} +} + +// DB implements sql.Database using a configured driver and Postgres statement syntax +type DB struct { + upsert bool + sql.Driver +} + +// InsertHeaderStm satisfies the sql.Statements interface +// Stm == Statement +func (db *DB) InsertHeaderStm() string { + if db.upsert { + return `INSERT INTO eth.header_cids (block_number, block_hash, parent_hash, cid, td, node_id, reward, state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated, coinbase) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) + ON CONFLICT (block_hash, block_number) DO UPDATE SET (parent_hash, cid, td, node_id, reward, state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated, coinbase) = ($3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, eth.header_cids.times_validated + 1, $16)` + } + return `INSERT INTO eth.header_cids (block_number, block_hash, parent_hash, cid, td, node_id, reward, state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated, coinbase) + VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) + ON CONFLICT (block_hash, block_number) DO NOTHING` +} + +// InsertUncleStm satisfies the sql.Statements interface +func (db *DB) InsertUncleStm() string { + return `INSERT INTO eth.uncle_cids (block_number, block_hash, header_id, parent_hash, cid, reward, mh_key) VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (block_hash, block_number) DO NOTHING` +} + +// InsertTxStm satisfies the sql.Statements interface +func (db *DB) InsertTxStm() string { + return `INSERT INTO eth.transaction_cids (block_number, header_id, tx_hash, cid, dst, src, index, mh_key, tx_data, tx_type, value) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) + ON CONFLICT (tx_hash, header_id, block_number) DO NOTHING` +} + +// InsertAccessListElementStm satisfies the sql.Statements interface +func (db *DB) InsertAccessListElementStm() string { + return `INSERT INTO eth.access_list_elements (block_number, tx_id, index, address, storage_keys) VALUES ($1, $2, $3, $4, $5) + ON CONFLICT (tx_id, index, block_number) DO NOTHING` +} + +// InsertRctStm satisfies the sql.Statements interface +func (db *DB) InsertRctStm() string { + return `INSERT INTO eth.receipt_cids (block_number, header_id, tx_id, leaf_cid, contract, contract_hash, leaf_mh_key, post_state, post_status, log_root) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) + ON CONFLICT (tx_id, header_id, block_number) DO NOTHING` +} + +// InsertLogStm satisfies the sql.Statements interface +func (db *DB) InsertLogStm() string { + return `INSERT INTO eth.log_cids (block_number, header_id, leaf_cid, leaf_mh_key, rct_id, address, index, topic0, topic1, topic2, topic3, log_data) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) + ON CONFLICT (rct_id, index, header_id, block_number) DO NOTHING` +} + +// InsertStateStm satisfies the sql.Statements interface +func (db *DB) InsertStateStm() string { + if db.upsert { + return `INSERT INTO eth.state_cids (block_number, header_id, state_leaf_key, cid, state_path, node_type, diff, mh_key) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (header_id, state_path, block_number) DO UPDATE SET (block_number, state_leaf_key, cid, node_type, diff, mh_key) = ($1, $3, $4, $6, $7, $8)` + } + return `INSERT INTO eth.state_cids (block_number, header_id, state_leaf_key, cid, state_path, node_type, diff, mh_key) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) + ON CONFLICT (header_id, state_path, block_number) DO NOTHING` +} + +// InsertAccountStm satisfies the sql.Statements interface +func (db *DB) InsertAccountStm() string { + return `INSERT INTO eth.state_accounts (block_number, header_id, state_path, balance, nonce, code_hash, storage_root) VALUES ($1, $2, $3, $4, $5, $6, $7) + ON CONFLICT (header_id, state_path, block_number) DO NOTHING` +} + +// InsertStorageStm satisfies the sql.Statements interface +func (db *DB) InsertStorageStm() string { + if db.upsert { + return `INSERT INTO eth.storage_cids (block_number, header_id, state_path, storage_leaf_key, cid, storage_path, node_type, diff, mh_key) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (header_id, state_path, storage_path, block_number) DO UPDATE SET (block_number, storage_leaf_key, cid, node_type, diff, mh_key) = ($1, $4, $5, $7, $8, $9)` + } + return `INSERT INTO eth.storage_cids (block_number, header_id, state_path, storage_leaf_key, cid, storage_path, node_type, diff, mh_key) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) + ON CONFLICT (header_id, state_path, storage_path, block_number) DO NOTHING` +} + +// InsertIPLDStm satisfies the sql.Statements interface +func (db *DB) InsertIPLDStm() string { + return `INSERT INTO public.blocks (block_number, key, data) VALUES ($1, $2, $3) ON CONFLICT DO NOTHING` +} + +// InsertIPLDsStm satisfies the sql.Statements interface +func (db *DB) InsertIPLDsStm() string { + return `INSERT INTO public.blocks (block_number, key, data) VALUES (unnest($1::BIGINT[]), unnest($2::TEXT[]), unnest($3::BYTEA[])) ON CONFLICT DO NOTHING` +} + +// InsertKnownGapsStm satisfies the sql.Statements interface +func (db *DB) InsertKnownGapsStm() string { + return `INSERT INTO eth_meta.known_gaps (starting_block_number, ending_block_number, checked_out, processing_key) VALUES ($1, $2, $3, $4) + ON CONFLICT (starting_block_number) DO UPDATE SET (ending_block_number, processing_key) = ($2, $4) + WHERE eth_meta.known_gaps.ending_block_number <= $2` +} diff --git a/statediff/indexer/database/sql/postgres/errors.go b/statediff/indexer/database/sql/postgres/errors.go new file mode 100644 index 000000000..effa74aa1 --- /dev/null +++ b/statediff/indexer/database/sql/postgres/errors.go @@ -0,0 +1,38 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres + +import ( + "fmt" +) + +const ( + DbConnectionFailedMsg = "db connection failed" + SettingNodeFailedMsg = "unable to set db node" +) + +func ErrDBConnectionFailed(connectErr error) error { + return formatError(DbConnectionFailedMsg, connectErr.Error()) +} + +func ErrUnableToSetNode(setErr error) error { + return formatError(SettingNodeFailedMsg, setErr.Error()) +} + +func formatError(msg, err string) error { + return fmt.Errorf("%s: %s", msg, err) +} diff --git a/statediff/indexer/database/sql/postgres/log_adapter.go b/statediff/indexer/database/sql/postgres/log_adapter.go new file mode 100644 index 000000000..c3ceead46 --- /dev/null +++ b/statediff/indexer/database/sql/postgres/log_adapter.go @@ -0,0 +1,61 @@ +// Copyright © 2023 Cerc + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres + +import ( + "context" + + "github.com/ethereum/go-ethereum/log" + "github.com/jackc/pgx/v4" +) + +type LogAdapter struct { + l log.Logger +} + +func NewLogAdapter(l log.Logger) *LogAdapter { + return &LogAdapter{l: l} +} + +func (l *LogAdapter) Log(ctx context.Context, level pgx.LogLevel, msg string, data map[string]interface{}) { + var logger log.Logger + if data != nil { + var args = make([]interface{}, 0) + for key, value := range data { + if value != nil { + args = append(args, key, value) + } + } + logger = l.l.New(args...) + } else { + logger = l.l + } + + switch level { + case pgx.LogLevelTrace: + logger.Trace(msg) + case pgx.LogLevelDebug: + logger.Debug(msg) + case pgx.LogLevelInfo: + logger.Info(msg) + case pgx.LogLevelWarn: + logger.Warn(msg) + case pgx.LogLevelError: + logger.Error(msg) + default: + logger.New("INVALID_PGX_LOG_LEVEL", level).Error(msg) + } +} diff --git a/statediff/indexer/database/sql/postgres/pgx.go b/statediff/indexer/database/sql/postgres/pgx.go new file mode 100644 index 000000000..6b75559df --- /dev/null +++ b/statediff/indexer/database/sql/postgres/pgx.go @@ -0,0 +1,241 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres + +import ( + "context" + "time" + + "github.com/ethereum/go-ethereum/log" + + "github.com/georgysavva/scany/pgxscan" + "github.com/jackc/pgconn" + "github.com/jackc/pgx/v4" + "github.com/jackc/pgx/v4/pgxpool" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/node" +) + +// PGXDriver driver, implements sql.Driver +type PGXDriver struct { + ctx context.Context + pool *pgxpool.Pool + nodeInfo node.Info + nodeID string +} + +// NewPGXDriver returns a new pgx driver +// it initializes the connection pool and creates the node info table +func NewPGXDriver(ctx context.Context, config Config, node node.Info) (*PGXDriver, error) { + pgConf, err := MakeConfig(config) + if err != nil { + return nil, err + } + dbPool, err := pgxpool.ConnectConfig(ctx, pgConf) + if err != nil { + return nil, ErrDBConnectionFailed(err) + } + pg := &PGXDriver{ctx: ctx, pool: dbPool, nodeInfo: node} + nodeErr := pg.createNode() + if nodeErr != nil { + return &PGXDriver{}, ErrUnableToSetNode(nodeErr) + } + return pg, nil +} + +// MakeConfig creates a pgxpool.Config from the provided Config +func MakeConfig(config Config) (*pgxpool.Config, error) { + conf, err := pgxpool.ParseConfig("") + if err != nil { + return nil, err + } + + //conf.ConnConfig.BuildStatementCache = nil + conf.ConnConfig.Config.Host = config.Hostname + conf.ConnConfig.Config.Port = uint16(config.Port) + conf.ConnConfig.Config.Database = config.DatabaseName + conf.ConnConfig.Config.User = config.Username + conf.ConnConfig.Config.Password = config.Password + + if config.ConnTimeout != 0 { + conf.ConnConfig.Config.ConnectTimeout = config.ConnTimeout + } + if config.MaxConns != 0 { + conf.MaxConns = int32(config.MaxConns) + } + if config.MinConns != 0 { + conf.MinConns = int32(config.MinConns) + } + if config.MaxConnLifetime != 0 { + conf.MaxConnLifetime = config.MaxConnLifetime + } + if config.MaxConnIdleTime != 0 { + conf.MaxConnIdleTime = config.MaxConnIdleTime + } + + if config.LogStatements { + conf.ConnConfig.Logger = NewLogAdapter(log.New()) + } + + return conf, nil +} + +func (pgx *PGXDriver) createNode() error { + _, err := pgx.pool.Exec( + pgx.ctx, + createNodeStm, + pgx.nodeInfo.GenesisBlock, pgx.nodeInfo.NetworkID, + pgx.nodeInfo.ID, pgx.nodeInfo.ClientName, + pgx.nodeInfo.ChainID) + if err != nil { + return ErrUnableToSetNode(err) + } + pgx.nodeID = pgx.nodeInfo.ID + return nil +} + +// QueryRow satisfies sql.Database +func (pgx *PGXDriver) QueryRow(ctx context.Context, sql string, args ...interface{}) sql.ScannableRow { + return pgx.pool.QueryRow(ctx, sql, args...) +} + +// Exec satisfies sql.Database +func (pgx *PGXDriver) Exec(ctx context.Context, sql string, args ...interface{}) (sql.Result, error) { + res, err := pgx.pool.Exec(ctx, sql, args...) + return resultWrapper{ct: res}, err +} + +// Select satisfies sql.Database +func (pgx *PGXDriver) Select(ctx context.Context, dest interface{}, query string, args ...interface{}) error { + return pgxscan.Select(ctx, pgx.pool, dest, query, args...) +} + +// Get satisfies sql.Database +func (pgx *PGXDriver) Get(ctx context.Context, dest interface{}, query string, args ...interface{}) error { + return pgxscan.Get(ctx, pgx.pool, dest, query, args...) +} + +// Begin satisfies sql.Database +func (pgx *PGXDriver) Begin(ctx context.Context) (sql.Tx, error) { + tx, err := pgx.pool.Begin(ctx) + if err != nil { + return nil, err + } + return pgxTxWrapper{tx: tx}, nil +} + +func (pgx *PGXDriver) Stats() metrics.DbStats { + stats := pgx.pool.Stat() + return pgxStatsWrapper{stats: stats} +} + +// NodeID satisfies sql.Database +func (pgx *PGXDriver) NodeID() string { + return pgx.nodeID +} + +// Close satisfies sql.Database/io.Closer +func (pgx *PGXDriver) Close() error { + pgx.pool.Close() + return nil +} + +// Context satisfies sql.Database +func (pgx *PGXDriver) Context() context.Context { + return pgx.ctx +} + +type resultWrapper struct { + ct pgconn.CommandTag +} + +// RowsAffected satisfies sql.Result +func (r resultWrapper) RowsAffected() (int64, error) { + return r.ct.RowsAffected(), nil +} + +type pgxStatsWrapper struct { + stats *pgxpool.Stat +} + +// MaxOpen satisfies metrics.DbStats +func (s pgxStatsWrapper) MaxOpen() int64 { + return int64(s.stats.MaxConns()) +} + +// Open satisfies metrics.DbStats +func (s pgxStatsWrapper) Open() int64 { + return int64(s.stats.TotalConns()) +} + +// InUse satisfies metrics.DbStats +func (s pgxStatsWrapper) InUse() int64 { + return int64(s.stats.AcquiredConns()) +} + +// Idle satisfies metrics.DbStats +func (s pgxStatsWrapper) Idle() int64 { + return int64(s.stats.IdleConns()) +} + +// WaitCount satisfies metrics.DbStats +func (s pgxStatsWrapper) WaitCount() int64 { + return s.stats.EmptyAcquireCount() +} + +// WaitDuration satisfies metrics.DbStats +func (s pgxStatsWrapper) WaitDuration() time.Duration { + return s.stats.AcquireDuration() +} + +// MaxIdleClosed satisfies metrics.DbStats +func (s pgxStatsWrapper) MaxIdleClosed() int64 { + // this stat isn't supported by pgxpool, but we don't want to panic + return 0 +} + +// MaxLifetimeClosed satisfies metrics.DbStats +func (s pgxStatsWrapper) MaxLifetimeClosed() int64 { + return s.stats.CanceledAcquireCount() +} + +type pgxTxWrapper struct { + tx pgx.Tx +} + +// QueryRow satisfies sql.Tx +func (t pgxTxWrapper) QueryRow(ctx context.Context, sql string, args ...interface{}) sql.ScannableRow { + return t.tx.QueryRow(ctx, sql, args...) +} + +// Exec satisfies sql.Tx +func (t pgxTxWrapper) Exec(ctx context.Context, sql string, args ...interface{}) (sql.Result, error) { + res, err := t.tx.Exec(ctx, sql, args...) + return resultWrapper{ct: res}, err +} + +// Commit satisfies sql.Tx +func (t pgxTxWrapper) Commit(ctx context.Context) error { + return t.tx.Commit(ctx) +} + +// Rollback satisfies sql.Tx +func (t pgxTxWrapper) Rollback(ctx context.Context) error { + return t.tx.Rollback(ctx) +} diff --git a/statediff/indexer/database/sql/postgres/pgx_test.go b/statediff/indexer/database/sql/postgres/pgx_test.go new file mode 100644 index 000000000..043112e8d --- /dev/null +++ b/statediff/indexer/database/sql/postgres/pgx_test.go @@ -0,0 +1,121 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres_test + +import ( + "context" + "fmt" + "math/big" + "strings" + "testing" + + "github.com/jackc/pgx/v4/pgxpool" + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/node" +) + +var ( + pgConfig, _ = postgres.MakeConfig(postgres.DefaultConfig) + ctx = context.Background() +) + +func expectContainsSubstring(t *testing.T, full string, sub string) { + if !strings.Contains(full, sub) { + t.Fatalf("Expected \"%v\" to contain substring \"%v\"\n", full, sub) + } +} + +func TestPostgresPGX(t *testing.T) { + t.Run("connects to the sql", func(t *testing.T) { + dbPool, err := pgxpool.ConnectConfig(context.Background(), pgConfig) + if err != nil { + t.Fatalf("failed to connect to db with connection string: %s err: %v", pgConfig.ConnString(), err) + } + if dbPool == nil { + t.Fatal("DB pool is nil") + } + dbPool.Close() + }) + + t.Run("serializes big.Int to db", func(t *testing.T) { + // postgres driver doesn't support go big.Int type + // various casts in golang uint64, int64, overflow for + // transaction value (in wei) even though + // postgres numeric can handle an arbitrary + // sized int, so use string representation of big.Int + // and cast on insert + + dbPool, err := pgxpool.ConnectConfig(context.Background(), pgConfig) + if err != nil { + t.Fatalf("failed to connect to db with connection string: %s err: %v", pgConfig.ConnString(), err) + } + defer dbPool.Close() + + bi := new(big.Int) + bi.SetString("34940183920000000000", 10) + require.Equal(t, "34940183920000000000", bi.String()) + + defer dbPool.Exec(ctx, `DROP TABLE IF EXISTS example`) + _, err = dbPool.Exec(ctx, "CREATE TABLE example ( id INTEGER, data NUMERIC )") + if err != nil { + t.Fatal(err) + } + + sqlStatement := ` + INSERT INTO example (id, data) + VALUES (1, cast($1 AS NUMERIC))` + _, err = dbPool.Exec(ctx, sqlStatement, bi.String()) + if err != nil { + t.Fatal(err) + } + + var data string + err = dbPool.QueryRow(ctx, `SELECT cast(data AS TEXT) FROM example WHERE id = 1`).Scan(&data) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, data, bi.String()) + actual := new(big.Int) + actual.SetString(data, 10) + require.Equal(t, bi, actual) + }) + + t.Run("throws error when can't connect to the database", func(t *testing.T) { + goodInfo := node.Info{GenesisBlock: "GENESIS", NetworkID: "1", ID: "x123", ClientName: "geth"} + _, err := postgres.NewPGXDriver(ctx, postgres.Config{}, goodInfo) + if err == nil { + t.Fatal("Expected an error") + } + + expectContainsSubstring(t, err.Error(), postgres.DbConnectionFailedMsg) + }) + + t.Run("throws error when can't create node", func(t *testing.T) { + badHash := fmt.Sprintf("x %s", strings.Repeat("1", 100)) + badInfo := node.Info{GenesisBlock: badHash, NetworkID: "1", ID: "x123", ClientName: "geth"} + + _, err := postgres.NewPGXDriver(ctx, postgres.DefaultConfig, badInfo) + if err == nil { + t.Fatal("Expected an error") + } + + expectContainsSubstring(t, err.Error(), postgres.SettingNodeFailedMsg) + }) +} diff --git a/statediff/indexer/database/sql/postgres/postgres_suite_test.go b/statediff/indexer/database/sql/postgres/postgres_suite_test.go new file mode 100644 index 000000000..a020e088e --- /dev/null +++ b/statediff/indexer/database/sql/postgres/postgres_suite_test.go @@ -0,0 +1,33 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres_test + +import ( + "fmt" + "os" + + "github.com/ethereum/go-ethereum/log" +) + +func init() { + if os.Getenv("MODE") != "statediff" { + fmt.Println("Skipping statediff test") + os.Exit(0) + } + + log.Root().SetHandler(log.DiscardHandler()) +} diff --git a/statediff/indexer/database/sql/postgres/sqlx.go b/statediff/indexer/database/sql/postgres/sqlx.go new file mode 100644 index 000000000..529e7f7c8 --- /dev/null +++ b/statediff/indexer/database/sql/postgres/sqlx.go @@ -0,0 +1,188 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres + +import ( + "context" + coresql "database/sql" + "time" + + "github.com/jmoiron/sqlx" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/node" +) + +// SQLXDriver driver, implements sql.Driver +type SQLXDriver struct { + ctx context.Context + db *sqlx.DB + nodeInfo node.Info + nodeID string +} + +// NewSQLXDriver returns a new sqlx driver for Postgres +// it initializes the connection pool and creates the node info table +func NewSQLXDriver(ctx context.Context, config Config, node node.Info) (*SQLXDriver, error) { + db, err := sqlx.ConnectContext(ctx, "postgres", config.DbConnectionString()) + if err != nil { + return &SQLXDriver{}, ErrDBConnectionFailed(err) + } + if config.MaxConns > 0 { + db.SetMaxOpenConns(config.MaxConns) + } + if config.MaxConnLifetime > 0 { + db.SetConnMaxLifetime(config.MaxConnLifetime) + } + db.SetMaxIdleConns(config.MaxIdle) + driver := &SQLXDriver{ctx: ctx, db: db, nodeInfo: node} + if err := driver.createNode(); err != nil { + return &SQLXDriver{}, ErrUnableToSetNode(err) + } + return driver, nil +} + +func (driver *SQLXDriver) createNode() error { + _, err := driver.db.Exec( + createNodeStm, + driver.nodeInfo.GenesisBlock, driver.nodeInfo.NetworkID, + driver.nodeInfo.ID, driver.nodeInfo.ClientName, + driver.nodeInfo.ChainID) + if err != nil { + return ErrUnableToSetNode(err) + } + driver.nodeID = driver.nodeInfo.ID + return nil +} + +// QueryRow satisfies sql.Database +func (driver *SQLXDriver) QueryRow(_ context.Context, sql string, args ...interface{}) sql.ScannableRow { + return driver.db.QueryRowx(sql, args...) +} + +// Exec satisfies sql.Database +func (driver *SQLXDriver) Exec(_ context.Context, sql string, args ...interface{}) (sql.Result, error) { + return driver.db.Exec(sql, args...) +} + +// Select satisfies sql.Database +func (driver *SQLXDriver) Select(_ context.Context, dest interface{}, query string, args ...interface{}) error { + return driver.db.Select(dest, query, args...) +} + +// Get satisfies sql.Database +func (driver *SQLXDriver) Get(_ context.Context, dest interface{}, query string, args ...interface{}) error { + return driver.db.Get(dest, query, args...) +} + +// Begin satisfies sql.Database +func (driver *SQLXDriver) Begin(_ context.Context) (sql.Tx, error) { + tx, err := driver.db.Beginx() + if err != nil { + return nil, err + } + return sqlxTxWrapper{tx: tx}, nil +} + +func (driver *SQLXDriver) Stats() metrics.DbStats { + stats := driver.db.Stats() + return sqlxStatsWrapper{stats: stats} +} + +// NodeID satisfies sql.Database +func (driver *SQLXDriver) NodeID() string { + return driver.nodeID +} + +// Close satisfies sql.Database/io.Closer +func (driver *SQLXDriver) Close() error { + return driver.db.Close() +} + +// Context satisfies sql.Database +func (driver *SQLXDriver) Context() context.Context { + return driver.ctx +} + +type sqlxStatsWrapper struct { + stats coresql.DBStats +} + +// MaxOpen satisfies metrics.DbStats +func (s sqlxStatsWrapper) MaxOpen() int64 { + return int64(s.stats.MaxOpenConnections) +} + +// Open satisfies metrics.DbStats +func (s sqlxStatsWrapper) Open() int64 { + return int64(s.stats.OpenConnections) +} + +// InUse satisfies metrics.DbStats +func (s sqlxStatsWrapper) InUse() int64 { + return int64(s.stats.InUse) +} + +// Idle satisfies metrics.DbStats +func (s sqlxStatsWrapper) Idle() int64 { + return int64(s.stats.Idle) +} + +// WaitCount satisfies metrics.DbStats +func (s sqlxStatsWrapper) WaitCount() int64 { + return s.stats.WaitCount +} + +// WaitDuration satisfies metrics.DbStats +func (s sqlxStatsWrapper) WaitDuration() time.Duration { + return s.stats.WaitDuration +} + +// MaxIdleClosed satisfies metrics.DbStats +func (s sqlxStatsWrapper) MaxIdleClosed() int64 { + return s.stats.MaxIdleClosed +} + +// MaxLifetimeClosed satisfies metrics.DbStats +func (s sqlxStatsWrapper) MaxLifetimeClosed() int64 { + return s.stats.MaxLifetimeClosed +} + +type sqlxTxWrapper struct { + tx *sqlx.Tx +} + +// QueryRow satisfies sql.Tx +func (t sqlxTxWrapper) QueryRow(ctx context.Context, sql string, args ...interface{}) sql.ScannableRow { + return t.tx.QueryRowx(sql, args...) +} + +// Exec satisfies sql.Tx +func (t sqlxTxWrapper) Exec(ctx context.Context, sql string, args ...interface{}) (sql.Result, error) { + return t.tx.Exec(sql, args...) +} + +// Commit satisfies sql.Tx +func (t sqlxTxWrapper) Commit(ctx context.Context) error { + return t.tx.Commit() +} + +// Rollback satisfies sql.Tx +func (t sqlxTxWrapper) Rollback(ctx context.Context) error { + return t.tx.Rollback() +} diff --git a/statediff/indexer/database/sql/postgres/sqlx_test.go b/statediff/indexer/database/sql/postgres/sqlx_test.go new file mode 100644 index 000000000..40b976314 --- /dev/null +++ b/statediff/indexer/database/sql/postgres/sqlx_test.go @@ -0,0 +1,119 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres_test + +import ( + "fmt" + "math/big" + "strings" + "testing" + + "github.com/jmoiron/sqlx" + _ "github.com/lib/pq" + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/node" +) + +func TestPostgresSQLX(t *testing.T) { + var sqlxdb *sqlx.DB + + t.Run("connects to the database", func(t *testing.T) { + var err error + connStr := postgres.DefaultConfig.DbConnectionString() + + sqlxdb, err = sqlx.Connect("postgres", connStr) + if err != nil { + t.Fatalf("failed to connect to db with connection string: %s err: %v", connStr, err) + } + if sqlxdb == nil { + t.Fatal("DB is nil") + } + err = sqlxdb.Close() + if err != nil { + t.Fatal(err) + } + }) + + t.Run("serializes big.Int to db", func(t *testing.T) { + // postgres driver doesn't support go big.Int type + // various casts in golang uint64, int64, overflow for + // transaction value (in wei) even though + // postgres numeric can handle an arbitrary + // sized int, so use string representation of big.Int + // and cast on insert + + connStr := postgres.DefaultConfig.DbConnectionString() + db, err := sqlx.Connect("postgres", connStr) + if err != nil { + t.Fatal(err) + } + defer db.Close() + + bi := new(big.Int) + bi.SetString("34940183920000000000", 10) + require.Equal(t, "34940183920000000000", bi.String()) + + defer db.Exec(`DROP TABLE IF EXISTS example`) + _, err = db.Exec("CREATE TABLE example ( id INTEGER, data NUMERIC )") + if err != nil { + t.Fatal(err) + } + + sqlStatement := ` + INSERT INTO example (id, data) + VALUES (1, cast($1 AS NUMERIC))` + _, err = db.Exec(sqlStatement, bi.String()) + if err != nil { + t.Fatal(err) + } + + var data string + err = db.QueryRow(`SELECT data FROM example WHERE id = 1`).Scan(&data) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, data, bi.String()) + actual := new(big.Int) + actual.SetString(data, 10) + require.Equal(t, bi, actual) + }) + + t.Run("throws error when can't connect to the database", func(t *testing.T) { + goodInfo := node.Info{GenesisBlock: "GENESIS", NetworkID: "1", ID: "x123", ClientName: "geth"} + _, err := postgres.NewSQLXDriver(ctx, postgres.Config{}, goodInfo) + if err == nil { + t.Fatal("Expected an error") + } + + expectContainsSubstring(t, err.Error(), postgres.DbConnectionFailedMsg) + }) + + t.Run("throws error when can't create node", func(t *testing.T) { + badHash := fmt.Sprintf("x %s", strings.Repeat("1", 100)) + badInfo := node.Info{GenesisBlock: badHash, NetworkID: "1", ID: "x123", ClientName: "geth"} + + _, err := postgres.NewSQLXDriver(ctx, postgres.DefaultConfig, badInfo) + if err == nil { + t.Fatal("Expected an error") + } + + expectContainsSubstring(t, err.Error(), postgres.SettingNodeFailedMsg) + }) +} diff --git a/statediff/indexer/database/sql/postgres/test_helpers.go b/statediff/indexer/database/sql/postgres/test_helpers.go new file mode 100644 index 000000000..f8311b413 --- /dev/null +++ b/statediff/indexer/database/sql/postgres/test_helpers.go @@ -0,0 +1,44 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package postgres + +import ( + "context" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/node" +) + +// SetupSQLXDB is used to setup a sqlx db for tests +func SetupSQLXDB() (sql.Database, error) { + conf := DefaultConfig + conf.MaxIdle = 0 + driver, err := NewSQLXDriver(context.Background(), conf, node.Info{}) + if err != nil { + return nil, err + } + return NewPostgresDB(driver, false), nil +} + +// SetupPGXDB is used to setup a pgx db for tests +func SetupPGXDB() (sql.Database, error) { + driver, err := NewPGXDriver(context.Background(), DefaultConfig, node.Info{}) + if err != nil { + return nil, err + } + return NewPostgresDB(driver, false), nil +} diff --git a/statediff/indexer/database/sql/sqlx_indexer_legacy_test.go b/statediff/indexer/database/sql/sqlx_indexer_legacy_test.go new file mode 100644 index 000000000..4a07b8a0e --- /dev/null +++ b/statediff/indexer/database/sql/sqlx_indexer_legacy_test.go @@ -0,0 +1,52 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package sql_test + +import ( + "context" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/test" +) + +func setupLegacySQLXIndexer(t *testing.T) { + db, err = postgres.SetupSQLXDB() + if err != nil { + t.Fatal(err) + } + ind, err = sql.NewStateDiffIndexer(context.Background(), test.LegacyConfig, db) + require.NoError(t, err) +} + +func setupLegacySQLX(t *testing.T) { + setupLegacySQLXIndexer(t) + test.SetupLegacyTestData(t, ind) +} + +func TestLegacySQLXIndexer(t *testing.T) { + t.Run("Publish and index header IPLDs", func(t *testing.T) { + setupLegacySQLX(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestLegacyIndexer(t, db) + }) +} diff --git a/statediff/indexer/database/sql/sqlx_indexer_test.go b/statediff/indexer/database/sql/sqlx_indexer_test.go new file mode 100644 index 000000000..fa8844655 --- /dev/null +++ b/statediff/indexer/database/sql/sqlx_indexer_test.go @@ -0,0 +1,227 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package sql_test + +import ( + "context" + "math/big" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql/postgres" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" + "github.com/ethereum/go-ethereum/statediff/indexer/test" +) + +func setupSQLXIndexer(t *testing.T) { + db, err = postgres.SetupSQLXDB() + if err != nil { + t.Fatal(err) + } + ind, err = sql.NewStateDiffIndexer(context.Background(), mocks.TestConfig, db) + require.NoError(t, err) +} + +func setupSQLX(t *testing.T) { + setupSQLXIndexer(t) + test.SetupTestData(t, ind) +} + +func setupSQLXNonCanonical(t *testing.T) { + setupSQLXIndexer(t) + test.SetupTestDataNonCanonical(t, ind) +} + +// Test indexer for a canonical block +func TestSQLXIndexer(t *testing.T) { + t.Run("Publish and index header IPLDs in a single tx", func(t *testing.T) { + setupSQLX(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexHeaderIPLDs(t, db) + }) + + t.Run("Publish and index transaction IPLDs in a single tx", func(t *testing.T) { + setupSQLX(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexTransactionIPLDs(t, db) + }) + + t.Run("Publish and index log IPLDs for multiple receipt of a specific block", func(t *testing.T) { + setupSQLX(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexLogIPLDs(t, db) + }) + + t.Run("Publish and index receipt IPLDs in a single tx", func(t *testing.T) { + setupSQLX(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexReceiptIPLDs(t, db) + }) + + t.Run("Publish and index state IPLDs in a single tx", func(t *testing.T) { + setupSQLX(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexStateIPLDs(t, db) + }) + + t.Run("Publish and index storage IPLDs in a single tx", func(t *testing.T) { + setupSQLX(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexStorageIPLDs(t, db) + }) +} + +// Test indexer for a canonical + a non-canonical block at London height + a non-canonical block at London height + 1 +func TestSQLXIndexerNonCanonical(t *testing.T) { + t.Run("Publish and index header", func(t *testing.T) { + setupSQLXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexHeaderNonCanonical(t, db) + }) + + t.Run("Publish and index transactions", func(t *testing.T) { + setupSQLXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexTransactionsNonCanonical(t, db) + }) + + t.Run("Publish and index receipts", func(t *testing.T) { + setupSQLXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexReceiptsNonCanonical(t, db) + }) + + t.Run("Publish and index logs", func(t *testing.T) { + setupSQLXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexLogsNonCanonical(t, db) + }) + + t.Run("Publish and index state nodes", func(t *testing.T) { + setupSQLXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexStateNonCanonical(t, db) + }) + + t.Run("Publish and index storage nodes", func(t *testing.T) { + setupSQLXNonCanonical(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + test.TestPublishAndIndexStorageNonCanonical(t, db) + }) +} + +func TestSQLXWatchAddressMethods(t *testing.T) { + setupSQLXIndexer(t) + defer tearDown(t) + defer checkTxClosure(t, 0, 0, 0) + + t.Run("Load watched addresses (empty table)", func(t *testing.T) { + test.TestLoadEmptyWatchedAddresses(t, ind) + }) + + t.Run("Insert watched addresses", func(t *testing.T) { + args := mocks.GetInsertWatchedAddressesArgs() + err = ind.InsertWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt1))) + require.NoError(t, err) + + test.TestInsertWatchedAddresses(t, db) + }) + + t.Run("Insert watched addresses (some already watched)", func(t *testing.T) { + args := mocks.GetInsertAlreadyWatchedAddressesArgs() + err = ind.InsertWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt2))) + require.NoError(t, err) + + test.TestInsertAlreadyWatchedAddresses(t, db) + }) + + t.Run("Remove watched addresses", func(t *testing.T) { + args := mocks.GetRemoveWatchedAddressesArgs() + err = ind.RemoveWatchedAddresses(args) + require.NoError(t, err) + + test.TestRemoveWatchedAddresses(t, db) + }) + + t.Run("Remove watched addresses (some non-watched)", func(t *testing.T) { + args := mocks.GetRemoveNonWatchedAddressesArgs() + err = ind.RemoveWatchedAddresses(args) + require.NoError(t, err) + + test.TestRemoveNonWatchedAddresses(t, db) + }) + + t.Run("Set watched addresses", func(t *testing.T) { + args := mocks.GetSetWatchedAddressesArgs() + err = ind.SetWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt2))) + require.NoError(t, err) + + test.TestSetWatchedAddresses(t, db) + }) + + t.Run("Set watched addresses (some already watched)", func(t *testing.T) { + args := mocks.GetSetAlreadyWatchedAddressesArgs() + err = ind.SetWatchedAddresses(args, big.NewInt(int64(mocks.WatchedAt3))) + require.NoError(t, err) + + test.TestSetAlreadyWatchedAddresses(t, db) + }) + + t.Run("Load watched addresses", func(t *testing.T) { + test.TestLoadWatchedAddresses(t, ind) + }) + + t.Run("Clear watched addresses", func(t *testing.T) { + err = ind.ClearWatchedAddresses() + require.NoError(t, err) + + test.TestClearWatchedAddresses(t, db) + }) + + t.Run("Clear watched addresses (empty table)", func(t *testing.T) { + err = ind.ClearWatchedAddresses() + require.NoError(t, err) + + test.TestClearEmptyWatchedAddresses(t, db) + }) +} diff --git a/statediff/indexer/database/sql/writer.go b/statediff/indexer/database/sql/writer.go new file mode 100644 index 000000000..36b0703dc --- /dev/null +++ b/statediff/indexer/database/sql/writer.go @@ -0,0 +1,203 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package sql + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/statediff/indexer/models" +) + +var ( + nullHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000") +) + +// Writer handles processing and writing of indexed IPLD objects to Postgres +type Writer struct { + db Database +} + +// NewWriter creates a new pointer to a Writer +func NewWriter(db Database) *Writer { + return &Writer{ + db: db, + } +} + +// Close satisfies io.Closer +func (w *Writer) Close() error { + return w.db.Close() +} + +/* +INSERT INTO eth.header_cids (block_number, block_hash, parent_hash, cid, td, node_id, reward, state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated, coinbase) +VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16) +ON CONFLICT (block_hash, block_number) DO UPDATE SET (block_number, parent_hash, cid, td, node_id, reward, state_root, tx_root, receipt_root, uncle_root, bloom, timestamp, mh_key, times_validated, coinbase) = ($1, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, eth.header_cids.times_validated + 1, $16) +*/ +func (w *Writer) upsertHeaderCID(tx Tx, header models.HeaderModel) error { + _, err := tx.Exec(w.db.Context(), w.db.InsertHeaderStm(), + header.BlockNumber, header.BlockHash, header.ParentHash, header.CID, header.TotalDifficulty, w.db.NodeID(), + header.Reward, header.StateRoot, header.TxRoot, header.RctRoot, header.UncleRoot, header.Bloom, + header.Timestamp, header.MhKey, 1, header.Coinbase) + if err != nil { + return insertError{"eth.header_cids", err, w.db.InsertHeaderStm(), header} + } + metrics.IndexerMetrics.BlocksCounter.Inc(1) + return nil +} + +/* +INSERT INTO eth.uncle_cids (block_number, block_hash, header_id, parent_hash, cid, reward, mh_key) VALUES ($1, $2, $3, $4, $5, $6, $7) +ON CONFLICT (block_hash, block_number) DO NOTHING +*/ +func (w *Writer) upsertUncleCID(tx Tx, uncle models.UncleModel) error { + _, err := tx.Exec(w.db.Context(), w.db.InsertUncleStm(), + uncle.BlockNumber, uncle.BlockHash, uncle.HeaderID, uncle.ParentHash, uncle.CID, uncle.Reward, uncle.MhKey) + if err != nil { + return insertError{"eth.uncle_cids", err, w.db.InsertUncleStm(), uncle} + } + return nil +} + +/* +INSERT INTO eth.transaction_cids (block_number, header_id, tx_hash, cid, dst, src, index, mh_key, tx_data, tx_type, value) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) +ON CONFLICT (tx_hash, header_id, block_number) DO NOTHING +*/ +func (w *Writer) upsertTransactionCID(tx Tx, transaction models.TxModel) error { + _, err := tx.Exec(w.db.Context(), w.db.InsertTxStm(), + transaction.BlockNumber, transaction.HeaderID, transaction.TxHash, transaction.CID, transaction.Dst, transaction.Src, + transaction.Index, transaction.MhKey, transaction.Data, transaction.Type, transaction.Value) + if err != nil { + return insertError{"eth.transaction_cids", err, w.db.InsertTxStm(), transaction} + } + metrics.IndexerMetrics.TransactionsCounter.Inc(1) + return nil +} + +/* +INSERT INTO eth.access_list_elements (block_number, tx_id, index, address, storage_keys) VALUES ($1, $2, $3, $4, $5) +ON CONFLICT (tx_id, index, block_number) DO NOTHING +*/ +func (w *Writer) upsertAccessListElement(tx Tx, accessListElement models.AccessListElementModel) error { + _, err := tx.Exec(w.db.Context(), w.db.InsertAccessListElementStm(), + accessListElement.BlockNumber, accessListElement.TxID, accessListElement.Index, accessListElement.Address, + accessListElement.StorageKeys) + if err != nil { + return insertError{"eth.access_list_elements", err, w.db.InsertAccessListElementStm(), accessListElement} + } + metrics.IndexerMetrics.AccessListEntriesCounter.Inc(1) + return nil +} + +/* +INSERT INTO eth.receipt_cids (block_number, header_id, tx_id, leaf_cid, contract, contract_hash, leaf_mh_key, post_state, post_status, log_root) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10) +ON CONFLICT (tx_id, header_id, block_number) DO NOTHING +*/ +func (w *Writer) upsertReceiptCID(tx Tx, rct *models.ReceiptModel) error { + _, err := tx.Exec(w.db.Context(), w.db.InsertRctStm(), + rct.BlockNumber, rct.HeaderID, rct.TxID, rct.LeafCID, rct.Contract, rct.ContractHash, rct.LeafMhKey, rct.PostState, + rct.PostStatus, rct.LogRoot) + if err != nil { + return insertError{"eth.receipt_cids", err, w.db.InsertRctStm(), *rct} + } + metrics.IndexerMetrics.ReceiptsCounter.Inc(1) + return nil +} + +/* +INSERT INTO eth.log_cids (block_number, header_id, leaf_cid, leaf_mh_key, rct_id, address, index, topic0, topic1, topic2, topic3, log_data) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) +ON CONFLICT (rct_id, index, header_id, block_number) DO NOTHING +*/ +func (w *Writer) upsertLogCID(tx Tx, logs []*models.LogsModel) error { + for _, log := range logs { + _, err := tx.Exec(w.db.Context(), w.db.InsertLogStm(), + log.BlockNumber, log.HeaderID, log.LeafCID, log.LeafMhKey, log.ReceiptID, log.Address, log.Index, log.Topic0, log.Topic1, + log.Topic2, log.Topic3, log.Data) + if err != nil { + return insertError{"eth.log_cids", err, w.db.InsertLogStm(), *log} + } + metrics.IndexerMetrics.LogsCounter.Inc(1) + } + return nil +} + +/* +INSERT INTO eth.state_cids (block_number, header_id, state_leaf_key, cid, state_path, node_type, diff, mh_key) VALUES ($1, $2, $3, $4, $5, $6, $7, $8) +ON CONFLICT (header_id, state_path, block_number) DO UPDATE SET (block_number, state_leaf_key, cid, node_type, diff, mh_key) = ($1 $3, $4, $6, $7, $8) +*/ +func (w *Writer) upsertStateCID(tx Tx, stateNode models.StateNodeModel) error { + var stateKey string + if stateNode.StateKey != nullHash.String() { + stateKey = stateNode.StateKey + } + _, err := tx.Exec(w.db.Context(), w.db.InsertStateStm(), + stateNode.BlockNumber, stateNode.HeaderID, stateKey, stateNode.CID, stateNode.Path, stateNode.NodeType, true, + stateNode.MhKey) + if err != nil { + return insertError{"eth.state_cids", err, w.db.InsertStateStm(), stateNode} + } + return nil +} + +/* +INSERT INTO eth.state_accounts (block_number, header_id, state_path, balance, nonce, code_hash, storage_root) VALUES ($1, $2, $3, $4, $5, $6, $7) +ON CONFLICT (header_id, state_path, block_number) DO NOTHING +*/ +func (w *Writer) upsertStateAccount(tx Tx, stateAccount models.StateAccountModel) error { + _, err := tx.Exec(w.db.Context(), w.db.InsertAccountStm(), + stateAccount.BlockNumber, stateAccount.HeaderID, stateAccount.StatePath, stateAccount.Balance, + stateAccount.Nonce, stateAccount.CodeHash, stateAccount.StorageRoot) + if err != nil { + return insertError{"eth.state_accounts", err, w.db.InsertAccountStm(), stateAccount} + } + return nil +} + +/* +INSERT INTO eth.storage_cids (block_number, header_id, state_path, storage_leaf_key, cid, storage_path, node_type, diff, mh_key) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9) +ON CONFLICT (header_id, state_path, storage_path, block_number) DO UPDATE SET (block_number, storage_leaf_key, cid, node_type, diff, mh_key) = ($1, $4, $5, $7, $8, $9) +*/ +func (w *Writer) upsertStorageCID(tx Tx, storageCID models.StorageNodeModel) error { + var storageKey string + if storageCID.StorageKey != nullHash.String() { + storageKey = storageCID.StorageKey + } + _, err := tx.Exec(w.db.Context(), w.db.InsertStorageStm(), + storageCID.BlockNumber, storageCID.HeaderID, storageCID.StatePath, storageKey, storageCID.CID, storageCID.Path, + storageCID.NodeType, true, storageCID.MhKey) + if err != nil { + return insertError{"eth.storage_cids", err, w.db.InsertStorageStm(), storageCID} + } + return nil +} + +type insertError struct { + table string + err error + stmt string + arguments interface{} +} + +var _ error = insertError{} + +func (dbe insertError) Error() string { + return fmt.Sprintf("error inserting %s entry: %v\r\nstatement: %s\r\narguments: %+v", + dbe.table, dbe.err, dbe.stmt, dbe.arguments) +} diff --git a/statediff/indexer/interfaces/interfaces.go b/statediff/indexer/interfaces/interfaces.go new file mode 100644 index 000000000..6910e3f49 --- /dev/null +++ b/statediff/indexer/interfaces/interfaces.go @@ -0,0 +1,55 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package interfaces + +import ( + "io" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/statediff/indexer/shared" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +// StateDiffIndexer interface required to index statediff data +type StateDiffIndexer interface { + PushBlock(block *types.Block, receipts types.Receipts, totalDifficulty *big.Int) (Batch, error) + PushStateNode(tx Batch, stateNode sdtypes.StateNode, headerID string) error + PushCodeAndCodeHash(tx Batch, codeAndCodeHash sdtypes.CodeAndCodeHash) error + ReportDBMetrics(delay time.Duration, quit <-chan bool) + + // Methods used by WatchAddress API/functionality + LoadWatchedAddresses() ([]common.Address, error) + InsertWatchedAddresses(addresses []sdtypes.WatchAddressArg, currentBlock *big.Int) error + RemoveWatchedAddresses(addresses []sdtypes.WatchAddressArg) error + SetWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) error + ClearWatchedAddresses() error + + io.Closer +} + +// Batch required for indexing data atomically +type Batch interface { + Submit(err error) error +} + +// Config used to configure different underlying implementations +type Config interface { + Type() shared.DBType +} diff --git a/statediff/indexer/ipld/eip2930_test_data/eth-block-12252078 b/statediff/indexer/ipld/eip2930_test_data/eth-block-12252078 new file mode 100644 index 0000000000000000000000000000000000000000..baee170abf465b03c2a68b3909af9291fab7049f GIT binary patch literal 50536 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 literal 0 HcmV?d00001 diff --git a/statediff/indexer/ipld/eip2930_test_data/eth-block-12365585 b/statediff/indexer/ipld/eip2930_test_data/eth-block-12365585 new file mode 100644 index 0000000000000000000000000000000000000000..6f7d87645cb411716955c529a4a24370f5cd0aab GIT binary patch literal 60035 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∋tNwKG(e8E#3(-pP&;4S9Z9V+yW7jg~4-Yr@pT z#SGe0b4q=mHEG4M)el^^?oCL!XtpQib(GwBYSDuamrYMq=$6~^{q3o5m)>dDZFOf7 z))n4qZ?W4~{G7}9`378{R(F(d4ct>CAP6gaUavN{_`y-sZy|tht2wU^Rr8b}{9mCG z=$W9(kg~sr1rBf_v|$6fh|nKlVd;*?_gYw-qSfOIrYZubL9fN(v?dz1kuIdO_>x`r zg-<1)G0Im>I}z(r6(iS2lqg5SrYt)BJ@#&)$LDUmy6OIIVay-#=amK`0a%!#tHf1i z;!BnHrYfG22355Z)iezNi~=tp=?=v88V$01eKbLclA`#cbuLor2DGQf*!7hT zm)*f@y1spNeof`FMdZepJ?rWm&Bj~3sWalop2)dHruITN*8|ad6M7 z8LJ0ZtyB6?+sFzc0YTWnWb^PV)m|+j7*Dwzics;CAS#RE+(i9UoSaS4F)Cn!Ix(th zsoF)JLJUaOCb1Z2sLsZe$MN(BwT`d4I@Dod?Zf+@n7%k~lR*m4h17o)2i+Q#D(ECaQVK~_af)ZnVoxCILYJX5 zsB8J{;!LGn2VpAG*_?f}OOG=HKJFNp?NQC*@KVp!+nan=`QheCZ+-H{UC3MT>{-v# zjf%alu-|VyiEgK&NCoS6br)=4=j^J3>gr}pNof23!Di;{s+mtEu+Tgs7)cFb_5P$8 z4zByq=Ml6{oGU%J_NCZ&BVEs3%JUHaHrs_=^CMdCTe8J=!}pXn$7Y)iX!6FIlrY(C zRL7Qke+IF=wpyLn5}uMM{;y<%UJF*;)#iWJW5M2stakT@9t#$W>Mn+QEI2G?Tj;Ui zut+YZ$AZP82B!WyoBztGLSv(td8CG~lfGYY{o;I8Jr*n$HErwYvEZ;6)kKd4hsE($ zdMsEhTrE54vEZ=q=%vSk!U8-CSgY}Gy_>|J_iLP{sZ32*6zFSJ24V?o`dR>8Ek^Ib z?)SBEB@_zq+ncgCUJrdmVWIZ}>oL__EUw1xvMP70=;S_?Y+uT~qA)+M)>aqOit)vr z-A8=f;xPT9@11ZGw(HRhw^YJ1BGhZx;wL_ny$|j7@hKz{5QL3;mgw~CG>@yqm%R%g<6mFZ%)xzfDv4Kx34IgX}%JuP~a-V3m1AELlshGXi4*&4CeH!)o?Jc<@_;wGcj?WyPo;<#u zOdB`ZbIK=&Rrw^Z1`x%PA`Z4)w|}%xB!1sB>Ux>rs5ZSs0)nu^*5Dt$PE)}z_tCw! z_K%q&PYHtmC5jorb-K*cW5GtVI-8g1vEZ=yxJr)&i$&d58}wLkSghHi#{yts5TFdK zSCfC=PdsPB(};#Sn1JQrRVb+Cq+p{IxG058Xy9aNf5^WjG(EiyaMW?sBsN%tFzgC??DUrlZtmlA~iw zw12ca_NeKhjL-dUR(hIMH@LzdJIo3>EE)gk-T4*aV$)3m?maN?GyK<*x)aFCv+^HB z6n=0TRs++zGM!$_)C4Ad^%yRykWb7T+s4j#SKA{V zoq3j+Fbv*YqWafIQ(oufAyorh?k>4MWZT&Ford?go;E+P@{kwBk{b;7KX&_Rs%wyP zz&%G2u2E~VQ3B#CKSFgvmlAk7r3Bz-qI-oK>7UZ8T8R%k9$4JD{?;0pX=Q2$72o|Il zhiD0sx%=qSJG^7=n?_N!+|tIKb9BgSWYMRN+`Es?o4Vzkt8>5Imx{qh!uluGb{zL; zj)YQ$b7ok>mF=RWvN^sdM@SvP-A9yKxpyCLv{oDl{&k|{TYPvy_d$u+2HAk|G`g3ty$~5WHN2v#Nim~HEJ1*CXVfMP0#vRR9vwN;&iJoc zR^z$T7R=jZeVcV>ngy0il)DbB+^uQtBxAdE9#t~Vnr~@QYf!l%i6pE%!t&JXtBY-~ z47Zt4#-Ycpg`<|eX(|$cg(apckFMTJEI=phL6M zfPfkAOM?Yf?aopRA9^z z6m+I3N@3_w<>Wv*inFn}FBzh8LX+r_W(wr(eXWz4p3a`wV{xnsoWlu6T+r?w~4 zC!Ltx=wRUYsl_|BCxH$8=9v5N%dm+-cg~frJp9{A%X@?DmX;*>Tm;c%!(}SE=)yRy zx|8#JOdZ=dIsdX^>@Dl47I|&c8~4{}9Oh_QMMt4etM0oVkv(>lHCeE{R!-P5=ZxoB z8T}4P8E5Jh)MCinvd%srx}YllQ_)4CxJ@W}q#%3+Shbw5cQt8z#i#NK5M5BJGiDENV6i7tPUy@*3LuKg|_@4-fUfI9ze5(hZ;{(7r+&jhYu)yp^I}zCTduct&qvxie;wH6t5fWI62=9EoJas= zy+{D6jdweUM5u}j9*ML$%_t#d(2k<5m!CQVA`wcp&La^D7tN6f0!o$SBZ+DTo92O) z$miKP_d`*JWs=V~O^WQ6rR?|a;exT#vDVE;Xx?)qE&6W^|dcGrx>nQGEOvBj z?Ny@RmR&~{cwcC^eDjODH5O!Ex+1C?g}z7tg@8x^h5a#4g@%p77M(3L51p?tC{_GJ z1^W!w**PcC%^ynoeOkXdrJ7k+-wAVx>g1%2K7}4N$2#p#+?s!T?v-gvE0A#21!}&; z3~6(!{n0)*H+LD|_%f_Qg>HU4deR;pS^w*gcY7>rwwOJ4sB&tlWzPpayFTEJ*5*lA z&zMPDr(!XaEaVgOesIf8&Y1@kf0y;Bt|wu=Htb>Re}>lFbZ*Yrl>9P#9VRzPd-TZW zlGD{FFmNXIjtw4svvh3H3iWr7>uSDtd#uxe^0x_tA$$9nwyK-3Mg(nvuou;UY@R2B zHhM32;Gl-4j@Cb@m?hyGh56I|F}B-JrJI&OH%s8^$T(EHrHoTFYVgUg$%GbhBLp+h zl#Y!1OOTUXIm$d+`Ad+KG*0HS7KI!M`wC^fNB|PHxv}1Tnxox>u3#cXRV;TRMU7^W zZq)KgB!IGBY9iG-QS!}$nk*vCE1Z~EETo<_24Qp@d0VXM(<$hDfvcmHBWgTJg>gj(huPb= zesgr)DVTw#bY$FLf}G^a@vmIg{w{Ko#>rgPqL3qDU!nXi5`ct@WG$&NYQYn~mLL+L zDlT{=($?LTi8+g=?{kfR_yR;Clxm$vA`~u~BM}6YD#=F@)eJVx11piwvvs#FFz7RW z^ki_Ywr_2|a)Cfi&_b^Kb%BN;%{N^~p#teQ95%inw2q8J-T#&hva2pUujcr=dX=8q z4Azlxe+hDuaZF~A{Y#LOG)`uaMIlGRUPD{*HY#!1jCa3?azI&fPiS03=cAecMLN(1= zpZm#i8+P~rh#nHBJhEN`)T+BqK#j029p1XPzB^E{w5Unp?$ex>YBerbIVcoW5DbEO z$~`Tl+D7q3b)&4~9wL{n1e4C9bGE74fC5sg4i0}fU+(!fRTlXoCB%g5SEX~((dY(| zAuA5QTVZ?gWcaz!=92?9*WPw3TDhoLn^u<=nmo?DRcAU0SA{}XB!I$2B!FtTQDSp&m4nGS0rMaoKe9%4a8!)ohxAdH@y`K;=G7_?I9j+2>>qh`$6mN#kS= z2o!Q8>@}42A^}Jk9uTOBQ|^^=t-7^Z4;iNjH+%D>SXk}Hx_@9#OLsR)sM{;f)%Dww zOdUP2r?uHA0r8m=1Pt#rh^JGM2VU|$9$DW&KsAn(GMLj%zl++hR(I`7XQ`V0HGJ?c zY8z!>zw<}`EEbpu688L2#G@0!S?D4tlYOlN;;^I{cTP*C=c(tba)jztbEt~A^JF*= z7ZSP3#$XC!(jD3+WPNGT<(=oO!XLlOew?vOg)v!{HS15dIM!=_%j=PgO>9=(Bn3ri zN}GUzv~jXdakUzU6o5{})XDD~i{zT5C<6z6pnq8mV;V?ZdmtE6ychKj(UlPX8U|Yc zNa7fEiG$v7_9#9OP?Ga7#_*KP>qSh0(uz~0YA2zYR0alem>N_?s9g4$ehkQ9>;)Ez zt-j?NpV!e+rmx)+t0AtX503qud9By|1$7(LbYpz8&1KF~9T|t3 zkfn^X_d2(xX7BLQid|Zb+dk{MvTn?L3zsr|7FcfD6sh=mCq?2bUGtyrGrd>-!TXy# zfpLG!3RSE15ORhG8?S5~L!Rxg`xUB|9%XcLzJ2A_bNgIctfLhw(kD<;6)0RJSEziK zf@{zr%>z%bjNAi<>sLnL<1PA?5!J;CvNE!w&o3gt3(8UL0n%sP0J7>%ErIyotDz`9Q>OJXnYcmqk zrdSqY)3}_o&%oGcYk#E9Z&Ar(K(UJ=0a%!#*BInd*G(mileMUFtOV59-Gw=Lft8uvo9-(FyU#;^_myEM9ZfDXctFN`=YQLi3-2scMo!3pS(e8fe z1jkJe)_gruyM<>l#k0{?f7q{Y(X@e06;a(017>&G{_;c5k~OnpQ(dxOlv_rKe-RRi zt=qHMPKS0`4r#ORgU^NBh~P%PZAz8)GpJR4b;{m3jT@bfQzifq`3(gDp9u(U`LJwZ z_qZ=nr_@6YEJJzkuia213)ZOggi{E*!WUn!D4360DZ}|PX|?)MU0G9|I$FGI?O!P0 zlTwCp&X*pVvTogK)veWfRYU2xp_@yvT8)EsTe)m2Z~u7J|8C5pjLlX43PrUF#H^{e zgDS=N9BH{@$F>PYf7Q#J-LFuY8^aPSESY@2aN`B@^2r{lJL31;k2a{)GCeGQ<2iPRR7NEj|uP>a(xW|bIRh1~I^8k1063$9;IJm7`}Tpra# zI3K3D-UIX0X~X8~JQ2s(bviZ;^}r}6MSmR6YajKwS#IUP1#&K+Vw|j|<8KKeE5MOl z1e3E5k%eS&Dc{0|S?2}0lPvvO4EpwpgcK=kY;215u0B8Z{pbV6er2j(&F{9SlEkGO z;R-bEDR1BU$dfC|S5SLlW$Xv2L@X*n&?Te_sfn`;4nrXy)I)7tZ(&l@9ur7)O0F|S zHPD_SkBwe=(IL40nbeIPYix>2u5a?Xz1$Ou5oOo!@cmM2L_)<{*M^_|<3M98vsEOl zs_)qKIcu$KKMk)HU9VobecLnYo!cxDfQ2c#X&q03J`MIh-yG>F)dK(SG;Y$3Uq;f4RuLERYH3j<8G)(ifa1!rmXn#a*$QRoH6c? zKAD$TdFx1rLJl8J5hScu&gb&^a`eYHheb@MdM(CttqGn4go;xD2dAe^rfR9mp@F%@dAKwfQ z^=@@9d5i0a>tT_7=G`kbAh>Jb$}e&QOv~lTcPlx1U6?)n(dxCweEM7VnedE+72o+h zZMpaRRl8>_AGq}GjiZZAlaq5r0o)`IRvkz!DN$ z;3__<;)1_wq!{qy_76kf;(0}2EFijCo^j*wdCSTqfUEc@)c}`&?zc7+3eIbg#X2Q< z;B|A7Qy{138o4V2N4)Z)f`^09IszVPAWPWjK}mC{k;(@TOpsvNVh&&u3N;qs(i=b0 z=@d@wc@`5q0EdkXR3^3I^d8<}3IiNYGc;Y1HPB6P*U;2uXilzScQ8I*OwQ?f;Md+0 zpGN1due{Brwd;a6v*eD?qE_E_nLBvIoI7N9dtthfBI{6xAtbETtn56~)|ao;T`*x- zkK-lrZ+%9;IUo{%h09brbIHW_;6Q2PWKBX^jYIY$VL2c#mUj zT6fviB3j~U(ydQ>tf}hRrid!WfLZ^sA)83u2t&%XQk@p%V@AC-DQe>TqkpweikBYG^@A5v7Kxzm>EH$vx;Ipkio@r zDoJ5d5sSeoZrWjZ1e^uY^rS-XASRl`I5rSxD%W&nLe|}zNn;*guy{PweXMzt_SMtp z<(XIcV-CrwqmC^GJ^%5m`G(Ky%HFGUW6bWuN%cR(iv(a{KpUNU=?|`_fuFwenNd@= zr&KBvCsjQq&Q%!T6a$*;#eSeNksFTWLQKX$FfS!WThE36xrwF*x-=HB+VZR~Hiu~=Kx@Ns< z>FYG}lf4v{0UqW}w^}58??Fo2t4ww=Ez5f9!)xuHlI)TQ6%w8j4;>aD3SDsqqC$xt zp<0q3N<6{Vg(2$XS+J+JmbM%DcymyVlv^j;m4DVPuyDhbdvrdgjHa#~v$(m%oTZ6n zcf7Fv5_~h~(rc18M?_RNy@q8zyAuL#(Ha^m1IH;&@t!iHe~<%?GWz14_TUZWG=y?}=5#z}KEjC(Qh~rW*+x1k;dlYxa9ZMRvct%KqWE zuI0uil(!gmK3Q&f(5idNqru&-d~2?#GU5K+^#1-t~%r+f3t4a-(vcyz&nX;QxsGp9^eY;57ad#i&>04UV}7g={kv^ouii}WP` z*n=pV^C~J21{ReM^QcKf2fYH-I1<*g)$8npxts3Q8Z&rk)+Q|S)SjjBq)31hhKznp-wunX4smP5irZ7>?&aY=Ie11+^LfMG`Dh<-_b| zqgH>rpA|oIO`qrczU@|se?%P;wk8d1i#_%^&n(y{)jzD}DM(m_WMBo2#8fiqB%OhS01L0Fvf{|92?X$z zxiWClB4NP}3;nm~1p3a+yN$O8+!#R%b?%W{nta55pkA_xZ zw>PZS*_|7$x>3svQq?Ff4H>7430kY}4^1;3#Jw+S-{keQuzJ&tBW6x(fqvS?pjdbE zR0F@ZE-k-?>Ui1K)#c8*A>XVg4QfsJaX6?P=akRxylB@Ooh{q6It_(O!Iy2ES5;a? zCt+Yw`7n}@$$(Zus;{PTZe7xkPGH{Cf41fg{wKQzd!bgJ?mBj{LT#FdU=0u>C z0Y;TV$7dkL+elDi{D!j>yinsaB?2gv&ycyw^ju}L&@VP2O;1kT*~KxW(BKz7)ze0F z_w55-TQE7?GJTJ)RZMiDE|zKM!k5)Is+ec$I{*8b@Jp47kDRfPgzJmEci*?KWzB%r z2N#w-Z1y24x=@SL@&rbeY2ZEH`_<7wx0b$esoLXQ$9JnYsQu6$tJ1n?*wN?JqvAbb z6Hv4^0RmM>4iB6VA>otx0R^q_q0k}Gh6>=&HxZ`x^p+g<1iA*H)1mUkT~(Yy$!qWG zl!PEfpeg}8iLS0HEmQ>O=vO3}__T&o>WmHy!O~l9Z84$_37euymmko< zg!a_54xJ=DrCNwf^WlMGz(>|M6mSI02Q<=c5Of$NuP&rhPf;q=x4+L*PTAWQle^;k zCa->0sB=Ko%J!M<*OKZ62^@!q?oH^abXs^X*`5-r`L|FBbg%X6Hv9Lmz=U>d>$SKb zDx%nO;)xmRwIX3QLBO$v;sFM7`_1@*C<`pmS+BKkdZXF2BL0n53@X0&@+#9h_lpE% zld#TL&9gRC+q-#Mxz_G?zg8?&yn2Hvw?qQ4FrW=;?OX{w1{?e-X>I!1&77D2t5`Q78jI((?2HuDJ%#&a3I1n6Tg2a-fEmE{+_s$b0Q}$ z)O&Me$FzxO7hO7aVCV6)_eBSNz1KgJ9KZOso$*9xdt=XZ%<|jm8P0ACiuFphYv7f! z)jRV{oe$y@{~@=RezsjuJh9fVW9Qy>JvTRZ%J36XO(=S@%Ds1qQn@_elcyvIdWN2H zb*(%<(x?*>RRXs9x=>A)aU45QBf0=w;CDI#Ezb!u_n>jO4(&$KGxWXgp*3;>%DXHW zv1*5tvh<^#+q}=nz1Dr+@cPI_ZQhyt;a@`Ddo}s`YgliocSSO)U0Zaw@W7ErZAh`P zP|9h+rwM1M?+1VxdS3X?cM30t@Pa1y6dHBXbe2c~?sPLY;>z=aE7MYwgzIUteNU0A&nAOONSoZ$(LnU}j0Hqq>BI_{$ zt<6RWh^HL^80{42RkWl4EIMD{f?mNSI{c|mBBL5d3R=*VHUUFv<77QsrqwvD0wt zC;kfC_i4uRydS-LA4`fNrY$B#c8L$rDg@F~?1Y4?$ZAS5cK(jFLM`09$6WlVIQ)R&{NdsIFQ-}8dN8rITjr7V^W=KU zcIN6jr~6mz``P_gs?S^^bLF04(?~&~La}mMr<_gkYdar%p7gBh;F9a&uMWE*5)g#V zovK{fcyL3t1hBLM&(hDib63JsLJ?Jpa{!^5L8X}`05S^}=LINF@d;Rhr)gjEE|8Mt z1^99@2%TM~8Z+tPo)&T2LW-|E+TOHdtuFgFg;|iWAxkFM2Y=aYb}zY1vsIrjjL5Iu z!A$(wLRgrhm9x`N(w>?-eV&A;Fx4_3tr-rSDxp34i6xL@imFJ)h67mx+BQi8k!r+a zs=vKWtml!}jf=mpGB9v=*|R5~+{xDYnA+%8aj!}I<*5s!XIssG>vX(X$00!^x~a-J zCLhA~r9OPfj46L}sWF8y<&jN9S50%pe$XJuW=Yl0qo}Xk-|bndAiA0rIjm?eD=2uqweD9`6^$^FG2k*sm5 zhg~C&9JHRW?H+St>F=H)F{V_@{hQMXbbKL-T{k}^F-pBhMp5JdgFa)$U=EInrZF z7vF%?Ium?&`mMsbWjXBVw|<|dkeW=jSaG^L?Ww>sz2$n!fX5J}fyYs! zlu(lK6ecj#sDIU%YCV3Z@5K}2Uq`sTKfBFp^G2uJ^@o#cO@bK8TemA}dDx~8V-|GoZ8siAmQDUWu5>@B@eeq>i z#F7VRLJyyfs{CnSwWcmXJ45aolj;Tu9E%@DINfXKJJK&!2s!^r3iMiV6LS6({d3|9 z>JbQV)o{TW{tG_@KW5;*ftbOOa$FgD-a!=N@>P%8MMH!lAe0b7N<{tn5sdmKyxc1s zT2}~$zrsp7r-hfUZfmz{R`sdjr+ck5CPfWVN!UF5EYwS{7#LF2A8IK=(0tU6j&l4e8YO|?X^&=zLLwGMr-=j?=5c#PSl-dXc2SQ=y>ozX&WG}C&ws@*=T{M2@Lj8iOzI;|OTyy~lQmur%u z<_L*;*)unOEM2s_f{td3n(!+}LF7M2CFGiWD+7Z!($NfKnol{EU`UlcGw#I zx7$A7XE-9dRC0sa!(7IOE=<|6d_$5G33TwA)~_@0k_zP=n|r?|>>sqYwX|`vo~qDl z9O?@Xq+k$4b@bmczOr)JuXXcJN*gEZqkLL{v3dLU^|vPP3van`ebT9%6_a{5zxV@f z9B^})FNytkHQh1c?=o(BT+f!uA0wTIHmp=Oef|@Z;m;?XkuXk~`sG;zJLB^2Z%Z2| z%dJ|Gd-O5k(f#;r4#A1cRqoM+r^4KPj@-_X?xj8#XQ z+wbsd-mq>hNeG#MuCUVP^v+okoE8x(kHM&6fRN^p9x(Gu0fYH54_}08_F8&sK$}7 zy;}P;EKJdD>W=CFdIhTD0{04q<<}P_nqPBrDpW#MoseE|#e4G2K+r2ts&(EgP`F6- z3Sqbi*6N<3f!9s1KsAnpE!H}L!NL?x8&~iz7d49i=r`wevmeF3b=n+|e0|jg<*z?# zhGaD}JhA58;*78cB&-i*96>KQgWu~1!B60Mgh z2E9RCf)i14nbeU|34|~}fjY+nK`h5B$awr<iL!xBPn@{ftLnFeU<51ZL~8U@sVlV7BU5 zh^A1PotP4=_Yq!M_Yh`|%(8GN8gCp-$Ps^fF8r*P~DqHVMO| z_3M1FFl5}{@@2qXK34VW+pJ2fd3@6>C(Cm4tCS#~i>&93v;FXJ-qo2sJ|#X*2g@*2 zqYAhT>(jN^^W*7N)|MYVd-DcfotT(|*;}5t*l~=mKIp8~X((JImtkUCQ7N{|p|TVZ zu*iIfNiT&~l`f?o<{_c~2FZM4b@dzSV+jVB&}Kp))dDF&$2WR@!Bqn(o2CvJTm`|! zW|%9`qCkq{3T|TpsZt?uxE%D6iSd{yldYR#@)HaDxpL~!wD@I1 zkIG#PXw`jtN@Hc!@xRV`E~s6l@usdbk2k&0H#RUwc00NU5 zZLtoEI&Rw>po#~Zo{%52Tz|C0fS=E0NE$=|CFVe3L$q zvgc8u$HVkkP*+hmDFfGfZdbvA;5&{AL9LmE;LK%GKbH(|)TCkr|2{OF31~LZo8d|( zgZq{Vt|AAP=E8hqK=AXMSPo-K0ZC?3VUqlQ5oerG6`uzaxrVDjU_a=3V`rAtoO526 z&iD5SKYHWaNB2azv9tKP23wX-{+Z;_VcGnrX?e*9CjKZ-!m4WcjhXdhd7$aDX~#SH z#guJR`)xa^_rw+NXJGq_=h#x8;As}x-*P_oD6LTI5{?HB6xlp;NEPo5-{pP_SF7^3 z2Ri>K`X=vD+xabq?%g?V`PP(%lSJmD+9&lbT)}=A00ixc;K3{cP85U&&PBo}^INzD zLWh(vn0KzUak4IvYc)=*^Laz7A6oUP(hr5(%BUIOSBOyMa@@#k?-oy9zt^Mfz$>M1 zzV)bmam~lIwe5!W9y`Fd$d07s&Z9-`Ms*vJ0Iypi^qO4LSIWS!&M{Pg0>T(8Ll_}P zGY+!p5Jibm(ZEbWhZu}XD_YWfYKcm(dTr>_eMTH7m^_IK4kBfAjr5K#L)C?Yf0PW% zCFl&qjxvebF!0CO$<$5NqQJO(DnV^H%*Zv#(9y~>SU_}myDjanleENru^(}Z2En+AhkfvUK`y+T=Hvh}JC%8+@P z@vu69Hab*so5QY@$*&fJUV&1r^In0%MY31?wpWD~$)h;n>9f?ZO~+NvM&woY?~rCL z_iboLKlg-DZDQ651VwV2un6He^pRRL(CY~imrl?NADB(R35aG_JkX*BWa9J+hg!H$ znwf;m*`zHBknqD)iNzO@ZIkQM)c*A~QdW=M$@)@{q-SxFdY9X7h-F|{VifU8=18JX5 z$J}gQ+FvNqzecx>s(7&JIZi7ZkBV~o`|g{daFGn85=IMb&Z`1PpkQDHE}Eimx`y9z zqyj01^D+cOF=Lw=!iY^Wcz|CKQextfx(HDoVzDuV4GK7)LuuxM2V(^<$;)sA6>KPz zR5!K+2Kdw;v{5xP0STvwe<*mAJ~M7)*Gqq2@c6@XX5U)I*$;NbADemiYwYefGa8A% zb3|dmZIE##*7c~}c#~0y^k(DSA{}aGeIbLE$~|M#s(Xy>#T7Bz^5g8!&F=qd#gkbF zZZ}^|a>j^{1}0DE)GMkyH=+m#9;k{77(9TM&E=iuW1C9uY4}sDl24h1Iq#aaVL)gc zScRcf%Uy+Oy}^URrQpGX^D5sS5g`C8Vj~jtDlEd;MZXGTpEHVh*iOI#ec?$BMkcPQ zu^9#vq9igAZ0YdG3DXjsP9uV2s~k~*6o_cAo~nm_&PW%p+1D*BD$(##q7)LoSv0vKQ9%`iKsT| zd`?8+f}RuME~RF-ju<@f|G@L$oNoG4FPlpq5auBD#(^*cZ(PWMd2Eysv7p57&Phzw zI8+iML3mQzez#&KvWbgxWw{xOo`Wt_t39+5o+$#Q+6jV1vzws-?k$lEe$@67+O59#Hg>hV@AGu8Akwc8n z#6@!u&qjHQ&lCty8nt1nGo9KRg7%b7qI~qppx4nOto(b;7$4xbW{h9YIpUA57tB*8 zlazs5D%2KM3-kyggvJ_xSs1xd$Z;rRm`KD7%+Ht^&h=J4k9DKk({ZdI>kFJ!2$Fy@ z2c>bU1~!)>MH?ohXb}RWA(O3XCiSGCXtlsuE)>o+9s%Y&htsFF&9vy`UbKDU$afvG zFYk`2zfSIX;HF)*f@{vRznzRe&7MGA$5)mWPwWBOmI_%-}~bjy%S zq2>DLi3A|wwr%6Tgk6p}_DkA0StDMnadP@mTwF_wk@beQQ|f57pcR;$FxN89rdb<~ zZ(Y51$J$iP!SP0ODdZHEXPzrfX6Ee&s|8fW1wVuKpVJ^y4Ex}=$3)}6J%(~XC%9#EH#1kfu`6&Ji$xU_HEdrk7v*3T9Q>O_>X;Z?;3d}Mfk z&?``?b>1sbxJdR2k*TNz=T%f52)R74=zM`ouMW0sJcn8xsE1{t930glE=y7+adoyT zhu|2hlM^&$C>SAHf}TC7G7OKR#2YUlX8&GFXV(%YeC_FQaP^p=GGz~5Y0;o}#I?Y? zKS|gIt-k~U3j^Ay)%t1Rn*-qEid*fPqCBM{FHQ0y zsDonho@$L2K&xP7b>^w#WY0_W28?o8`E~A;Q%@)Fh`XD+lY|YLwJPX%@t$+xX1^q(D5pb8#zrg|-7ij`I=gs@Bl zOJ|;{Rqyb(_lsjQ8Y%i589e=)V*8VgJ4jfu+%ctGJMlI6{4(&=wn9Ds#F&C@U}-bZ zd2xm&SQhHQ=ZQxQN>q!d*dnq$1rL6mdFrA?^1JzI_KWYw-WWA$Y*_Hqsq4FwaHHgU zN>RMq&QXk~0ueu+gTZyH(|>wQ0cR3iwbq&%xTlnkHfcd9A1?nKU%Kx!3#Th^yb>=C> z_INyElk10)BNuk~WLI@|e*UDBB&@8@psk$ZZy+d9|f z+QIfKcDy&R>vqiBY`>r5aT3ZnKkoV`Jq1<$|CUUkvDi_&uO18PO)2mlgPn&5P*`AsO9_FL46D>|5r!&U zfM#Pbhkz3hjU2i-tr84uI-tX=R*=JN1a-iu9k+p+xaaZsKtNl^rZ6B#{i$s@$N7gI zsWI8~>sY0lsm*kB%?)|Ik82`zMBVNpVF8$ijFY(PE$j1+T6I@CSLF+lQ(39V41d?_K!sx_yYk zrQnx-IIqH<=4cpLjwf}@HNK?`-2H2XhTvfh;tFaj3Ycv0AXM@xHpb5CR30k^D3#5c znY;PnPG{rbc|OF$2_O&Wiic2<3*%DkkqaK;4E5kal|^j1MoC}*5BwBw-`MBm?n?m^ zm0$X`_L~!H+E?!UZ(6a3)5o9XtV$g5xAr`Fu)_Ir8@7|M#wnpoT9@DE@}kJOP3xOq z-(}sh#Rx-PFwjl z;*W^j%G6hTQK%KLSM>3--8(&Nd*8`1CYhZ$bt=c%&qmjaZrmw%_1_iNQMhRA6)Fac zlblz@TqXqri^_+2^qO$*&UG5XI#_F|Y#5#XUs)6Ka{?dMMdqr9bx}4oRWNb>A6gSW zvKZ5N8ZbgfQCqibLddwkWlb1&ujt^2KT;=tLg4kU?H!x+elYYzGry4ialIVIl7b$E0y)5;C%BL#eHmom!D*U21uOX% z)8LX2xQ(-a&=V0BOgB~X-9$D3l4mXwHE9?Q)YTA)O=KTI32{G*BPzfTIuVyiz>4W! zJMM9V_Zx2bdK^-gJYi?>I%aOi*A?WR$UH9WZtr&GYwE0&l6$I^w{}^-%ls4xE8l3| za_yOQL+&&i5cME(QQvWwuDn?x5`ct{c=)Y<+5H}_pdW}oaPfh};)I~eNHmoKigyV{ z3Gy3z&I!^u&qET32jb~R+JQ>WMO0mMEkGZAq$(n)9Y*b-jb5A(IK-hy${C<21}N~S zVbk3M@rg%&y{+zE<^8zu#H0p6*Dk%j@W%!c){I(+iv&1f|CHf7E+v+KFlzmbF<|wg zi|D7-xZjO_pK}IftpE6==)%jUy$c(tNpE&tucPDDOCL|)JJHW$ zpVhONn;5OCl1;E*H2mT*;AfD4r&p`)g)87P= zYLG-^6N$TuQoohJq@-{yD<`RP3?Gz6ZJ7GXNu^ynTR9DmY5j9$-KcLaLrPZ=1**Ke|JNu#{0Z4elzUI|;tLTn$GiRN;-{E_w)d2IB` ziw?o{&!lebSYuOEa($E6?d5tZB{i@8o?h+ky=LyH{cS+W3K65`Ehl+3fcROy=Flb^ z-$oa0Rd3jr5*>EfR$Uz@5`cv%x{$*!f<7CG_Bix=o>HyhUzG-DBj9Fzbks>b7VN9a zF+GwQEC?Mr8jN5KaavsoHG&bk#X}Do<`4;0Mo{Z|)F#2ELEenIV9_P{k;V< zulQsXN(@)# zf8i0xrDJW(ZBOSrn^bQQWd?Wv(w zVQyW272e_>9lO`BWyqZTSNo^SjkTVy%VkxX=+(5{2K(@9+52)2Ry8U~!seboKhEFk z>X+aSEzCVuPHlbdY~zmuMFOxeplz>onyjGj+a7L*Q=Yoq8 zX7C7o)_@@?DU2&l9R&ypp3R_3r#W<)Je(Jy2&yieA|y9Pr!^2{C`u5gc65@h8v|+T zPkLkS+up9TyTcTVSl4kj5s7}^LoCR;*LuozRq!p}<>9v;B(|~nR-tg?h(bNqKNGJ{ znnl)X{LHKN)^+!-)RKTIan2g-d~Zg*LDAz(P$%lJv6i@Ou64XfnSksti2*y1Tr^ z2ol!+?@Z=&;z+apdMv2Z32sEbB zEvn+mo@O4++oSgs^Ulftu&1csvX1lnLU{@kTuBI|qQ(-f%6nalmve`MNsK*DwWJ$^npy7AK`a6%z*VM*4A*J>Q{ zd<*$>N`C%TBGRC2dvB`-Iywi|3JlUX2rUt5a^2o7vrN4`;2aoLae>cv6j6P4^~|_B zzE{KOq9n5e~3#^v=Ea;BG$rm0hNGB3@*!L6jGmm z4EXpCEL!pe$6`rq6x_@9^eFrpMm_5+VVtZfs9?sSr=VZ4r&rx~7*;w1d;$-g zHl8RNp&#(zREb*Foy?%`^I$?ZBLq@?Sh1mj8od0E-(he8diXLNT*Ma=+{m}4hnsl8 zC6obD)J*{e&2bY-izpyO$xwfQRNIitI+P%@tP3ve_Ibqd?$xKyimuykNydS-V;6?W z9a9aOyzADmPq#y#-kfT8%J5#H_QZ%*By3pq&9}=fp75bwwIg@dr8YAYop1?R={BXBcV35WMXo)H1 zwX|;guF)5S?5qFz{1hKZECp^K4OJ@s)FtGH9dk?e)0j!I+W^vbXg~KDc)Wk z6Fl($z_O0hP2a&jwZ`_hqddJHASfiL=)f;XDo~t1wMi^AggQ~tNXXSp(PgbMLX#AI z2U}uz%8DI#Uk>Q!k#{4oV%?gfn-sR6TIos92NKr&JTdTHud!cWG@nsrQJq0jVV0&n72l!7Z+nW<$h;56rT8NQC+|R>ubDu53FgAILJ>k&$FDH?%F)gw_TBm8Pwc)|{+y2zO3Z(b(Glqi@zwL6>q!FN;shbLqE9@*OGN7d=;V@j<_>7KYOx7+6q%|5%v zy<>6K6XMISaJMRU(9zAmSIY7tBaaWh9xEdVEVH202+w*KZ{a$Mm74`l=r zw-Rr9ysfi*1~`&5tqt&0=n>O;N|N;d2;!pFY-|aGwqOh$kzP1}kkyG=LVr0*;z1)( z7HA7L`YDzYnn-&*OiAqqaVTopJ$+{%FA`bh@TJAx9!s{Kuaf0eBehYRCG2LBO`D#- zrdA4KON6A~U6d{95Q~eBv>$w>%2(geua5g`9hsgdu@s#zL`HxU16bRG^$I~zYj&}$ zK~L#){Fhci)PfOg?o#!)E#SNZZ85a=Z(9hqINtELEr2a7?`tD0FVvH4VJtf`dg;PJ zOvFNyEVIK_Gt>)hG#UyZc#tQAnVklITpI$Q8ajM+(>ymHn1S?9@pFk8BtbkKG^kbV z0@(o!L^9w{qp63s+=e^kG>dCsK~mVSW>8#8%|1(0>+LvSbyTxaYtjp-P3_G;j%ZNI zd{>KWMd-wEPw(F57q3)fF?pJ%3rk(^dY!&qrP9jzQ)4gh&+hzWos2*t)^2m1*u=fR zvqqEpGn&*dbv#?5PusY_{q=qO*{$}e*VV~y`Py9*yB(`GW9icy9ups&JR@UGIzSo0 zTSAc$kPdH87Y(sU>Jys*^8GjSj<2WZzogWzshKcjz02t1sr$)?-<=)tVL{Y|($>uf z2aRRQu)&M_+1{;1HQ97xMf$a|XNFHJ%Hpgub@+Q|oP`AE_&$1Ot7BWrE?yzwFox9Ok#aQ$iCZ7Q;uL=EZi6tu^*!#Rj>P228$ zE+^(qKfmGEVWtSWc4ZM(EU_+51)ojpHp*{~|kb#visj9KRmZLI26N{Eq}HdD5jaUdRE7t!D{AaetUG&Ix9 z>T4si3@9a~c)1{14W(g}I^}49qGT9ZikG#33P`*1b~7#=>(c4gxkRjsmDLqVP^u?r zj`gO}w10pU-{)1#oduO1#7^up+Tq@eD)n58W{Xyv;v<%oh$&ON-@p}F5^ayWdk^Y0 z^U(no6QwD;rP1hmj=x4ctT4{*(`NVL-Xr>5mJwjY+Ti{>PsMsv(J@?+;-`_k2>H?E$JmXKKvRaA&0 z?0Ek5AY4u}5mtZH|7{C?Ic+tq*>76_TUgxCM%WZ;18qS`!ypW$RlbfAmDDCcFtLeA zlM=9K578WkMs@OrfoQa323e4X6<8< zfiGgafY79wp9Sgc$br%Ahs^$1(4)$cGsBmj&*p#qYPi~5J0anWrN3R*9}}B3X}$B% z)_ixLziG;fasbeKd{yR@qsM7YRqs)s(r?#(R%W)+m69?!G|j#J`hUB3Sy?$%xz?z1 zql?+MEw|%Bt9hRHN(XG*alHM9M$=hhs!hNAHhtU9wb7PT8K7K(`+CpquD_<+X6xuv z;^i&t8p8sQsI{C?!w{9jO^d^B^J`pRI_X`()KSqS#t+y6bqXzG;8RDFqr!_FccE2jr}wLq?5npSU$G?$F>q>-;}k=kLi1 zEa0AWa54g%SkMj4{x*XGerI`@<^Rw|*iEjhljRxQZg`f*V6!4pj>X9VY^||&pb(Bm zTYRIlezt&l8e9^<3XQ=GO5->NYt#dEc%ybH%ZoFBUO$L1OEWJEa#fwh_L0d8KR?Z~ z*`>l8w+`ufvjyi@o2xu3hEXLaU#tAwxznI2Un+h*wO~dBiwm{fdiZ9SvvDCQ776Wvd!f&Q703+{v2T6C_d+<3Eu|HJUtivgi76 zW}(~`Vy*P0!1H5HG>IJr5-CaaKb}ZAuZjAa7!VEr4S2`;tJ7=1mcIZ;$Y6Z|%E%wF`J# zw$uHTtO0m?S+?{Ws~eA+yH~Badt}~eBfEtydHE!!wB}Hu+&i1P*0P=Z)4$f|_LoNW zE|RxYlO=ZA3j=TD$NS%HH#`2*r%`A3mCk)ROP^9(^DeA)2ye$>ZTI>k1E%5_BAh_P zV#qYhtJ(;MpohXV1EvnRAZG*;5fBjk9?T8402G$;9M)RHaBFmkrf3ccwptOA0a9oE zmAym=sc5Mxoh4v60R$%vIt5KUeE3;YI*p);P@E!Z7N<;<$;-VSoHir;bLjH6t&qef zWg<4P2;w)XR_!);9o-tbmTvWPGSlQt|Mg8e$_Q}c{Ha_GDCf7K(2?mm=UG{n`E;+& z^mfay4(Qxc?Hp)Sc1o&$>DJ2+xHT#8$+2LMpLz1%Y~!h*oVMTa^A=+#)vvY&Ofw|L znV)9ruO4~0M426K`>Nr#z+lS}ThIHnsJPV&Ofw|WYNr{aP9xbRv+H$@M(`?jL>MR; z7DEz26NN14;8o4v!p7xd2e5$o~#8ypF1k$Wgh#Z(H!! zQFBZx`r8(QEpCJud7@qi9fZP(CU=&{-Hn1h@Y7AhmnLW( z0fcIrc6e%hw0rAV@3hyRTg!Xh9&ps9$PZ7uHWeSR1E*ZeV>!qzuVt5HD(ja+qujhE z=4y2*Pt~sXR&;xCxZ->HLUC=iM_>0Zi!6D2U^(aE<5t%_^74ltK_EhDmp;DMV9P9} zW&z(t0F?GXb&}WzY~MJiMt9f6?Y7!+@1x(9;*VZbiY)qUwY6=LsRQr6O`I7kSAFNr zj)%s?y|r%}w~q?#oVcfK-Oo9cM4C!cP3}wJ$GkWY8O2j$>O?@gvbam zV$1#~I+f`TOq05RsN4hAvGMWbku5hIwLMhz^9ZL;bF`Lu9mgE$S$2Ols>l}N=ng)5~?EdLKqbr6t$uGzJ&zO+!K{lZpDU# z3&*Y3UwE}uZR$(@w*OAEnLh^jzf5VJ5;w#uEH(cZd!2E&-N3jG6I|!!A+acUIfQWHTyKmUv?5T`3=>TN}nNkjo_t4d{$i#Li_7%1>AUiZ)$ykVzk3F~-ZaOmY3!VXG6IZP z`{-!;KG(Gg8uUa@f#?I!Qw5$ReVR7Kn1_eO)2aAl1Mkug>PxL509`PXkN8+5C7CYO2 zy1X#*N8oLXSN`@j8d$YFLYMB?@sz_NR^S5ns-B5)Xg;Vx6DI~f0&j{ZAC1aRUpLhz zSNVGlG^t}|_c&ML`Koh8Em^2FsbI=QJWY9AAldEZ`R!SEHFj#z_}kHI>($1vQP~a& z#rJ=*`uVm+k5hT*=?8}loOk#IOHvHr{;;&a&~N+}$3$>LkHk3BH}uTy+`eCn&sy%l!jG5O6%x=ml?3ZWkkrIO5=SsYN`;X?2w`z7ZvZu! z42hjYhobgi)Ue|#smpJ-x0~znJ*G`Q|G{qNY7_hFn3yv8M{5fooaOXriUa+D8n8_M zBEp#SX>am`dpTaWFwawPa_rUflOjv7k|HvwO660Vj@<>V=p?#O!SV!8$vXT8D%=Pz z6y*8a7VrijxS&utXrggj7#_3O-~^+CG(ZeRmj1VdcxtUUUIl>C<%5q}9M+{XS~uCe zGrR2Nf}{KP4lnU*fc0@Nm!vukLs%9U?^iY7tN6A-RTBChaoT@z&E~siWo%^xI5C9V z_bJPb;KGMz826NJ?|)sLi(0CBE(KdChpKW5Fp`m|rFHEnn-g>!QN5fD%gAa{MMcz7 zQZH^wqEOV{K0GdFy2lgOYyJkWk6fh(L~k=2R`$n?MUK8KuBK{Fg_RlwZW@Aht;?+q zoToB;q%@671~5e&kHTWq@HwLnE2U~ilp`)p1T7qht)e(IrY6NZKMR}_Hht@fe$DgL zYqUmBU&(nWm@ah}`Mvk<9wS4j<_FNzJ(Z14!_Jdy3TOIm5%iEnRcSIe3s&*}Bm3-^{oo2xvscouluXA$v zgiAA>B3WGOBl80JzpV*xm+M%!Gk1733*Xd;`d+BaD8B2UAsB z<><>KKVJrT3cM0g^kB4tr?4*ndXQUP6>Bv@*A{w#h?_zuI2gPQ!5}L2k$O}TLX;*X zZP28O0nZ95#wkbh7;#65kP?8Rwx@YsH<(DA5fd|IO9 zAkkC04PsqR!H9S{pes<`DyvagjeD#XdCC-L^$l%{O>=MD-mllKn!7I#x{~tw?p{w8 z6Q}yDUTZV$Q)!f6iWmOP^U)ZNp3TBMs>iBYOQO+TRJ<<;R1v-d2^TG_G3oBJJV zTQ5pxamghM^!>T{K#hYj)#~0ZT6?19nqJHM$Ov#^1TQQ|ndlh_qq28A7@+O*q)g@0 z=Sp{-u){0twcDvXipp8_uKvu|!+$V%41vTr(~lwW26*kezqy_*IE0=53=fY%hX|I=vE@UhXP$Jo@Ke~=E2#g#M~(>O7Ndne_Y0-}P% z_|HYfS-1Q{PZZS^$JMii53aG_y2zO2vp`gkM4LP+NOmz26=c;BR`99;5@c9I?XWG) zVz@S<)F$1xM;Sa}qihT|V)8|4)dA*EQd);-i4+Rq*29q2j0PK2_@3NOPEPYA+_NbJ z5sXNn0|1q1fC4+H99MYW@M;ew;P9tjXaSjK-XCPn!t?310UbUcDwwBRTCoG0?s#d_ z#;YA82aa4{c%t3FI{Ain+A+V0-R>SW60Wg=7`VT3`C;E;+Eu4ccPqc(%H-lta+&{; zM@E1XC*Pfy|BGLT4gbVrcV@?@zTcNCJ>5i8iqXgJR2c?Sj?_=B*KnH)u*@k&-755g z`>Y=B#};*&(gI{Ql5&~OY-S(6?Yd`Ksr-Yb<8W~jY!iILv&rz+%dV^fP9up<^Z4@%JkTt*q-lR5?@;oM{5KGX{e zUlLcMQj=Z}gDOxE~g$37&Sq@ zGG5;&E_Hv&hMP{d+*x#Bd;3i_CPu7g6$R(y)$*x+NMTu+XEd*Q4PXBESU<>$-;)>P3LR(NM zFQQ41!BZr{;0O+e%NoK-8Ek}T3Ial51OV*ODoVbDlhXq&Eu=pIjv68qAIwJ+gQbxh&!2m$gJ#F z&CF-_54PIVmnCbav2A){LE9SO+mhhaio`h6r&d|=v>4@jqxFtR-#ZGT``)jUrL59BNa-$eRXsp7$P{ib62AjZtSO9-0Sx6o<#EAtoqC$Z!=)_mK9qdJe zKgdB4i?Rj<>$-&&5NVe6|B34|n$)e!vNZ%l;BR^za^=V)^EzyMIpulYJ~=+;3mJX4 z;;S62U<19qq?{>!zt^bj>MKru*Ltn~aHv+vS?m~-eK0Vp8ha-kQiq^d1!3E zkEybK%h^e1^z6YSEHACQ(4fY&0U&vhM4LQ$knEzEJb;dQo}KHR_r8+$8s4i)?e;+~ zDN9G>Wt7?lJi3?QnMchVC)~)BGKs(n?YZp3ZDkFHDi*}ACdwqp(+h)hqooR-6eMg0 zA(K5_b|u=^_wEM&aaIpn?(=;?y-9B3+=a!J*!flMc4%&#CbDl|;=8y## z+zwhXub`Yl^KCG7G{Wg57-lmHRl$}40Q{rCpKbw!kSCX`D28jMMS1W=wniEn{6kA3 zxZ~Gh2-4e-vKgNTDWC&|Ixtu_(18}JX%;^J$l0~CdsLR_c7NO1_4d&Fd)*Hmy64nu zbktId{JuG+ewKgDM6d_i^U9@Z3r2T2G<)NuUr*LdbNjk$g!cP|HH(~IgWs)=&f27M z<9D`O(%MA%H;oC`Ns8Xnos62m*j8u7!`iPddt92pKa6JOQw`=#n7Taqp9DwG;y}XxOBl_5=e?G867y!9Iv_M-Er$Tdy9NkCqIgD z3+Q_4Z6~!$#mt#Urio4k9z0kok{JJqr6LfrDNB6)Af=yntC5{OY!*MVbvCe6B#Acp zQjrukhND8qPVy=r^>U=VmVv0^UPP!h}ek!WO)QLSavIu(;G6+gQ9y?0*I^pp3~-PU_*1b#12U{Mnm7naqvVK$r8*rq2o zl$nqek`VHG&JhDoJAj^5Y_Eftd%%lMwUTb?dJ1R!AAz~Mb##QE&XOPuKYmhNf_4}p z3gHRS6!;ShBSIJ;A@P``G_*(qB|~0321w)~faBK@f(B?02q@Tu7iX?QfprP^6N@O4 z7Eu4x)scqwkMD*5eOE_Fzo5(tHqhHk%9-K^wT;RioNk?RrS6*5-hF2spHO_Vi|Z%5 zuS&`_zh1fV#HwRf6a!NpiSeJ9@(R4q(|@${ZKa=uuK428j%8CW?cQD!OnD^HCZF<1 zb}=yJ@m|yOrfCqO;nAg4FZb*E$%Ek~S!m!8CKNDI<;lZBB>Ibz2jEYOGI+pf^5C-s z^*@_DToaS3z8>?pollU0oz=CfSeKOhTaw3xUL(wwznj^tap<}^C#P)d`Lt6d`SZr2 zVj4|}E!DohvmA09z8^w5s6UlFs+Vii;zVPG-;}R-#3f|i!n1W>?fAQr2gxo5k_YcK z%vh!bMZ=@yQLiL=#hQ{NFcOHrOM$R7+M*BM$diZEM>l!U4A%)zFcOsnqX7>~S6w=x25Z=DR<8b@9?s*J!VR{GC~uLOK=g zhupP6@*pwJeDbjSY(u}P=K2162OVixb#2jUu0?8q*O{s|9N&*0T%B zw<~?7Pr-@biv;#szt3wqOVq5x{l-DJw^n(Qmj#zaz{z%fyY;_Mw)w||>j(UPwE*6i zfsY9{tb)D^L`gx!NFYD`TgXtb84efSfyoarfHtEb4Jhc$gF&FMK`5aD_wsQ`i%pOa z@B-fvNDy&kfI(jOIwYLYF)B_ ziCLI99CYeFD608U_DU%*{gXtSeEKKZ#lZBB>q>%ouacSoPBg4SyNE{9f5T5TRZl89 z34r1`>Shy#5i81<0XjVKHjn~9W)QeDut}bAaAM&kM20ii0a6;e)~@OmPwl~R<6Hxm zKmGXN>HLOORy1q2i0#4Ry6jsP61JgERDJ&kR&`pI$rkLJz3v$q0Zt6z=(v}q(DdJ^ zL4DPp(q;DlzYgv@fKTByI)pBl=^u`43gMe6Zn85FVN!I792pTJ0#X3d#CF|?V}$V4 zp(g38L!w+Y6t&48d^hEPcrv!{k*$4xRGq#)rqr60?upBCyM6A^?6Yg!I~HeqaHscT zyTNC+Y#E(4rP47eN_1e4OSG})oxIs4!!HwY$qeYxdB+~_;$gC zG~1Kfh-Od9z^J7p0!AFl2uHh#P4K)P(3&HEf!|7l9-}oHi2&5mPpDA<&?#C*GNm%_2C z?8a`ILWj1=pBMPNveNhU1vGKBmet8w+&r=7^T1QTSfB;5m={{zXInVBc%h)2s_bV} zxg0ri`m#@X_w^s+4XlZ5CFiF)m4?FhBYdBM} z{@3>&G3@4d?d!2bvjL=MNR9F#2NG?;>V?EO)2kQ2+V|}D*slIf4=ISYOqljHzn}f} zLtynn60LUiV)U>{1j?%yA*2+v|I=vE@QMp=RUu0{I2Knj=IN*K)?F43yr1Rk)u@wC zzR$C1Do>s`F|Qo>3Cd2<)^?vAejIX+&tcgxi|32B4lYq6a)O6{?9MiwH^igit>_?^ zB}p-#cU7p}C70%LU;Afy7u2p%HAhLAaKL-O=4FFDyY&be>%6#p!C~WeN9hva@)6AD z(j+)b~R8 zEWLv2cMZR~VNB#@gO&rz+M39%MlEM_qQ)%;VdU1dXwv-sfW3b8bDsi51DARoF@HE| zUWb$}g{P;QcbL=i>%t8kXWBeW-IIW`Bgw|wNedCYofP+YyD|PaZAK<5c|wfVJGHbwa@&?BNa|LARDs`@ZulNB2rR_ zg9Y3&9DxPc@uxdFJ&-I+ASG`n&8iX!_fyl2j(X0^yE8nw`>PI{QrzhsM?aTcu69y# z-_XZp*}AmwpCQ>Fb?D&VwbAQO*H~PYsy73BwX(^P#dA~LMXPG%S;ZEr^if8D5u4NN zFXyj52%X}P7=tfEH9wVYZkxQfiiZ^++WYIUO{)$R@m^Qj{#4CbtDZCGms~6^V@;C1 zhsFdFKrQ(p25_b;D2Fa;v|!-Zdlid;Ce#P|lv3<%s6k5%heqTsSbP8iVow8lP>Njy zY3QQHua|boHLYF+J+h3NJTl>Q(zo2Ryg(SKTG<~z@utqIx<@@vd^>RL;jPNWf9394 zfEA>`eI~!Q2JXbQxXj-(#o7JmU@rT$TrU2?7-h%=jG;!U&B6l9ehwO#tl*!l016I= zwhAFA>j5g13_;6kutH&hok5nEVqErX?o_4l^&R`VEL~kAZ27^wH-`j|9Hch;HJ-Qd z(D0%*6^r(`SsIanT-?ht>i;Y{{$&%P{z>P`Q{pMTNO`Y3vbK&&+Ng3y2}sJJ z)m6(+zki)gc+<|e(H2890cOL0GsvwpeHZTjZ43TRf9pxQuNZI_)A@X*utI=|4JK9e z9Uic!z#m^Ax~Ncrdj_xQ!%z_H!xdTpG*B|Q&99L#ViOUNKG`bi+=8Q|zz+Ul7tm2n z;{6ZZ>DLxyV||Z>?l92>1mfz0J5p|Y@50cgQ=iX$-aY@i_&dSF8uSS2ZO!5YIE*Rx z&GB2`c62Vs3HkC|KUO8{@})y}hNzu{jLJ@Y)~#juWbZ-YGn-GWvgxE*g-e%|J~(97 z+GqU;X4ZW$35|*-G5!@ArTZnLB&+{H1*%kG&&7Kdgm6JpRyO{Qa zU?jUJUn>{9CTeU_Kr%c!y=c>*oxwy(5rj*l6E%`Z2)*=C6s?aVU_g3-$%-$G0Lb<_ zDoNRh&s}^jl=Z1MRxy_DcO}KcvOb(YGeBxWKvnn3(VOt1Hi2 z+SRV!;x^;!RUWicMt~DTxPi;7gXl5Db_L?0rznYlkw9)Xmm#>uoS=)I^(nNHfM@_o zh2d&skLX@lpv8Vb0umu%xF&&*ut!*iPeA~Q<9V0@H1JQa&;sTkTAWxk^YfqF8J*{m zZY8Om|BWtAdW>&z>!{t3hb~d(W?ik8eSOt^sr)en!5(mrDVMA2-ISo%MnRh|maMhQ z^-e_0y~q93DrZ!7mm(*BZYkY(;rSM^v*+EZJt!(HxCDzUguxXKI#yUcV$9`cU~xiX zoax1hIo)=!S;JDhbNn$06NiHhI?rnq_u+QGVqkGX5^eIu3CS+XixXT`5-fO?)CO>( zVHMg%G@A0-4Loct&5IrWy#RQg`-V26!|^|WEnu<}5+j2jGE8T%2zx$Zf%!%H%pQd( zgpHI)X#u6QN0+ql#K&i1K@%yFW?(+!Nf`XB67mLk3TO-dK#>bWD6~m4KMT&ZOz}0j zku5@dKj?Dbugj7>ueRI`-D#V2cMU5E(r8GZW|I-%#FI6bQwm*KVn8`n%SfZj5mT|S zT-4d8jqmN@owGx$u_ii4HEI~5a=5i*aJ{LMcKh4U1DTe@IMbO{qp^z!P5Jt*Z$+h8 z(pXL}+;GN&vDZPSC5bk9rX|@$Inz$o?yK*;XhVIOu}oPJ3_qIuj)E6E?n0~5PVZMI z*dn5IRH0RZKC(2jV~WI{|Mp1_D=GB%WQdgtlT>3C?q zZy~`m_e3R?Td^VG!g1^M7hY`zLsC^9t(RrvRsX*3WxFi1s5CNwjrmYv^ZvH zb0oOj!&CQt>XoZqBcf&e-L8k#dg^h}?b_SF=J)@&F59&$kB2Wl+taoXi%ZL#r{J4# zow84Yo&pCW6h;8xUhXM)y&4o76#pbsgGPv^z@LVh;LgMY9HBbciRTX+f@8*PgBy_fV`*=@|nr33OsZHXV^<0r_ zK@8lJUY?c_;KUFPE&i#oi54eDWfS8_S0SNpeQ&a7dfRscz~Y3&IP;4WyU&`gJ%0VM z(C&>ON`Jq$n2op71h6#=ji5zHra46<1Q=P3t2h8Ir~_9OX8=J9fTobPG)$(1Ss*RTJrm_Cq`}(n zHd~^-lSp3u!OaXO$j-T72lTM!i_(Q2ny z#M@9*knExy6*{Vts>rLP27nU{tI#f@O_az;2giy+1i+Aa1RA(^av0U2bkFNUK~#_! zXFe)QR?9yuCD+GG_kD437+fgy!i1}rTYXCgQ9%-I@~A+vb?l-T6&dy_c0{T`!SLuD zx9f-R8D9K=36nM~3CyE}sTA}fV<9taLYDIur)+V4rvw5K5D;LGP4*ZzgCIJ`W%u-* zeY{9ymBW`7dwVR|dcI1QSB=yrP8aij1wsOEw;6qG>^hI)z4MIC*5xpZD-pl)ZS#OR zcQ07XiEZ+-xKBXRlXahD1UNB(ZR*uM58f&Szx3QK96lTX7AxSta?v*@XL<&9q2Wd> z%03ZEAV3K0MyCnZ%%@CA%3MhdckI)2HfmmUr07}z_fNW;|=>3uQJyUA# zI~Lwx$Ta6#CARl#tJYO9>z|+dX1(0}bG97LQ`h90?we#rv6xVeW_s+Fv;zGd$`vm0 zW}Dq*$Kvm{hRX>=YHjwc?|US-r@(#KJJF9=y(zZdj%F{f2cbgT99l7_|+mT-E`@B`34tjSslIHlvpZ-CgHBAle>am1jqCBBg1LL6J*RsE zTbNPOp)(SwdxcMIfoX(y8YLw%)C|!SYNSzJ+<*p3tRMg-C@F{-fTU4_0DvysMMW`f zA!?Bb5%YS8BmxJphtvR10SNqw1xt)Pj=MLy%!*E5`elO0#_{Jaq&YV)IG{v=pW5s< zq|CF%0dG$~^=exCXyU+z*LNJN+ME?71K?t|OEzK5w(D=aw)Se%VQbICmaUcFK(88p z`~2cr=qVHhw=*3ZLFZd=ByR*M#}j=Ofe8O|%L&Y8aw&xM^|Ns(-J>L-S9! z0IOgUrPOdOu$AEua0UiPcZTTsI!(&_Q2Qy_P3O2MB zC1E^>AkP3fgc2xdIPnMt0|AQDRf7>&YtpofQx`>tT#mL*DOl=<>ro%)68?u=_XYPq z0X}k~>MGOwZS~nAo@s>_Ot-1+o-_XShj*$34|qQm^U_jg}&e4G%KqsheDGeV~?tUs-4>1+9a`Sx$eWH}|{ z{a0wG(I~CarGptVuTcN?dAuO{^HSbVau-#PExrzA=_RJC)f zJ7q3_Pfo#4#`fLiFNLa{?mtvZNXz1JaDn@{ zQ@s}YWobCNlxyhxH}N}%kDL=^AtS(v^L9A4sA97LbxgGQGAjE{t?1-0mJ^$d`te}e zn6#l!MrjI#WJI|@x6P^Z#>9^BoO|(k)d3!lM%4={t9DIoRJKv=am)4WqFvj!?&bwx zWk_QDCsu|n0ymtm-QwVgxwtqCb}UhUrAL?el2gFSkR)2|%FyUxlL(YohM1;APzX6< zBR~p1sQO^ZFluW?;jrcHKSPF>>W-;WhuPr!9y7VPAn*&rVZsj z%2O#WuS@Bq)FWMcdndL1xEajB!?(D2J67wt%C1i1f%%4XD?Yz(>9!qnI_{rX*7;$X z@I{?uyp0NfODHl9BpdCykLyg5fw$vu-jMFoywd&N;y4^O)-Kow?}NkLqgL5HVf=36 zI2`U7`{1G9(?4W4l&Y2e@z8CsZ(6wrC+|eL-9C26t<*9w%Q6uIs{DR+UHBMzkY!#t z%eqL$WH=B_k{ZxNDsU#`2=rPZnnHgx*y4r8D-cHWpEM^z6b(0GfxKw31^`Mn$Kov- zsFH4hyaAp9I||OvkY5=16AR5l+#^`Y^O|+^DCu^0)z|# zm*ZWNy(VN-HtAenNjdN-I?KMLKYC9DGaZTXpP1>Wx{nqnT{k{?M!F%ut@}&p6NudVuvILdBe()`ZeW+;a~R%mf&>s=F6aY=oc<1Ni{|S z<%?@!n1kU6N2-`SD7*tga~N8N*Q;<}n$fxb0s3gA`%+@^0P;j`4CF+?4OY0PplA#O zK`D92uI}nkfhu=(H)d1Ut;<^6n3MO;m*#~66AIh)NIb7Lc~r}rb$99JCvF6mEO*~? zSf0>agBsLlae-m^-(JiS>;2=QeX)pFU8V(%PKoi65s1Vc;(7-TIy3!6RR2L>L8PFZ zsw*@`l_L!j@)ep@P3K3=tTZ@xVDwBAonRO>3{g4JTDri#FO>pf8+HMijl?*UnXO}s zUMnqL4a~W9&BJwMr)e~Y?r$Gg^vBC3@MqFUqW{UvhJ}=_y-ZdY4F3;Y-PQ22(be7H z8R*IMj2;(AJ5suX`Ax5g2~V$ujNlU-xe;OE$IPX|NT3Wdm(?;_VK_o`b=MRRrms8n zx!SrcPEDD$NoOyY{CGF{o9}fNSLWdUMw>sU?_9sb?_}UsyULG#<(@xVMt~DT_>a}A z!6h^BUe4fonfTt2waj*iH*z6_h@KLrFGPxO7)?36`X^vw*a-Z%OGQFWSnSdw0(mMS z$C_Ht{epG`bt>T3@^tm3_qVtQshxtx^la5JT1q~Z|MUEGAfDsbD_YuFM59->c>MIvn0S0W-m{#%uIEB|i$Ot3Je2;vMAq1$4n1^*KmqBSz>5U1cb} z?i6UI1rjk?>C6dyJMxsm8=9(a^A$;o&Reu?$$+Z|f~&O4?mVKn&-$ONpak5X^jq}t zVRF6Ilh=eaeO>!Y!2vH2ud|H~nc4DYG*(t4hP#0=I$JWLFSffR(%1_Ho5 zWNUDZvMtTkD7Z5yMAr=li8-e7tu%7wc)o@_m8Wu2zny!REm;*{d*|(q{dY8x<*R@( zrRvNq{P<&!B?afQU%mI9I(AvR?{lY(=U80i^6NjY%sKL|n`8H1<8GB$QUB!PWA9`H z7;)iI2S@k0SC-;DHT={bxu}tt28>EsrtRTaZUkH}cXrR2))!mI2qa>9u2UoHgEc^FT9#mK#K>O{prKqv7Sz?WEP)WCBH-O?Y{~dx=1`uDX(* zRO0aW?CaJhCqB5DoUr@Y_46lLTr#uc>WiDxmyXOkt?jYpY+`>fHVvHJwbYVluavGa->sJNu9=`~# z#gG_h@>&e^&FuE44;PH|pZ^1MlmuFb-D$hGL818jHC}*gF(lC-qD=dw9my`4zRE0y zoODQXNHDA%t6u|Ap>X+7)pCM#a4as(XiN*l7H6vaHrrBRNfpHLZId1Ho$5LM@47-qvP-6;LL5#yM}?}mVM*;cF3qyFHX?+X1?QYD zTmwwf3#bMAKCW@pvq=P2SqOtOw7*&tx5I;dG$ky987`QKd zql3moS=*>=(l76_dP)fhNx8q}myCzr4e&YhrIw~-(5--quKnjlYkQSfQqE<+->aL4 zXEd(~k_YLaGCif(Mvs|SVogZzJGWX1X3*I?b>D4f+o0(qQ~i>$QKymYlKJGJ;k~MJ zR6$0v@SJt(?_OMa*#7}DA2bR5>QiwvsktY$W<@ zJW`J4Rb=?RY{%zAGni4)8e6zT!BA3av<44Ef)zDS3n>}6K^;&>l+i%uwcyZTE9N+% z6QDz+TELe=WEKu)sFAB_&<6pCv-9{M)oEs0*@!B2)v>Fs`m{@C}dz2(S z4fB9jH(16W9$v}`rzqIwd$;-ptJI6k?vu!-=O0-5#rdyzJL!E}yj=&@9_U)=q7II) zW^c8x+>?5}D)iq*Zs)KdS&&4kJ)big1EfG>4Jd{VOj$Wq=W|A7lbm8yxioG5Xi`V; zs$)Q$*9Zg0rjhX`X(#`UKmsd@fWuKebX6cZ8SkJ2nj$&ADkS5`2uQ~zBfz-99ss7DtkV z$Ot6j>>&ZYw>8|9wP+U*^rU`jMmb)TgO|!DSs~V3>cBMlW#BA=_0GLc#S0d&yPr56-ai(wUEQ+?Vp_Oy+MwX zYEw_RT1WZ5k?8){xZ275wR*z2 zwbV;znFSiebsIxrWCBPFfNA#pYEKeM$@t1umo@PfadAp&C%BEPGGv;EJ&-2HXN@%Epxg%D4i*+BSk5hTX6a7v_T zR>gSYPfuV+hU-mnJMvbp2rUxH@giCdpgT;Ye5-cedYIsA_PX-+*N2*Kf3bLjhtpce z%{f?HR^Z7y``0vB{rKm*_!$N5)6BP7{VXCQz=(oXm6mrCDDtrgzmb=t(!YRA-v1^3>ayf*9nlhjN8)%xYDo|3X~6N^hz<*By* z=jz|MHk9*JSX)ayPvM+Nu-Y*NcrYYB2uHHIoLEkw#0mElxK56xUpY6dMvJh?##FQB z+UY$Dx=$|P@u6}|aI+?Cz3#hMQ49c7c?!^LKa8Tec`EGY+l+fkZVjY>90djxX-wg& z>cVnAV6AvOaA*o^)dS^<(0c6%!6_$eLzE_)r@orkZS!T=hUV*1#tyO%&FL{Ywp~6J zm#5ZKn)ZFla$_po*U)pO#GlV``qSU4fqC18cR`B%iu?%6(^{TLtC6si4|ZX2+igBTq%R z+|ctB;V|_Nj>pIi1dtgUQxZS+)NTOM;%B@vMZo=GHHAi=>K(?WHXXZU{D3p# z*R49xxMI29+bq<$S2vg`+iQxx1P6}cj`5*Zn9vg}vubzkSrk&E*0&2e>a z?G)d|2Nt{=!QwJic#7**z1O!ObiHPL+Zno^!WsWZU~U~e{$ehbw$O^t|3E`Y!NSjp zM)Qk~d5O718aRMjPQmE(7pjsX5JL;-jO|g>n&K)zw=2)fGo3=KpE}#_lZWfuwW~|~ zN@Q^z)JCn=-SPuB6HI74U!|v{C$*pkasvT`VNY?bxayoA^w?k|I-b&JfoSC%Xsmw* zK$CfD&yr!0ts|2h3ct18ljn7la>aA^l7CrKt*0~=Bm00c1wQ*VA(mC`sSF(Y|1%OU zzf5#0rp6X1Huy|}j#nNm0A)C8^=%}NNs$3YD5qes795l-LgP(DSeC*}7PY?fo2EsL zy4RuolPOQuAF`jex7~w3IV)N=xp@{v?ZnO|S)Ja6XXFs2nM+(}Mzay=9~x zLf%O}pUd008bdxxo775(Wc~ZZ`EHQ z+p=Osz zvdji3m*BqMbGz%W>9*NA`jmKi%euy}z$0oe%NaEcQ8~<7GElo{fz#8rR`vgacMRKk zxLK{ToV{BnPpDXjeVTdL=11PPvG@M2cMM5($@B{$V#o;xq`MaktBcpIE5ASW*L}%O z&<(xGHj_CEGg}u`4W<&Iz&F`IUy&u0An?-A zpaK!30*T<)ifD$^D&WN4;1l$;fYfNRav*GF5J*u_Wmssmgl$UNg93xxv}3mY$3C9%@tB zQf=ZgD%X&2O>^Ud0aygGIw)I3ft9GgCx`QKwtousCwGX#cN{7aT{-Sjaq1 z3ZHP7C29oniWn7t)0=E0<(M@11Mjo5mB$v0F!wOH(jd7xNNG@Pfpqw4S#03Y6jqn> z!y7nQOpK`7g(u+dNT3CykPo>QTDE#*Ad-R`l<5(`ZD_dTc~by{e|m+67`TC77gqeB zp{f^zNwYT#B#=wL=o>zD!4uJ@S#lYb{i;Ean=Xs*)(<$Hdn(=hdP2=6yR|G?Gk}$p z3+%jq*5ey92c2zEEJ@?6v&G|`@L9X2`6zo#6j^kqM8ecE^g0xB!tv0P1bsEVo znO+ZyUR5|cjbK=%b^(vpWKp-ba%(b_3#3JiKqTxz7C|K^+H%Q*kUnHN?putX_JP=E?fdbK*43R2rgx(ZL9<)TnYlaR7B_E0s8bvAq@bEvjCNuw8f63E> z&rOv)j85;_iZ6G_^&vH(O6hM;t#>?KSafkGm}e=zS}mEyrv|Dr4=NHcwX&o(dqIKD2)Wo^>Tm`ZM%qfk=8T`S5 zl!n|;q4_x9(}QXxT&M z-#UT@&C@Y<7MK7@j59p}B1fHdvv4jIjX=Fkw(ud(viIyXdHF0b0g^YQgbhB>_*>wDno<5_Cw1l{9?brwe&)gB{ue3G;y zy7!(h71FdFqe&(Q9}n=V-6MvbdED2l6+`HU9zDt7!oD1svEM9&WT_DCj!;p@mHum{2^_~*A{cH9K zY3454h{ZQo%Wa|HSMIPWw37z}ZV>qKO?gP;tvD=-;p0+>GATYqDUgDOeJQwM_&tR2 zB6gI^r+6AU7Vik*G_yP)*_z_P{^6IC&-Wi$s8`~)@h8h3@`pZjN2) z=+Y;fho;rA;QhyHeV2b_LfAF_0fGx}pYa^Dq)kC(R^#+19 zgHYU7Y?W70jS?FHzz{PwEs($)G1!AO02U?^fkJN&UkEmoFZd36Bsc}TM3r#YMHb1iOdmJ#5@V;a?U$m=y{GngmNUmxup zGN*R7PWw-c8CN!Rxn{wmk!sHvjLIe*;Ga-V)xt1y%HfMZ9FEw%|J~CA16rcz7MAZC z17nzyOv^~1?m}2>f$<>)s}vxB6ATwhBm`?022=oEsYsn61uc@nE>J`rVrM)+xi0z` zaeTM{3W}owTTCD=p#Q1o7COK7@A8f@)sHoJIc?P`AFtQ#<=wRvxbjM3oarmCj%H~A+WG^BzH9we*BpF3OEL4XN_#(Cum@LO zNuq&WR6P!6)M+HU7+oYPC=bxQSIGpDVae?h7X1>>DvvN#$%97y;YbA|n>!t%P<{{^ z;DD#_)Ph<8QY_Nwg|t!)63}oX7T8Y1KPZnYG`C}b5QOCG)*9K3I-V`$O>4B2Ml%ci z87SN@@sw&`Xu*~jA3fH0bNsry+q^!B* z2}7G}M=IPZ68~~_Tu8h6k3BbDY|?BmtE`&YK9^$8x`G)}K{-{EkWuA`k&I6~a`B)b^OE?h`q8k-ap4Idl5x$n3I zKF3}qXi^_~9Qt*?LC&EKvgVWTlE5xaO=OrL!<-wL}IASy_VGaD7!F?Vx# z$5f@KG0|`d~mS{DVb48E`mZ3)8)`H0KCt3IJ%%;kbbsBxJy!R2aZGfv@V%IU2Z5 z<%<^aLW@c?y`UyqXyxY|zG{smiETUpRD^|+&pC)0Y7jSRR<}Xs9Cy5@=A`%VO=A~D z)eZU4;b^Tgw_kvhE_PXT_qRE^I-J@bt}PSW^K2WJJJr_tn$u^tl=phlBIh_(WCMVO zPx~c2@y@xi>xtJNdh9>H=EJ+wetT$~A~Udwl)HDhnR`m#tycn@r?(w_JJuuXW(yxB z=508iurJP_&$8@YJ-qqg~A4j7At~ znVr$VuiqFMi`vM;G0nTVr%$wiGa5m(+8K@L6Ff*rc2SDTV_4_tv@5yhcbi@f&%K3B2{HHpPD{i9IuhFO=*+n@j1T_`+ zyjK<5H5z1C1MR2@J-oUutq!`l%oD?v2VW=wP`3vh7~LMS->uSV6qi%t+DL~WgH^bC zF(a;alo^O3(Y^Ja=EW^;Z#UbLwkb7Ab8g20d&{M5)Se2oK3DQ<)wg{;%u+2YG_n{u z(DIPmL>5;d_vomKhuRfu`_cdErG8_X2ea4r7%n4_h_eRNjdZ+tY9Rl0!}TMY;GUA` z;5sfdh2$wie2AVBk%oH8+l+b&5>WC!ruS6a6Lz8Vzq@&C?=$g2e8X9djx>lJ!Qw(y zc*^>F>5-lrvL`YcG^W;nZv2;dim*t>lx8?sbc$#;j79}$)KdgrKqQ0ECL2?>k8bTq z9#DVL!woC?PdSo&b{A8?m&GNk@RZH6YwO4P*I3GrsSQI~8S+#DE+s>-Nyb!$B*}@O zr*i(|+0SlxxcQYrO{eB8JLKib9^c07j++p};)<&9RFO}Wp-#~cuZjeM9^eo%Iu4 zSM{xH6UmRMjY0lOo{nVe}Tm{RxzgR=iIGuVU-;)4O&rb>M#9( zEzS|FlYq_nB0&O1d9ULsWkSA%^AxE3Sx*61{qw8z+~Zr$pWm`x?$DT_t8#3PFLO!b zw3Eecpu$s5Wz0@I@czOGo_f*Mz?i~iWDwT#lo1b@%u_%=HJ+jYy@jBg$>ymd+onFw zTl7TOpdmNj95~@S`$N@AzgQqiEGj%@_r*Kz!7sOtG&iO;_g4D#ElT7r1B}gDdY&>e zApasy(K4kKDuSalCi9fb>fW`A+e}z7gr#x?oTxcyz>76qSzNjbPg(YPzc=@}cGLJV zwfRY3<70}(Wg%F3`qA^0USByPvz`+B@$CLL=Bc7mRD_#tzFgb(MtMdrO{dzKMob1%F<-Q%5MX6z2L{xmIuLtrx={0-jx@5qe6}P zXIAMNAoqX7Q#VF*ALVoPWsk}$MlJp$Bx`AhI9nDsmI_Z<6&qt7ka+MGKc=>J4iP+s zGXyZDQ_o;k7*qP>q!EbS@K!&jWFnBKXtE3$AvV}WktUm`%HFjpRygTnvE8pD22Xum zD0OYsU-CQEDm-O#eH1fflEsJlT=v_Vtn{85B|AQ`f*q)c!vSSa;ZzbVWj{(nW&%<( zrUVZOd(*8bDyKiMn!Rd8*5T@bZ&oQOm2!6MT7bomMvbQ$YO-sFc;~*)d1{;g2vd$J z^h5@Ot7Z(AJY|ehuU+g4Thw?;-~>HI!HUVoRJCS5)0{lFx6U{9P4<1;4+bB8lsA@z z5`?0{Qx2D0()um@QJ2qt+p|wr@RYz?e=nQKg=U5ajEy;gUf9dbEg)rki2{0qfo(cT z4l1OBf>eq{;)qDhI8T}4CAxtP*&Ev{wkxrrNB=yrGcLBuy|n!_7T2T9!R3WF1XY=_ zDmgA-bn?x0HZFZaWCS=dghy14=El_aquWGJ>3#`}((T39iJlT@NuDy)LC0zW8*DG9 zV6YY(lzB?t1t-H`tOpuXrtnn%3O{28y>aT(V}H*DF&oCu+4khI{QlI0yVIK_pF0+{ zWc9$0s~aX?Y93Xl4~r?K3l_b0uVw>mrS9~J#$$tNnv_ zRU6*vX`ZZ6mqt0=TG&oTfD;4Q`rfGWGPx1TsZbsNMB#BvHokB&o-N3b5X9s>0?*$6IiuI8eq z!*+PL|F*bLr=6u{Z%Mt>kwqf-&H2_Jo3&d}%jVpkncGG#56{uTA_{z7Te+Bz+5QlW zVDMWUI~NjPWMx2Kel9aKr4b~^JR_M;k&E09dJLf={GtUxiW?xx2rGrIFfx&+3O>27 zNh~nEa(v3C`5j&7&$Nti@KgJI&G-Go7rrkLF|f?#^TXyHsT`d&JhmT;3*NU@(`M%8 z6Diql%yg-I%-Y*_gxw?=fkf;%@6(SWe*1RN8kAplzCQjtzwobL@2YkFw=MWwyX(U% z)wWO^jWGJq2$l_FDJDsf{;<|^)th*yYqoOO<{f!*$nawGYlZ9>S9U6UheaazjmkIixTn=QPkr2L z$WxHNFhGPoFB4c+avzVws3i<~5eKizUaR6saU9A`^Ku4ArOq zR!Br+R6|9NQ9=(rJW6zu5>tdUlE+0&#LQ5W*Yu#Mq=!kRhEl>W^6JNQMgD!xx#!+< zZu@lH{^p67k_KW?!v}_!(M? z63gfusHh|zAX|#2nncoBd*=Er`u!u&c9W-*TTSKK^By_3zKis#FW=9n>RU1AjhgT3 zuCl<#KYC@29D5;h^2c#B1}Zav6;|8dMDg{@g#xB`86}GRt+SW$UVBmH#izy>32!h& zZdhOt{uiBu03u88lOh(F7!gqtz)WH8pgc)-N?xdjmgi>FvYU4Lz=d%z1jV)N<{Dr zeH9pP!_m>yNztzQux9K&8*NwXEl*!rJ&0X(K2+vj#DSk~*`?aWn$|w?y1{e#p|0Xg z`Z*^PyA1_JR^11u$2@5>IFQ)r5c=TOG!4U<;qF<#pZs>hBJ-^_C9lWFD{l*lE3Zxd zagy~P268DiXO~`YKGC|&W8K)wD4W|QDXRr;FFUi(*w|ULP22DEbb+tS7t^dc9+^=x zsD`LE5I`U^iyM8#3j63dQ&%8Xa5O4HN|FeXWFVD5liZAVP!44z_MjlJH6^~pkRc6V z5+*FEj*=oM!UbG&@DG_q9bp5MY#$Fu>^46*soMVR&=-&X|t$cCwmx!qJoW1uo04&R{aoUK_6jDwW}#(nru zwZzl&%wzq@o=Y~(j!P(y%Ztu3smiu0`F4GoMebpmXjbE>x`nU|O#+pHG!CE0uUyKM zIwX<}feGb_B%=f*>_>3#K-wc2K5DBTR%o;CYZT04HG{y&p>!5z7!3L!cWGVm9GMgpvF_ z&9mqCXV1#nomM@;+pA`Ch6{)<(rrYzb)Ay;51LaJvtBUQ(`HR^ z35muO6FvpPmt4b>JPLN7-q!svBYx~3=hkz(sxl60w|8#kCn?XHYWG6vXTjpn?i#%{ zi7Okj$Yj`?skiHeIC+5INt4j(pQDPE)0GB|AKOS{_+gBfYqx(% z4LEa()13TGeTUB1X?&YGi>#?qB;j8FS=#$ z1awbbSd-YgWpM1Psh6ak$NT0UNoy&2yz=-Fi`SmTU|ksz6HzgUL5MJm5_cktRb0Hb zQY4TB1BON@2;pg?1QBwj4+Jp-FbY?}6Qcmc>~R={A{)WPpcJdI5y1mLTxS0rvG}gR z)nofLbCuz-`lsIgSf4mdE#?b8t_E^Zf9|l|>K%xA{d4{XtM0H5mXWQGO^a74bKG-N zCZ{fo86o#6#zk0K{xpC442@#_&|2+?qbltrt5`)}X*w{*mE%U3+j0 z1Wa(B4+oJoOG-oJ_N-TG+#yy+gEWHAJ}lhfR4M?+K)_T3zesh&B5So_482A+nz@o0 zvdc;0iM-gcaJm>PP+7o@uDqa+1&@(flt2MZ5x){lSYDj4?Ol|I;s|V{;=u#UB7guA z1_A(}6%l;Y@`x!5MF4>y;{bNS$^$YAZh(~sZdk&_5Fm%60nh^g?lOkJK6`Zr1ArVd zBA|FybdeF7fnb=C;Kw6oXc=Gy0zUl(Fj(T@SAYQrzmgfSBc*K9PhZB`knWmlk^eD! zl}$sUyZ3yfm3N&U^9h|juX--3@k^iW=&#_xs=M;z!nJ#(9w9kd749R_q_-mi^6Lu(gqJ!-K^I4@ZY)QBOrLd1ot_35ITyVr)?|h zp$| z?a9_#613`S$h1dV=mJagy94La7^uuRjP;7tq$$Da89Lr}2P&dc!X1A-QU7)E!x_?c zSytVw)>DjAdNd~NsFgx&2k5de!T({GmA|v|?KO%z3b-Wq$JTaaZ;Vs^`{v( z+38YDtzfl@tdgD2&xqHg2flVvf8dkVF|5{8yf`FP%U;udg{L)`xM709Ih6)yjh`*G zc6VMoORf7!v$~n$vPGl5x1W^KvL(u?AxEG7RyC}GOs&SzY^&mXx{eogHo|pp`lI5)Lu<$#c=Bc^FJXSs2jvusMYDKxj#e6fKhnzi1rXhxF&v!3Z7OOB}1QQS!d z#jZ_Ff(e#3jc2L~i&~9hale8h z$A`nu!L;T_RxKJogL9p*h*Efp8y!ljn`qbzG`CZ)T zdjEm=#v+P|L%>gl-11N&pIk5sk%&z|fal?PE`dd`8z@HH#G5n(27l1v0T|OVV zgkb`DY5_=)gu;o8$S9O}jssXZf+D&K4G`sp0Cuo2LTC|}C9M@P3*@$T9!zp+)QXofS`SCnc-6N#h%dvrWV`kTRf z56mBD$_tV6uGlf!+23?`K$B`0+PN5NT?_xY`ThroT#RNJr_@FyX8bW@-h`P=am7tH zC#<~sEO|kr3r#mnG;_VBT4u0Ti|PXsW;G6Fwoa;6VYM#bGVsp%_YN_~ldaT;=Y5~> zmAjMHCs>!7RI$1|4PDu}cpG}}SZK1^5MP()svver1g&N>+@yL9xj$KFo@nJLuDl-AA zssrQ7cO4sDKk(otYeB%iHADQo>&h}mOKTjfZdU7i8i((8{8xF`nbRa#DYwG^hd@4D&Yy$3j;H9ovT+eYb`@eT$2r zl+vOx2yo=Ur;q_C9?Ud6i6+M`Pe?^+T;hz7k0->SRK*02lq4=gKqMzIq-8j9A_g7^ zLMR8Gpp_ADUBNJFdiA@k!th4pWpA(TL9R?~DjucbFYPc|c45Tfsz}v+u3MBA@s`_; zduEgA%BNa#c*R?zqnn#6XoIJ;6=@xJEq zWeu0kXKObNwpPp81WpI*C8_32>%5o*E7rn4S$eM`-Dj@LAp0Q8>HfzyJq|UkJ?Hz+ zq{Uz9XC+Th&0yJ92cnr2t2Cd>&REVw1>Wweb@R$WnHeyOQ37~1I))qF{P{`z5wdq~ z7!`D=-c|;%A|#F|#}uSUF5z8@&LdS%qpIoL2sTl=oOV{27{&!8eD1v7&GXRHk*^$I zwD8Td%+J*7m0vDWbZK8G*fZA4<><+g*(b`jA6u=47#&TgFB~s){u-HIIOXPr<=nvF zA=|EM2YTyJ6`8ij?+Ho?33+j`Vd&@U+fyH;er79>yUmSm$&JU_0l}E@3kStOG7%mV z=6EC)A6TM6jfl_~fT0l#;PCJ(^g{R+8_II(q(T(q!i`gYq&V=cEB<2D)t$sCimaAvi~ zLc^je+da(2N%hRgY8>=kGtwZYJ20+4HYr&hBb9NZhsXQ<@Z${N8+NAr-odTPbFx8+(N%iIhYqenvEKwd}I)f^Lv0QG>>mL7b#7w7e2ly;q5*2^Lam33N z(nhu-2hFFu%wF%lIMq04uI!xH0B>tkKB)@3zg>4EU%zs};TS!=Nk8wp^t;Mu_48>A zVrH(I^2_CoOAvgy3=<5N%M*Rfs%I|@QQr6_VqarHa-F}1?dAo=W3~nEDV*T`13KBH_VGn1LwNixaiwtScF%T-E^q_aGXQlygq z^^``tVvEHeS4bFFe6{}L3h0XMQn~c?m*4mTKX#-N3K>#*2rMxI|FlaM8rj7h6qa8q z5t)JIVUaik^VjFEjlOdte8s~0PpWPvh8f0mTy>(2ywchH;fkD(9*Gqnom=aBa?hB8 z<_qIj)Y<-Fc>1Pt4qpaz|5A1TI|Zuj&7zTSt9DS>zBg+=-#8^?S7pVKY!O5M<=<*Q zm7O-Uukff!MDH>4jlDeDi5O665N^HZf`o11&NFEjB)pM3UL zees*Fhj_zGVnonI3PJt`wEhhZLn1IZ8pZWmSRiT4?+*OfVwmV&J1}-;>W}{Kjq82r zawJvboZ zYvXU{V;0Fp3<9%k>!jD~R$A62L3{zdR)5*MzuHoQjQ=_a^jhePyl;Pe0apmX7qVuB ze|*8NmSmp>YVC{PhBcKqAsSA&isBho#Lh+~F$V>L6&ks?8VHWya4I>eQWlCjn}hS# zRqJtWoUcJpk0%p%Zz^-%q8DMJ5cEhS4s{ZK9_-*p?4Q*>#%bDx+kHa!-4HRL%mCKw zy5!+ey4MsxX#BDF*10X3Lt}Jai3J-po?M- z3gYORG?6}#;D|F+;3x{gI(*VuuZ^E|>fk%m<&{$1&W~I%ut}`EQl&`>UJU?}ccfQ$ z%beUTWNoEgrh`Y7t=-?Xn}`8rhOqJKc#`h5hFv3smQv;VpDCv)^*T!BB^qkKVIjUU zWgJFwegnN$)Xmg&aY900#L57(N+0AT(K%ofiQ_JcMRiEPs@iMmGG+(?fm{+~D5b4* zbZMIH*(Jhu*1Kyj=cPU%%sPbjKj4$E;1t3<;)(r^3xh^os$#n9X8o&`B6`J#ks=0^ z8Ny|INmc;kaDu_Q_UfDYvG3cTN!|PSCFwKuz{jM$t9NI__Z}n2nrk?v1LqH)*W zB8FlaNB1M6alUp}cYZA;Hf4rMFe|LT!ymkA4P$FgcJOq??=!$ zrD32{Zt`Ud>_>!fs+0gqBxsib!mrHf7*u?Jw*&0v%yFGnz=r&zBmGedgG$JA3k~Ydb)RJ&%pN6E6x6tqhB`d z+rC{;{WZ6l`;zmwW}PNQSY-Adnh8-H@qsjqex=DWL-o$akX zM5hNF#V0e5g~m7EKZ(kp8jTbDP+{v_Y0b(9fz@mqRQ?t;uKccu#}|^$Mm{NNSVupu z@W@&DJyS z>d@mE2wzzHs9uK+?#zf_J}GraVI4^vgu3FRGCo9+H_0rU!-YMu8A zoL}(00$RwmnqaN&A?SFe!ECAAT(SKxtzFpgEyRA+)dIyBX(46jFA|-uAPvkLY~p7t z4gn`B6?PfL6Ino*KvXG3%0~PQMUx0IgJ1}cSIVX;^_`-xoH)}XsA5`^oe>@M4$kbd z|Li8i@%il)U*o2_e5$1Ixu0t=Dz99ajm4}!l}03&yjb=|Ox)F~S-ljz94t^fJVoyT zmckD{B}9>fkF8CCM5P}sx*^3Ppho&nQ=cN05JV+S^um)l2zwE*k_NiH z#Y3t{B?O_`J_v~h?aMaVsft6(|8craxkA()RoLEM>8XlSDVHi`YEnYqSYo6nH8e9f zD7tb33lHq*8Lp5T7x?$NLXO#}_apw+?(k=+2@Bd(p6g>$FukqCg)@4A3Kdl<#oFN- z7$lP4GWaaHFj2j6243@fUf<$#*Ky*(f(XB}Q|Eq|(0rCfZdSv&<-NalDj4!x(Xe0q zmO&!XU_CUB-j*@{xce`KVab1WN>dutk;*Mv_2hg}O*mbZm<~5iR0BCZL(q{-OfiDY zOoU@PE}Vb}iG&iQiy(fk6JgN;2`U$z#h^uu0(zP>Vyv)Go!U@A5T=C7bB;txBuW{P z-#g^q`BtSt}j~k|Myk^POYyqzJ|Xil~KLd(A4UKYk~oRlMLp%Z`F+YZOLy~^@CgJsc&J| z>zO>OlskOjvRC&`bRWFqjdX!X^t(x26Bcw>G^0yY{UI6eKLnq8oPW3IT3uB+XOv3b zin>+u>5*i&zQDN9rk6eH9;{DJKKyFs#bvGf)SBcb(e@e!cY+$N7cn3P3dT)S=ef?8 zUxXb@xK)0CT7222S7n#Houc~PGC%UFhfDv|njZ1ttdD*De{KCa`9fKf*TCgC$^S@yD54xWRTOOfs7*ok zv6?fXak}UaxDyn)T$?r#jGLy;bN^U>;B_lyt)%kO?@w`?M(iSvLcPf1coa*7p$P;q zg2xL08yq2msZ0qp79t^mi;`SU)AUG?5#SG02B8qjB4I%_abXg{voV{|$>Ler1SrD4 zB8lWMO8o};)9_m#?G+CT3(}Xhksa{*d~Ho+f!`h3D{phBP9=JsBR1{3Q>JeZw_yrkg{#gX$5K!3M0mS^&Z$u zmj3-`*MRlweKyT``CxcWKW*cwM%{;c4(asZ@Y|IczuZ0ry*#}pWzO1F>WmvY{!;G- zi%V|41g`#Zf{TCkFIhTx|Jwz%f|njdeZj*Y{OTX)7xh>F zT&wXG>lWZ0uQUvi%FAxs&n>lp8qr8*)xynMVFkl*Fu}uEY#2#^ivx)f;6N5eGPtY?Ol}!>+i`mS!&7%3ZENNn9Wi)a%VqByD~ibD5z?ua zalSp2#*4%N@S+(-&3Y*9(iS?Jfnjs(ZKVm}k4xlS znZ0Mz(B@k@nA~{eS}OhXjz{i0`)1r4ZmxKk{I0ay%pS9=BBYTTtvEY#!>X0=2nCYGViF^$WIeI9>jKTG0Nk_02=xUNTLrAz$Zipseyxn zbou}RmBh_jD(Jsf)Y<()=jJc@)pO{)GG7u)mhWA*;{NoF7pQ=nImD?nA zQS}8qO8Gv3j4-g^!X|>jR--e11e+nea6e5LVn#d@pJJhae%839z_ht5d=X zQ=mf#tXahfzGOrIkTBvT@OT7J>M8TrMYnGIaJk(nvkLv1Z%kNoI65sTju<+X6v z^r}zZ*BLa$xBqfSc}%bMBJ+x+U19dqO*Sdh%wT%*&Xl2NR$0#S2zT+?Ugo0J_bz8s z`-LdfU!$?ECfHnE=G1HafR=rydGz=992qd8!-T25Cl2pDsZ(H|u~WKF88Nm)K%bDY zeLFVnH{2s&m`6z82IEHt4;?Wycxe5x6a6PZp|PHW4#IEeZ-DgrSi|S=3<|C1^0?IR*XnMBc-y znf=YARG*F8oMvu5Rv~+0;FJKcq|)l9AlLllJ*UsMP*$Qwe|7KC{rs50L8lbFLI4ar zw%XNXs(~ljEIK8!FmP-2CEB>AMB)ajU3BjfM|;Ym@-Cx{rk28bG|Q`EyO~ z;r)d3w?37-9~oB|XO>pQyXBqw1M9U`AgUzFN27Lkz0iNjqbb&w8Dl3zbQv)9BUsyl zr&%heXJH(T*8N|A!HNky`&(s#lZr1W>`-DoB3?nLxQT8-b#pbP!ps$ar;X#GbD{5G zs|aMsP0>|w2NH**!^5x7)_tNo2DoRetGe3Uv4YVrgV4R&ZdBBN?(%Z4O^VIK;2IY; zpNtrLB1HOGfoiNc_(0>2A0{c>T|y%}#pE}!JT$nihyh{NzZm$%{&auvOC#Mum&(s-40OO4d8A-l6rZ?`fr zf4SsR(ou7RjeWFjsX^oN1{$9jb})YI_}s$3=;@n;6zqGs?wG{K0# zPq{1+u+ZX|0RnFHq7%tv>=DWmV?<<8ff-Yj2uI5{qRk;h1iHYggeRiZ+YeSpYUW(6 zR^FG(9F4ns;P#sYW9!H!eV!#B=&t)E;zx({?SF+wd?wfi7ncNlpP{cClpGD zE}u5i|3dXX;71pnYB0WZdm}E+FKQR`e5(lt>lk7kuQbS#%4@be0S2%ILGn>*KB|rD z;NVNG{XqS0vvQc3|>uT35gO!Gn^g?Y7*cNBm+hkNf+n?!3f+wFpOsLcnv))mmyUT-ujz$L zb%)MLYCrR}!})t629z1X@QoP2INZjswiAIy-MF71)fy*j*(g1@K>r6Az&OFh9>BB% zG923N`w~rqMGhrr`6u2}yolPc0t{fBYMl>YoL|%qVA@{TYX4N?9ltjEU->OvW1mJ& zv|Z_d5v?zp8M*uezoid*Q@O{6fED`?bpmKK)6+ukvE+E`_m}^z-_mh@QQs@LRufFt zDa1RTUY9wF(fua`JgNkMTlTArHY8g z6p$%{U@$V6QxJx`tbAhDWx9x*Z4#qCN~Ug{^>b13VxL(=_NQ0*xe8tn00z}vF|tz0 z7rj$egsIXWX z2Ou0>^gtv;M1ZCjL3Aw=kOavB#MGci5I>A)S+D|35G$iqkg!P8ARv*D;4cmQv5A+7 zuy8bPh!Q{^_)|%I1xIjUML&LNn<{^GsZYJZ$7eQt7q#y8?Zf-qAJKMinvmvTn$Su+0iobJ_7tq{&-KS2@}+a@!<@t;@v{D;|j$Q08j2W_r5L5Ag;A zSdDR7?X+q%4tp;ix~q!9cW=(vd2sTAEjn5>YIMxZjZNI|_?I@__R^z*ck7qmtN9EQ z$41n1(uF5#hR&Zuf#`x0T>R*w-^+K;!O(@x%Lbt85V%^**m$$(+hbaS=z>$NZFIr5 z38GJe^NafE!gVQBf-Yg+@oS@}+k6iVTzqKxUB}p+X;;n|#b0@~N89m)J2?evuf{%& zFjqJ}saxxx+eUN)y#gn=*uBDNyIpA3SFgjb1J5GrP;gGCvUXQ3%~l$KUV&4s^In1T zi~3%Hnu>$DR>jc(j(4mYI*+FB-md#-1+!@6Loh}09Ju+0CK`exoO3Vzok+)F-IZU@%3_dYlF$l$v3w^=Jt#jbJIv-;FaT)p5~ z|AK=hOc$+o$vrJ%K$z;imTm!5nur01Q&Y%OLjzk zC>vJ4!@v^1P<06G(6aoD$o?}=MS}s1Q?2s>jPr}y0nE1=VzEv^-tlT5I0(PeyROyy zZFfy?UVYHw*mgU|Y@@TcqxK&U8WZRJ#i-&)1!@oOwEIRyMr2Bsd(JlUzZmKMn?u)#Q#r1HK%$D?dzG{b=I7_EP0+ZG*>>&7EtmjsENt zJ@e{?*=PwLv7;}AojVERFTa_0vAk5My2d{;l>A0eg zj&3d2s+$;=ncHbwb;HRzT90bft&L+Oh;g`j+O`_va~>2mipFN;s{z0!zGqnIqtL-1 zs^W|*c2w2-Sg>y8tv&fQn`EKt1lTw*r(5RHWoPc#f=0us26rfQBi0T%m*^g{xXh!6 zMv+^`_BAi`HL>-7SEFUmZu+xq#qX}cHCoY!Gg$-p-YOU*hPXyk%5F*Jj_HZ~Ru{vz z1mzaTB%T7tHXjuT2F+#=&446;ev{ZAD2oIhpb~~XCJrHs@DtCkGVRJwRk(VB5<<~6bL?NHV~cVdNoF4^S@cW+Rjs&KE(5ixMgQfWhK z<-^r+H{EiNs5eflD`kzw;W`@jo}`}z%cn%V7}CVXWmtfYB9lhPV2$IvrJC!NecmLh zCs^<4_C-Y=i`ILWk&f6q#rR$qRh4Y{_&qnv%!3jC-iwNGe!(xP&@QFM`oE3l9seI# zQgOPKdf+a(Mm5i}ODfeDJ(Ao>>hUp*!>GyWbr@i#aC9sZ1TS%9<7zUG!wEE!BdE>w z5Ve52EC`TnQiX&v#{upLg4=9IoC7}(e*bRNGyhfV-&c<9+UedoJ8dWDd++BDKJJ(1 zl@>APyZM~5;~OP<98vIk0I*^7*P5GV*UquGPPjO_B!z7+6 zI4e}D!bLEzj;UAVsGe>{fKXC|pGS}YQtAy<|BQ)tgCuUKyxN^pV+U92x%GL%^EVq; z{%Wt_b*TX~Fvw$n^8}1mcL|==WL+_yp#avwCtz?j!Bl23ET?tT4|T{9jV)cSmLgAN z$t#S^bLi`7HLaTQnaW{>qEpvs9_~33k%XcSmd9!sY0_R)(OM`*e>Pe|VLk7!6~<+v z7#uv^L@ApgmAATa8J#P+{z~sJGu0>wh1AD%S%RLxxIqGMx)3LB*f6pgK7wQC#{dB< z%@WsSN56DPgOD*d?Y>JRJY zMlCoz;EuL)<;1;#J@+5q_1*GQKhbHA$ytGA&aUu|U!UdqQRG_AAei&b z`ZF3=4+N;7+4K8s?qqY^{91>gHU;O)wS8TGYh_R0OljKf^Y8jco2wPgs3A&=7&Lkg z*M5h57+K75Rh&gw`Q=B*>HZ#}lb;oS&bB;u8Kq<3vKSnV;!a;_P(~_m(?1vuKosVh z4$k{*yZ{g#M&N-R_^Mippn*s_%Fq>QZkC0~kcg&7&}8NSqX^(AA`W3es!Am7IU6|( zfypcb0qVd%I`NSYh$dMacq5$==&9q%dj>yW5}n>XE^1R{p z8b^I~w9$V1;pOrlN7z@}B_BR5d2HPa>zYSyRHs`assHrt{N6!}fn#)W&znZw+BgO^ z4p&dxRzrNwgCfT~v`nlAwb!5eTcM$_$4FDsgGk)FK6a;_x{a1|B z*ym8=jD|Q~-5uT^-cgG)uGqfeeU=!-hPX!$Du zu1Bf;6@VW~fd|r8yhw%!Z0KxiUUaq2oa4#vpHRfP(jkgB2@$g@(KVh zMimWyBu*$Dvk8R4)e{@fFc^_^&b`YTsfEN^`n96qSAe$pInnbxzmUPC*|Uz@FXxcKa`6nW~#%rU2TOVNRj0h^ zw`=f~LyDR&vh_zEdZ1DbE&lfW>@R2Db#8>Ri{Z+PCOHmxBF3R5TSdgq!-*&c3#-+j z7wPx$8rO@9R;}0j;H9s10sY_VUK-m+e_2{~g(e3YjEHwXc_sCV!=<6l`*hH~WUHid z=T&>q6&COY1wF!fhaRK2fy%93051V6Fo|ChksJo(>^cXDB@|6%-Z#Qh*^Hzq^Z{sP zBL(=mkR}rXu_z>n2M}w%g~S;$61)vXt1%d*eiR7%(>>OBJ2_j9_ECIyvRUboy;A00kiUZkiS`oalCX*a4Nh^9st|C^he@OeVl4+()qdZl3%UXIbQ3w zxBR=MJGAY>>zrTjsQda>;}whYYS&wzWHGzHNrHki0p>dw1xu$zojoz6;8M^i{i)_P zZslGOF`&%)b?zN1ljKYfN7Hr=pplS+I&_p5yrG9D9R36rO zL07IkNOm*qY2e)<>C*Xk*SBfgj}W0esNf+06bx_OdD81MwKn|lnzqib;Kydu*wrEi zgxONr^8AK72MZ7XTgK%#4+_|AHn)47);lMrmOJBZFe#*qI^&KWaemMwvcXRm9T}%l zcg>a+zhCW9F@CiE)zmLpl`cOjA9zTeaXmjIC&Vr8YHSUR3yn*0u9?-uy2`xVfVmx( z*H3G9eWbR{s!_K_>yc*VL0}xN9x!f6gpu(X&kuGJf;KPSChaoW#Ju!tzhw>A`@O2O zXUj_)E75stG>%s&0OleI0$zaVEym8K-Ej+Gnu}mZ8aLd8s&KsV!<68MHDut?95=-R zs^NiRIN2f0GLiH+hE?D-Fyw$R5?UA}#BqrgAiPgckGGc#4`2aIaO`MKas_6KQ5WH% zE|FZxsc~Z;tAVfEHg1;gllrn!Ck3Yl=D5x(VnCSB2X7r)wP#&hxQtU{oK_29jmF{D zGwK$=%_0Y^xVPu}oFM|sHrrBtuI0AXz%jbm|J0~kn^uz`#^LH|8=6EX z&K49XQe(3s%=#8*T%B7i9s30=zH!DCd+}Xn`_|^frWz-`T~ZKr2q?|JM+DWgTetV3 zx{&=(F24Dpgjgg3xkjUJ$8#OHmfvEeXf|f$!mVFKHARIY;g6wmXfE23Y$b}#2@b)Q zSw0mkO=L-&B(_44j0u8zlKDJ^1nVy~ui4;vL;!O;UhaoG`i6EnwFiGay^J`~H1|x^ z(&M%5!m$qaSBFX?uWutC4!(TdqN~2uCT9hzOPf31Y=}|bvwz6x+wpLMwY?n=cY=T4 zIFSVOR9X0s4 zK}awekx0@!1bzJ7A%6q7muJrV2X#}H#oKS}T)M%`A-y(y*t($}XiBZ_mcc1epva_o zHDX6?cM9EH?&Z+|tC|~rPRTA1F`ZoPH!5Q={IpxeZcFeVTz2gNK+SZC5+p<4rK z637Yt!aJPcuUsGrq6r8{Ncvdxz*hu9kvG*9Wu#@%QmSx7f&-8o$RnXiw6y{rNQaFE zO;xv2qDk<;JbZBXZufF;w)DE{-g-{AZ|nQ`hA%mHU)z`v|EW23s>-&XX77hoSkveA z%pUzmn<{uc0Ki@Kix^PmQXSqj+B4F?4a_ZSjMHkRq|rFs?_26tN`;aiY03!vkLS2pz#Sj1~y8B$lalu><23nCwno5y$#vGLTyTJH#>D%4(c83n%>N_nk zui_XPzTIw5sA_kOM(r4HGE+>6` z|1IMtO4G+ZYrV&{bH8z8Ka?n6=gadJi_{t?m71;3>Fnh6Zy9%YeY}bL{Aqd#AuGKGt2ItfuR`m?i>6Ek#_1cMkE~c2>waXv^2aJ_m04_UcOPw=wF!7Xd)baH zcO1R*%E2tVd9_W0eMX6NYh_$1qDzZoi=9o>8>iKTRXpR+TNY9H{r%*#&H=~Z%^q6cD2apw3~16L`S>NWg{=hzi}0{6rvSpRK)=#Sgrq5SoKxx_ z0?#Ique}?8=}~e) z8h5e99XpW(L|sLjyqk~SxzjiC;_7KTL^WEEbJ5>0POBkWJmb(|iNJYJD%P^I*j-qt zlpc+C$osVYYp+^eSB#)c>q$TLir9Mm7;v3MyEp5T2PafW&kp#!=AcKZ2d!g1$QOC7 zyzqI(h7OK$@$Jn>t1zHm!%rg5Z2R8xz_+16nNx07lqKL?wnYzFSW~YoHYJr1~I70q*_<3rr*vN4^GwUMMs({hXO_5S^%Zv zx*$r&z&;opiXzYg0`onezP9YO2Yz}Q-K3^?UJxUY;KHK;07C{JlL$}{q60)jjNl-i zk;cLjyFvmPh15jr02t_iyd*@^A&NdQAjGL8hAKuvs{oz=_JKdu#MGb(%(Z2B+j}|I z=Eqzs99{kE`LeYG-|SC(rEMHYsWJL-x8#r}T@pW!_z?9_?zFqc0|lzN!Ql|U5n0N+ zd&4WXviUK@V0XB6nuq~mp13W%_2JbnkKmW})EK8#9MEVSb~hRs`v~~0{$eZNkVCJV zUjWAGVkcaqW3a{{-V%X^i=KOR|1c~FTwCG<7yH`MP|<8usjG#a)$TSF=@SY*6IV|u zx#>>Dd~j`vQw@5QR@asqPaDUe_S%x~Qi8#{g?PvR2OezabSq2jmC8LAHe#_J{pWMeHtWB?HP zRgoc35(x<*+8Usi05JHoP=K6Itf_oiqBPv5l(vc9ky2rdUjOU9rMp=4vOO2FVprO+ z@nC^wc)&R)KFECEUX$)-cTTNc*i2TvpoHU`?8iobbGiE zwE+YBU~njkLJP%#L43oyZ@6|l#KrQCLXE+^bJQEB)y$yLI9!lXx9eDN(4kY6Tl*^o z>1bxabsLdmwoEy>YQWx?5zi}(DgDJJbXsoXSK>#lP%r9T8oRul?B!E1GvEXlduEW- zyKUTRbi;2QHq1cPA#lx>)313)wcDixGXqYw&SwUkU)0VFe3wEj)+xw4UN?_a;Z9D0 z8mzHTBg|Ek)&$?UpV@Z?=oL7@#qJfZRmYSM^L{llXX`pd9ReC`wUwRxR=&OeZqO@m zs&(EgaDGwSD-cWZAlIsRs)To}8aj`rzsc06{U>Hmg-0WR_%|$sz|M&fLlvE&MU2`N zNIW||$*Q4oHL$A-nn=(q1MHm7R;Itnbi<+IzRb7LbI0i`3NB^6kes{dz7%u?t)lu5 z|90~;Ee$)YPkwsibj=yP4~@DizIRibsLrqbmHI!V@_u&f(3av)R|c9ueG)HE2$a!? z5=y)@h~nx4Q4kPA+VCDmwV)0(a_{{r5{pWS}2u_2V|~1Vy^FvYt0?8s2m56#=uqbRK1$ z{nWJdJM-!743~E5lXz%qTZh7M>B4T4ZW!Fqf$p`@R)KF!-*jIc{wQg6&f#bGH?64f zwby^vF?yk2!`Jn6GEmp0+ABOutiIoAVQAG%dn^CDE4uAnlT|j;J*al*_&$f5t$#VS zzDCE09}&R0K-7f13 zs6A>lE==>`SPekGY}+feGba9T<02m3@Fq>(Oy33;<2b>^UW}L7 zUa?Qtj!zGcKU)TEC;^t{zmz&WI4uEpiWXp1>wGbe^Gop;<6M^$&PW9Djul}s1*M5Z zDjytR!UcKy#&+hDED{RkXCnv+AGLu5P-cduOdv_(wq`MKJ%GimWAPu%N-)7 zc0W=w`)0=FK?90wQN1m@CF%qEH?eu=b8OxhFnQ%^f+nO8Eb#NH%sRB_ZI2y)GhGq z$!|V6+l<>>Tzaxw%O^JG%b?C*c zH(#0_vk`yzRikmJ7bSW%$vuW1zkp+KHfy_r6NzREBFAWF9FS0A;ru=7jMMTybDVDR z3QpC0s9Y5X%ld=9+50v0TNOIOWk~*y=;<}b9$LnZ34V>}AV)Q#li%uUsEP~9+m0cp8wm`w@gE_8miWqoibg=7Y zJZUtJ*9`$hPR2*WeFeZVxE9rRJZU^{?TnL1%=0_US&z1DwEE28JI2^-oqXBIl&Tw?V zfV+3F(O|Zsp;e~Kn$U@LSNk2duGS-BTE|jDAEqwszwX-84So^Tl;1?w0cX8- z3@T^B_&zlnCm6)CRW4UI5#P?4yY?~g9=<0nTNuOBqwUW@T>y}d-ban_43 z(QwLDa9S5Zuf`fbTrvNI|K(;;BmlW=@#uj?DNsO`TLOvEgjSbOBu|Em zOIS_7NQf#tRRqwhJ3SGKDX_8$Ac^2k4`m~{g3_Slf8zR4GP_f1xsubifo}4zTtDJI za;)HdP$UWu@|mT0$OIJkbq2`={a zBkhC?hZYn2sk!;13RlN(>R%i{bA91R6e*K8^OYyHCxh_|vwGjk#EKO6Eb43=Oh4c{EWJ6ss{k+DDIAw7 zj-(NUDAuDqU>cy%G6xq$G6A2x6;L#@aCNXqj;NA@?@h=6ih^j8-*bi~KFNy6g9uoQ zdB8QYWcyE}4!hTz61ulZ=LPq7t@N9>TH7`40pmckc@7~jQe(DN4B3_Yc8nq`UBO!b z0Bs&{9bWmw$o^K>=m%VJg0+3X6?cMv-#C#3^i)|mh2Hxfv7Ej?pAZ-*cGrl;NQ<-$ zjfM*aZaqSZTh$DZ2=K=ziicPLwycoE3P_#+7bN1fi}i&BYy@} z4_Oso_H0#~P@DK#1<%KPoviH$)Tq06rLT??Glrh)zc78^xPV^w3g)*Rt`Hf76r|Mr zgcqll&H}R(PH^#ODLrYHq+OtGWtVJ38ww7N^R_rUs98AN`^Kr(`7DL=%iox#*j7bP z357YwqBtC^lp0IrBcAGWd*3*o{}Ego?Te8uO#k>olBP6MO6B9aY-4<(M}R(HED^3N zVHr&X4D(V_d<6^{2pIjrTi8L+2eW_?J7-Yr8iElBqyqp{h6&CUkPH4Hvlao03^y%_ zzMt8G0!R)`@Y9_Ie2pixhfeft!_?$ZYz{O4JWuu(A;zt-H`7#OFE zi&ESPigasjyq8IA z`6AD$wkhox-E^tN+q;;(IYFyU55CMAH*&lwK5;`4q*8Fr=tdq@e$x2ug&|r$ogf1%75NLSYd4YVZu&XUT;+Y8duz znl#pb?@=>HHFSxF4$jAYHT5+OK(nw0y}d_ePpPe@K8uz<_&r@cRfGM_nx0QQovTn^ zA5wt-?0(N7G0-$b(E7MQiqf@*rG$n$8iTNg`fAA<{HwN}mIUXT4Zm222h8%#kT|~x zR^&SGr(CO;w{LFWYO!L+H)>F-B+-0&Y5jl z+w0Y`)l#7fyYrX4?$)2Lud=qpGZD-=oa1VI6h5(63;fMKM#icq4Tk}-Pl zy)g1n$=y+oaWOO)3@Hlf4I2Qy9o9-JpD<`OY$-xup(GOUpH1*CXeLo?PG`_9 zLX&_Wr-cO31cG26i4hoBi1Vz_Qoszvm#_q7k>F2ATrB~^K{yI4n*coU4>>PpuY!a~ znEpe1(9LJvxx9YKzqbcH^=I4g$Ily`8EYmPawMkV+QD<|WeVB>m;+*5SlhO{x<|Ar zeWp_I4ePL#b+!h(wbr%|Yt-H4dhE)|WzP55GR@o2a`-FKv30*NHO86P#3w&0aVusN z3HG3If{VQet>0j((znWjje(QhFfM_p((z5wmezc74n87_Q?2toXq;b)zX#2=D*o&Q z$KvS%R%tjvDi65v015MuNC_Omex3-)&$k54${cAB9E6xc!tu{1nJ~ItX#z#>HF7^P zF?@O?$g43TWQZ)bE~L^4&{Px4BGL(i2f!0xXA%7UCMgYugS{6jDeFb{!i`fZMD;zr zIlOg3%CW$Ot0Sb-A;XEL+{vR|>E8UzOf5kXm+}EVhIIWtsgj-Lq7Uf@+17!wmRj(W~Tmo(v#i<51iCzf^8DPIJM8HY4yW^M&l6O63%f-<0?{l zaM%fE!l7Vj28%dh^~l%Zg1GQ)9r)Xlk;DQ%@PqJEpoSj&aSH+OAXBhfR5Sen{rYwP`2ws~)jk8D)x$>m zraSCyt*=qT{TuD3QsS@HeLqM1D~QMdBbVtZdaH+kp!cslY*aks)H>!LeAq~0G-*Qk}+skOlrM zE!%^mqbG-@lc}BG^qBK+E6^*S6bej3c<_SKy2TI3dvJX0Y2&+j-%xebdk1 z?eCl+UVUwS&9uQ=j)TmqS@`_iEJ0)~H zfbaIId6p=5Oux!2TvEL!clx~Oy6Mvv{_oCIY%sT5!WXZI)?Z59?jCFbQzn9E?EM)1&I1mN1{uO)UlMX!d?8bAWG=;0Vp zA`6R57B9ub+&~z;`8uxY3d4C*a=hxd+*IZBm#tTf&zE`xVw+YMaZUdz}*mm;*>HkseJmaI%rEVLJ1}#nXJeMNs6ot89wHy;yYFb z${~hXABtqsl?XyY09N>66?UmjSET48+fWQlAGzk|8i>mQoU(24kUnt!>Z0Dr~8+ICY>Hc70>_qQ#^K7#$ z-5)MFBKzG&nD>;NRUQen3N?p`@12^cAxTQrd$P3lVUIED=n`qly{py@#(>MsHmfUC zHffl&vZCWV&ttXUOiej|32u+p-F2z_)dqdPM@%-jcb2?UuWDHHb^&Ajdzi1ieq1Jb zDZa4+clrucci9&&-tV}5IQ>HQiOY>w*Z5qk+LQL;fPr#LI(}PF&?#lI2q%#&d|P$l zmXoVbT#UK9+<)AH!Hd95f_t)1+xfp(){9P0#n48#@MuC$yMY}0nFgZhEI=W<4Xju_k~czR z3)_)kM-bs*H4AhL1Zp8@BslPiGY-rGy828*wI`bwQoM_< zkpcIvdj)T@7^pM2)rWD`6#XL}uAa8hN~3Ywe5Tk4NCFO{YsnKMVgy zKhyA8)NKC+pJ~9g0NNpOT@a;XU>^()MGN$9-!1G161E5g3a9^bER_`D0+21t#%V{4Qu*xX^g~OefCjNc z792OtGwS@FXZUMMj!_|AJaZgfwwT3eeQHO%OY7{AkO+xC&u8IJD!4JEBB^ z5*&znBskEC9l*HJNdgA=$BawJp(2igG+Y9MkOX*;f&Xk`>k>c+!Qs%Hgwnx;lF$xOWU9{&AWMSkSA~qZcAL-KCDr33ssWz!_KEb%#XnW5LS-*_Y0?2t>6ZuyJ5+$DGZ+i<<|4 zM#HJr_Js_91UWh$bz%UXkdRz&Rl`N^g{pb#T&rE6$Fs{gE^;mWmfYlBQ;Q>x zUFU?HXrn-tT9v+3!S+F|ZS&jfKb!oyWc-Uj+hHOGl$nN0wI`XDDu5sD&~PHK21QrH z9S9uqFW?yW(~Oh~JE2lWSXC&XsFsL)$3t|2MJv!PHOgksn=umE(%Vr}hju#hF^af# z+6#;+ty(Iw@W|b&KQ2?H&n39OU+P`k+j`hc1!{8bZBAGBElxURza#I(;1kwX$4aCm zh!_y&8vUl1UTGIM$4sf$St?&_9#CXVQ8afNQilaa=UbFaWB6dHN*DYiVi9DbXbRMZ zVU@dRqroBvLF8}Ri{0y?*xKk&QeuN#}jE6yH=Af^$G${ zR%^8=3eGm;XK{ zzv^1IfS!~5Vn#F=HQg>WtE57ZgN39b23-8sxDkZw{(>$Lzl8!8^1)&eBv|99nVhs5 zN4S$yAZjEy7mFBBW*P=3r`|ZN;;}~E1N=%aTwZVV$({jQs$P9pC8&Ij1o4x8+8L*n z=l(I{a3=*ibQqXUycl&R`ZpAt2uj2=1?gM3L<*rY^6RMSbi*z8!39GL?fU-8uiQUl_xGx|v|SyZ za*a!nH*s98$Q{(a=77at>pWD{QZU+>Bks~(-6vJ~A9j`cr={{$Qp=((1=@!|#fxD; zf}Rr%9s(el1kn@?;@rznXfk_X$CMc;(h^CYNHGwb@#{pAL8~4GZLW|6ilSad0G!BT zi6c^0>Kz6Xhc0%;+9hs}Jy0j$Lu4eXIiL=9AZ#9&g%K+TJkn_@2D- zT}rKWe_T=h>m~Jnu9)!JW>KtCIxsrwME7vp0lO+%OlbV6|6}K?oyIg70=9r$t6N=e z6CE8J_Pm|-!8*;Fbm=&|>Gz+vwzkRL-l^1siv1N5u(Pshc2IEjJtwbkw_mpFX0_>` z8umbMi3BkrnXf1x2^M@Qx=P?C~pO*~BC z(VDO%jsc7O?Ij#eiVBWUJu89E26{T;dcKt&OD-AQyVlbkfi~A}UaZ`m5@*2A8{L>SJu$a_@C_@h38i8F7zEx@U(t#gy8-*J^JTP-y38HcxZI>}6Y$u)Tvt>+RyN7d6E;%tc?&-&NehOAUoy9oh z$;O9`EYryEvclm~+i6SBdYOnA5N7L<(wZ4<&e40Ny0`~Iqi&7XBgWMj`-*s!F`z2} zev7~fF79s;QuCkgKBwe)7w>ybgkg@PM;>fXl?fYR&qEwSV)~Z~pROdUv8;*8J?6 z-G7tmx1dXnLW71n9cmRdK6hN5K{u``Z|7a?ch~i`QP=9*+fNyGXI|(eO>gW1JCjvT zd^IT9_u4!k<0Z|EH)phaCr`4{`M&A27bB{Sm8bOb49~GLeqZ}O;j%7Kfj?&sd+;U& zVj<4Dhl;MvOJACC*|3h0!-?bv3un3oWu@u2XeITNJEd0axMD&R^*?>G(lak#+okdipOStP8I3UGlu-3;5ris(7G;v>)#o7qh=)2#L14_1hp9*K zi#3E>1k#JprVF+=f6(|-_iv{=7_KyFadpkk8&$Qv>_6L~tl5hCgL}vNC8if_oZ8N` zdmZr}BX$<$ukY0WO8w1J`R1lJY)gqko#;GZfsUH04kKtb=17CUS=Kaw1X%>6Nh${n znSv}LzXQdPkAMVRqPWHs)j~KiS^$;rhf2LwU=b=A6?5G!R@%%UYs|Hf0S%t4DYsYa zMd;P03CaGqZkW6qbFuQ{8qF>5RE&lhlfXq66gA)ND1U@B{=g?ItEtlk*X|w3#$^?@&h$^4y~@fbl#@u z&=+$#wxW5D-m|UG^(cy0!N>-5>E@z>6BX&HW%Il$zX_)z{{P|vm|Bb}`PQGc{`i8O zX1DG2(ApPhk5&o!gamHB3Q4Dw3{)AjE-}QX^8+FjiBILDSQ$E}n^X$+Ime zVKw^MlK5>AhWYV*zLwb~eu==?MXd){IUJh*>v_Z63pJ;jBsw{ZKbxsyr`}f6;F|OZ z-mX7D>y}ax_FqthBUmcm-e=e!U%(LzeX)J)A7603PzL?+1@MKwzEmDJ!B(R$C^jNk zfNuujlS+I?nP7+(Popo1sB(J)3Xlb?SNNSV;m?;#hYredSbO>N<|#*x2d!234YExBxqg80>T5c- zo^vOiv&PZUF)po|#!(=u{9jpMW{P;rx_^AZ&J^(@n*8wv=Zj>gKfYjnvD3)qk1sf1 z4Cwa97r+;KC#3SkM@Bebpvxmt-PFOZObCt+%M@CZBm6FBgpj{u0Xvx7Wi!R_%__>S zCt>%_NtDJFiY%g#8=C;XQko2={EQB=SUcnDk&;?3!=JX%Z{U&FZDjYqyzbmwA!|#!ZXHofNq5$|Q8(qo{P>1qp_Cr(Rh){CEZtxNPnf zukX{l)P1w*(3_JA36eA#C-4f6q1QsYnpoiau)zO60WoW#U30Df_=1h|yRwNtzF>W^ zySBq0UvRz%bNu5A&KH+k{P6|ri#-JS#}}M0f?WUj0{FtPrBr_4(q7INYJZL47O2cu z9OxI_(rZroLk+6y57jj?FBJj=%}uiq?1L`i)hk6ah!2nh+!RiL4CEBdz^a*(>k5!0 zM1Vh-6W|XfSf(H#pqLVO1WRiEDHEkZeI0!)p|^GW%c(id7cY7|zPz2^`SgO%A+Hsj zN>MIbkx@S|#5E?zdKg%r>*8Yx8H=3*Y(GRF&Y2h!>rE~>mYK5Uj7WEJjlXFstno(}WRu19v1I z9<}7fhAGbJgF<@LZt+68Ui`%ZT+@h@Yik{CtoTM~oCuY3LW^p9Cc?x8R|Ew>r19x% z(`5S;Ztf5>{!f*dYt!UF_Jc?NQ|GRFvS~`0Oe#+`{jS#wwqHNz|puI?7MNGN)9DS2_t+(Km$psrv!IS zw{H7zx!ozV3jLaIOjvU`Ix~HNr-9DzobH%ivfs$tTT3OyG%eS}ZDMH6-FMq6Xd~1f zP9V>p3gmwXCz5Np66e9HnjfclDS8}lywRUjJjwQ9-=|EMEs~!@vMUp zSdDp)NWY&={eI--)$3R%cjdKk*Yv7S-q#s4#kc=*M|n)I^&<0%rCpI}RPpq#_uGTN z?yU4Y?f5BuFKT$WboS13+wK@Azi)TgR2+dZUM4U&6y?-w{D8n-6TA1DGII3rKK8rZ16i;J7va98Jk6WvDz^c_8ALW^Mm9hy$|Y%qRg@X!%MgNN21JJEjv6a?0c zSoaK9ly{u5v*pgAC7wsD?wHud>*&hfA0;1&WwMA1b-bGU`ZZLbc4&0ZrR_vOUZ2#4 zXMIh|>s7nlVOSeee~|=K8VgI6hVD}N(W7=S3=kXxL9fU8A{!DoDoF!UdPJ!ib*_Mg zpxKxMNs)X>fOr&h^Rf|1F&KdZYKAIEhJ!bR0ysL!H~{9%H{d7~MPuoEl?eb6tWiuY zHl~n(KqsX^$N$I+|MqS^QvWpFO>mE;YP)*J-f7OABFxR*O5b=Je{#{OuXYyZyStN} z?X5i&D1!(VjKeLEv^7qn?$af|%`M&gv|WofYo@zCJ>Mxj#jJ&TBr z7xy7MiNy3v74J6oWX}&%MZORfc2uqVCFuru$PT9(_(iu5+2Q>1o5;qtn#f=s7ih~DykphSd9+eGPbxod1>a>x@<;SnExJ%K&z8zK`jjC8t@%a zaUz&$NQ`7laBdRKMi8GrJwG(ss$ufu8x`|Q4e!$L{>-=~DfPDO^#ol(S+b|yx~n;T z9=CM1J+juS+APPgR#o4O2psI@(EqD*>=%XUu}$BG9d=#){n+?rI}+Y4%`5X!)~vMf zfRrMso!7P%ram(+*Ki6k{yw|ES=C)>6>WqmnW7){I(|XBJDUk;xHu7fk>sJj4G4BZ zQS4-_Rw~6)WJTQ!r*+}tfo%nGW6<}Y`^NQ}^R~8Z;JvPwD%yQ0VbOAM53L{d8kbeI z^yxNxwtn@g^&$3ZN1HvhPR>;D#sT1}Pt>AP?sf7$NXDL=Ebo?6E9UeG5d*?3`|$B{ zxd%Dm62zddRDRL{yuJyca-g0>Rs?MV&zVk~AL%m5;MgO26-5aYX6eS1ncA%LUHD9VrbH1DN#)dbL7^>_+$OeiEm>-*2)R{K?jjw!P`MPXOBcp% zRTk^El-eSjO_p-WrIb+m$t6NfivN4g%$)O{={?O3^WV?!cRtNI&-*;z_j#W4Jn!wC zIdf9zwMmpxh!8?F$0MY^tSUYA=gwWd!vfpSw8{04?acttU~XVyGC!fu>&znHT=(HC zT;4y(9d)%S`QxK8IahtEZ$vBIx$N4i!|@)+UoN=Wn3O#!^?_gJUe-5OtMt1Tzisxd zJFEUJ=l&`@(D&dv{jGEIjzqhRyize^+`NG-kpnYFFQMhzeLtL3Qd$+r8l68j=itaG zqs_^6PLZ^(jVQDH?YZI1!60&8EiO+s2fVio_OE=R?woyKnsfe6McbTQ+j70914>iC zIaEF1oI)=vmg^jCk)kw(6v;x6Q{d%C1;~LF)L{-)Y=COr=^ zFM(kknr6C!#?ai>Qv$;@4WuY?3bZM5k9Nq-cWrq5$u(1>OSWzKtNkET3O&HJ@kBzICXIfZ(qFQIESFXIPAm{Rnz&C1~C8t!>gP8d54o} ziq6~mk>`8>gUnQ($LQ9XYBe1JG_?sh$b1oUq8=(uR9z}!Gzv~1je{vB0*6Hqy%C}n zCYAPsIg6K-IW}w3-DeGTpX1?enUe0bh4~_^9!{lW_qtn5>fpNjltFFS-k;B|_Yk(_ zufTW(n4#^t;a9er6PdzjFiw*Mg-MFI_$V$CZJZ7^ygnh>7>N=95DX)W@Q!Q{%sjwi zaa{p}#ooD45<<6xj}dBc$Q`;h0tE5Tsge@bjU0JmQuK%}`G(8y>aN>mab)>;;=h$D zv{-3+;OP_nr+r6*D8pk-$M47W(u%YZ61Jt=nwF7aPiw66{WLkVvi5$TG&8a{Unmta zk19qv3stL4&g)GC&MD)jl3d$zy@ws_GU|4&UAw?_;0hh3_^YqbRjiXP6!!_b(kFfw zY!0Hk?0NsP=uP>IP;iBgG7XZZ(0v=Zr;P%zU7^!igFIF$Nd-Ox-6}>4!*2d)sZ;k$ zsYXfBW4k|&8d%*|zxrUynVh8y(>y<@_nIe!{Xv}^0|0}iwnZAH-0;GmHj0ON9tJS& zAskVLH;fBP#0PXq*&Z()NWf8D(kpR}fE@S9&a2MBh+YghVB-;J0tG%emsW)V7PJwj zIGu5bgNf}EY{CNq09d%#8`2KoP#X>?U;*$kiU$$2UBDD|ATB224@?yuw|TgJbMk~G z&(cJB&Hg?c6dgQ@UkyI=nm;7`K=|PH<=ZXwI&NBZUI>{*l57B8X^`bP)4L_5z&X@A zf)#ZRb%G4r3VW|&GBg(4sz)gX&wDG>h83}`?7+yiZSlI(m*+V{j+Sq7_8(n0Y(nJ} z?ahqH$>x;|%)iv6wjUj*`RY8jbi}$Z1AZmH%|k&t>69%Kc-AhcK?woxbei9RZ6($YpIPK`*&QGMe&(nz7%|lL zC6w1j89Aw4zjM7nJ&)()8=3DrstJ5gJ&3>RQtyT7HTy%1HIGN?51*m4Xu*o?_sPA! zpL*-lE*s{*Mn@Rr3t=WId~y?zp$4l!(E=2c=BeT|jiOXB6c^(8Ks176o+GMvAu2&E zJ_Z#~qyWXFc`8DhMo}sP6qn|4X%b2Ca*=Ea(IKoYggF3w^L$(G|kvW_eh#Lr2VCsXFj8>3)6Y8-^+iql+7P8}b#Tj*6Lom-M-cSxby24 zM;Z(lMmE`x9h025a$(TSreB`T2c+HpeH9``;RIy>0E!N9QphC|#zT@MH67--jA zxGPAX(Na>`^X3~hQ`4>cnxnc;HqXgeZftMAP+#5~C`IiwxZyWO&`<4yRX0xlwayEl zV9`Sw@!w#GH9E0&=3oRtZ6up42`C;x@ag5Z6hbP6R@qX-SVAWO0v|C}A`uXZaAHSp zpekKkS{aiFiIqJe1$@Bj3_el>382q~D2mjGCx48~8*jRd?bf4^J1Hf9+=@)?rw1ay zVn?C-ZG%cC$NGfSEsfmfoA321aLrERnbtzmqGb1=@=8Q96@CbHUZOA;F1!Q(d1Ch31NG3hZ+b>InVw`pF;Nub{|a>e z4_Q_1)~FviZ>y2`czl`r%xvGG^Fbq@6?oA%liM#+e+kzm;JD+~3ZoG^+We&N|5h8~ zWudx*`Hh5Srr+-#PEMI+5p`21sjBYtI8ruRNZOR_k_0--b*H>Lxv1Jte^G(u)m^#k zychr&ETOr;Ic41Il4~0kfi|5p8(9|C_y`@j2;u2Lv*$hE=+}Rx9f|+X+JejW2i=*AOj%RdlZ0m{2)V1xK9!+JM#205&};?UR7aVoLH`3d8{I~ z!pJ7bHM&x0bJD9OFv9N52gm5fAFbnke{c+Kii#XJD%&FokK4`jXSrmUP3`*HY!wR#NI-`;FcA!3*yJcc*2Rb;V+ z)++Ui=-7;gN~`45b=J0_df`I?rpGz=&q*;enf#*Ch55j++{mE--`1vy*puI87e9Lh z5B=~N5<@F_y?`85X(UFIG(`{8H18i!4l)>tX*nLqRFW-XGLwj`96SV>0(!}d_8}Gq zzp0s@ZtCIG;g(NsckZH9pqD6g9TYtzf9>;46LXf_{newx<()~+afg{BKl0gkmbYV5 zY!Nq=8-Di(3y>*dwi9mxDe<*O@iiu*HXUsmf+1o^`yy6CPNaau$s*Zw!~*7?R?p;v z64r`CGH?kS7;M}Jera@jgn9)3>g8OYG5h<*XB(W1wAb-c`tP7#p0N0Msb^?$*soh6 zjMrA@46QokE|fUJcHrUUn>R~_eWE%Q9YRDUftZK27SSxCORy_p4Nbn zAgaE_P4`TC?AiM0UwZHtKR$H(&Z=^~?#phOH}XDqFB4Ka0D(F|1_0$f>(oL$3k;ip zXi82_EhW)aR4;%)Ur)040;W!BpMZJ+#t|?v@=7pV+))4r>O9h+3Wr8yq)u{bIdXQ1 zD0P#r=JwMMf}MtLt@!ivTZMmuqRjuW%AHdm9yI)3*R}mc{3LGpy+f{KrZDmhh%iH; zL!Ol^lY04uSkOm&pyGu~hcF38fQbRpJ;R(deNthoBY0Ja__B{7A+jXSl(e02Sv3h5 zH6;a+N*uVqqNk>2rTOxZ^%?g=&7b!=_nHxAoLMP6_GqxdTiuiUT_0Utt$I6hR>3*- z7TZ%JA7l%8>#Xjje`0o-Qm~Ytk3(-y+T=pc&1=9(tN2GKlKYf zV9lWB_`rMDCTCYixG1_zN0}Bvb~yO1hXJp&&$~ycy1WhS)$nxX;Ng8400_+Ou6^Qp zzui9I!N-sUl;%nyw_iW06n=UGTz4~tdm08=Lq`lbirEJ(x5SI~Idb*MJT2KymRHTfbeL`4XeLo^j2h^Hut$*I6?6n$mvnGX~EHFl-0Pou@P zPmO7j_G4DA?e==rGFH$m!+$vM8$9;;0MbfRPG z$V7YlJL4Gu2+UK{GCJJRVn-6Ya|&Gp$aPMUcGM!OEBAbNXR$AEP8nZC$qmdXd*M=l zlMZjRo;6hT=~gl2N0qWMY?0$|y|3Iq;;Q`~ER|4-zy7PJc3W=LPn{E3sAC2t3MN&1 zh4pjV-^c9?crqGg8nh^do{UE31U86@3+w${s!72blu1*8PfEBvx^|n3`HSjjhc`O7YjX3Xb}wDEo?|3C$LeIf&F) zbLjoFdaQi1CTJBX(@Jj@sJO7U3aYz6E-RCy0x#nEbHhtZ_qDY;KpQ4!22zBf0b;Jq ztRMpg6H1%42{<)LFze#tDTYN#TsU^4DhMcwg&^iL5!Xk=^-jnOsJmI{9p@SAX6I9? z`FZZgoBN5IgyV;nsolvf&7Tl-GOlG&%y;%~F-MBlPxsz4Y>TSdUk#sxux8r~2ZyYq z9G=64wG)Q))^Xdd+nL7z*cnD>x%^>Mq%$({dn46pjtOa7nD=|_d={te$_g+o{9x#C zc?aj%^Gp6J%yl_zPeKb2JeY;U1q3Y!QGx zrmIWWXRdl2JgFh6-s8_~IYfqth5tXF;kP#x@5$G|p_O$Ay!S1kqr26MiPdbi{fm}PiX-0X28!lgv(BQwLTRDhiLAM zxA$Uyx&m>~q&3V&g+~!NjFr&sr_7!^Z|b6XOGhJw1WUx5&ke8G%>khRjm?M!g=)6+ z!ji5eZiqxP6mW2wji#W+4UsffK$9GfHeA5r0!;IW0xtQ0g8+Qm+;9wtaWO>1^#tv_ zcB1))XSJ#P8;N^V@TU-Ufq5U+VL&+n?qn{jU$02oZto&iU}cZTh^^-#~i-eli9`P9DDZ(^oZUQh;D z^xlqp^S$0?*XDMgcO*8A^X?oF&DT$gS$6E!vv(r`l2vmVs^!|&`q{!{MZweJpyzsd zzD?ihx<=sL85&R_VgN{w;T`av{K;)PqQPPC zItQ0Ua0IYcMnmHX02l)wFlh3{qo{x^$?Skkb|V{_%vdYYjR7q2X|)NY9O5VYtiOL& zXlj#tk3(vbIC8%X9qqbj81XEOGVVLcwT+*>^Pl@$_pk1`#r@BNVZ(mS_$BgBA>jyW zgPi;5>E*`1($q2`C?&<`K;(Z)_pbTIf0aGTg1j8vuL6T$#d7R?NN+cG@Z>g5IxTVF6H!OU!<;t)c z?)7S`CqCJVj#bKh@`KZ%Tx&^oWs})oWTu|lrL>i)Hrgf?MvS6lzd0fVR0Jh3mT6j| zLm)Yl2RezA5?K6?X-w|b44J9)zzyc%`YF$5RQaF!?arNtf$sB&Oeyp|P{4?fnzu(~ e|7Xol!TKwzhYtV!. + +package ipld + +import ( + "encoding/json" + "fmt" + "math/big" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" +) + +// EthAccountSnapshot (eth-account-snapshot codec 0x97) +// represents an ethereum account, i.e. a wallet address or +// a smart contract +type EthAccountSnapshot struct { + *EthAccount + + cid cid.Cid + rawdata []byte +} + +// EthAccount is the building block of EthAccountSnapshot. +// Or, is the former stripped of its cid and rawdata components. +type EthAccount struct { + Nonce uint64 + Balance *big.Int + Root []byte // This is the storage root trie + CodeHash []byte // This is the hash of the EVM code +} + +// Static (compile time) check that EthAccountSnapshot satisfies the +// node.Node interface. +var _ node.Node = (*EthAccountSnapshot)(nil) + +/* + INPUT +*/ + +// Input should be managed by EthStateTrie + +/* + OUTPUT +*/ + +// Output should be managed by EthStateTrie + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the account snapshot. +func (as *EthAccountSnapshot) RawData() []byte { + return as.rawdata +} + +// Cid returns the cid of the transaction. +func (as *EthAccountSnapshot) Cid() cid.Cid { + return as.cid +} + +// String is a helper for output +func (as *EthAccountSnapshot) String() string { + return fmt.Sprintf("", as.cid) +} + +// Loggable returns in a map the type of IPLD Link. +func (as *EthAccountSnapshot) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-account-snapshot", + } +} + +/* + Node INTERFACE +*/ + +// Resolve resolves a path through this node, stopping at any link boundary +// and returning the object found as well as the remaining path to traverse +func (as *EthAccountSnapshot) Resolve(p []string) (interface{}, []string, error) { + if len(p) == 0 { + return as, nil, nil + } + + if len(p) > 1 { + return nil, nil, fmt.Errorf("unexpected path elements past %s", p[0]) + } + + switch p[0] { + case "balance": + return as.Balance, nil, nil + case "codeHash": + return &node.Link{Cid: keccak256ToCid(RawBinary, as.CodeHash)}, nil, nil + case "nonce": + return as.Nonce, nil, nil + case "root": + return &node.Link{Cid: keccak256ToCid(MEthStorageTrie, as.Root)}, nil, nil + default: + return nil, nil, ErrInvalidLink + } +} + +// Tree lists all paths within the object under 'path', and up to the given depth. +// To list the entire object (similar to `find .`) pass "" and -1 +func (as *EthAccountSnapshot) Tree(p string, depth int) []string { + if p != "" || depth == 0 { + return nil + } + return []string{"balance", "codeHash", "nonce", "root"} +} + +// ResolveLink is a helper function that calls resolve and asserts the +// output is a link +func (as *EthAccountSnapshot) ResolveLink(p []string) (*node.Link, []string, error) { + obj, rest, err := as.Resolve(p) + if err != nil { + return nil, nil, err + } + + if lnk, ok := obj.(*node.Link); ok { + return lnk, rest, nil + } + + return nil, nil, fmt.Errorf("resolved item was not a link") +} + +// Copy will go away. It is here to comply with the interface. +func (as *EthAccountSnapshot) Copy() node.Node { + panic("implement me") +} + +// Links is a helper function that returns all links within this object +func (as *EthAccountSnapshot) Links() []*node.Link { + return nil +} + +// Stat will go away. It is here to comply with the interface. +func (as *EthAccountSnapshot) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +// Size will go away. It is here to comply with the interface. +func (as *EthAccountSnapshot) Size() (uint64, error) { + return 0, nil +} + +/* + EthAccountSnapshot functions +*/ + +// MarshalJSON processes the transaction into readable JSON format. +func (as *EthAccountSnapshot) MarshalJSON() ([]byte, error) { + out := map[string]interface{}{ + "balance": as.Balance, + "codeHash": keccak256ToCid(RawBinary, as.CodeHash), + "nonce": as.Nonce, + "root": keccak256ToCid(MEthStorageTrie, as.Root), + } + return json.Marshal(out) +} diff --git a/statediff/indexer/ipld/eth_account_test.go b/statediff/indexer/ipld/eth_account_test.go new file mode 100644 index 000000000..cc2ac8430 --- /dev/null +++ b/statediff/indexer/ipld/eth_account_test.go @@ -0,0 +1,295 @@ +package ipld + +import ( + "encoding/json" + "fmt" + "os" + "regexp" + "testing" +) + +// Block INTERFACE +func init() { + if os.Getenv("MODE") != "statediff" { + fmt.Println("Skipping statediff test") + os.Exit(0) + } +} + +func TestAccountSnapshotBlockElements(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + if fmt.Sprintf("%x", eas.RawData())[:10] != "f84e808a03" { + t.Fatal("Wrong Data") + } + + if eas.Cid().String() != + "baglqcgzasckx2alxk43cksshnztjvhfyvbbh6bkp376gtcndm5cg4fkrkhsa" { + t.Fatal("Wrong Cid") + } +} + +func TestAccountSnapshotString(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + if eas.String() != + "" { + t.Fatalf("Wrong String()") + } +} + +func TestAccountSnapshotLoggable(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + l := eas.Loggable() + if _, ok := l["type"]; !ok { + t.Fatal("Loggable map expected the field 'type'") + } + + if l["type"] != "eth-account-snapshot" { + t.Fatalf("Wrong Loggable 'type' value\r\nexpected %s\r\ngot %s", "eth-account-snapshot", l["type"]) + } +} + +/* +Node INTERFACE +*/ +func TestAccountSnapshotResolve(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + // Empty path + obj, rest, err := eas.Resolve([]string{}) + reas, ok := obj.(*EthAccountSnapshot) + if !ok { + t.Fatalf("Wrong type of returned object\r\nexpected %T\r\ngot %T", &EthAccountSnapshot{}, reas) + } + if reas.Cid() != eas.Cid() { + t.Fatalf("wrong returned CID\r\nexpected %s\r\ngot %s", eas.Cid().String(), reas.Cid().String()) + } + if rest != nil { + t.Fatal("rest should be nil") + } + if err != nil { + t.Fatal("err should be nil") + } + + // len(p) > 1 + badCases := [][]string{ + {"two", "elements"}, + {"here", "three", "elements"}, + {"and", "here", "four", "elements"}, + } + + for _, bc := range badCases { + obj, rest, err = eas.Resolve(bc) + if obj != nil { + t.Fatal("obj should be nil") + } + if rest != nil { + t.Fatal("rest should be nil") + } + if err.Error() != fmt.Sprintf("unexpected path elements past %s", bc[0]) { + t.Fatal("wrong error") + } + } + + moreBadCases := []string{ + "i", + "am", + "not", + "an", + "account", + "field", + } + for _, mbc := range moreBadCases { + obj, rest, err = eas.Resolve([]string{mbc}) + if obj != nil { + t.Fatal("obj should be nil") + } + if rest != nil { + t.Fatal("rest should be nil") + } + if err != ErrInvalidLink { + t.Fatal("wrong error") + } + } + + goodCases := []string{ + "balance", + "codeHash", + "nonce", + "root", + } + for _, gc := range goodCases { + _, _, err = eas.Resolve([]string{gc}) + if err != nil { + t.Fatalf("error should be nil %v", gc) + } + } +} + +func TestAccountSnapshotTree(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + // Bad cases + tree := eas.Tree("non-empty-string", 0) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + tree = eas.Tree("non-empty-string", 1) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + tree = eas.Tree("", 0) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + // Good cases + tree = eas.Tree("", 1) + lookupElements := map[string]interface{}{ + "balance": nil, + "codeHash": nil, + "nonce": nil, + "root": nil, + } + + if len(tree) != len(lookupElements) { + t.Fatalf("Wrong number of elements\r\nexpected %d\r\ngot %d", len(lookupElements), len(tree)) + } + + for _, te := range tree { + if _, ok := lookupElements[te]; !ok { + t.Fatalf("Unexpected Element: %v", te) + } + } +} + +func TestAccountSnapshotResolveLink(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + // bad case + obj, rest, err := eas.ResolveLink([]string{"supercalifragilist"}) + if obj != nil { + t.Fatalf("Expected obj to be nil") + } + if rest != nil { + t.Fatal("Expected rest to be nil") + } + if err != ErrInvalidLink { + t.Fatal("Wrong error") + } + + // good case + obj, rest, err = eas.ResolveLink([]string{"nonce"}) + if obj != nil { + t.Fatalf("Expected obj to be nil") + } + if rest != nil { + t.Fatal("Expected rest to be nil") + } + if err.Error() != "resolved item was not a link" { + t.Fatal("Wrong error") + } +} + +func TestAccountSnapshotCopy(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + defer func() { + r := recover() + if r == nil { + t.Fatal("Expected panic") + } + if r != "implement me" { + t.Fatalf("Wrong panic message\r\n expected %s\r\ngot %s", "'implement me'", r) + } + }() + + _ = eas.Copy() +} + +func TestAccountSnapshotLinks(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + if eas.Links() != nil { + t.Fatal("Links() expected to return nil") + } +} + +func TestAccountSnapshotStat(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + obj, err := eas.Stat() + if obj == nil { + t.Fatal("Expected a not null object node.NodeStat") + } + + if err != nil { + t.Fatal("Expected a nil error") + } +} + +func TestAccountSnapshotSize(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + size, err := eas.Size() + if size != uint64(0) { + t.Fatalf("Wrong size\r\nexpected %d\r\ngot %d", 0, size) + } + + if err != nil { + t.Fatal("Expected a nil error") + } +} + +/* + EthAccountSnapshot functions +*/ + +func TestAccountSnapshotMarshalJSON(t *testing.T) { + eas := prepareEthAccountSnapshot(t) + + jsonOutput, err := eas.MarshalJSON() + checkError(err, t) + + var data map[string]interface{} + err = json.Unmarshal(jsonOutput, &data) + checkError(err, t) + + balanceExpression := regexp.MustCompile(`{"balance":16011846000000000000000,`) + if !balanceExpression.MatchString(string(jsonOutput)) { + t.Fatal("Balance expression not found") + } + + code, _ := data["codeHash"].(map[string]interface{}) + if fmt.Sprintf("%s", code["/"]) != + "bafkrwigf2jdadbxxem6je7t5wlomoa6a4ualmu6kqittw6723acf3bneoa" { + t.Fatalf("Wrong Marshaled Value\r\nexpected %s\r\ngot %s", "bafkrwigf2jdadbxxem6je7t5wlomoa6a4ualmu6kqittw6723acf3bneoa", fmt.Sprintf("%s", code["/"])) + } + + if fmt.Sprintf("%v", data["nonce"]) != "0" { + t.Fatalf("Wrong Marshaled Value\r\nexpected %s\r\ngot %s", "0", fmt.Sprintf("%v", data["nonce"])) + } + + root, _ := data["root"].(map[string]interface{}) + if fmt.Sprintf("%s", root["/"]) != + "bagmacgzak3ub6fy3zrk2n74dixtjfqhynznurya3tfwk3qabmix3ly3dwqqq" { + t.Fatalf("Wrong Marshaled Value\r\nexpected %s\r\ngot %s", "bagmacgzak3ub6fy3zrk2n74dixtjfqhynznurya3tfwk3qabmix3ly3dwqqq", fmt.Sprintf("%s", root["/"])) + } +} + +/* +AUXILIARS +*/ +func prepareEthAccountSnapshot(t *testing.T) *EthAccountSnapshot { + fi, err := os.Open("test_data/eth-state-trie-rlp-c9070d") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + return output.elements[1].(*EthAccountSnapshot) +} diff --git a/statediff/indexer/ipld/eth_header.go b/statediff/indexer/ipld/eth_header.go new file mode 100644 index 000000000..9bc307277 --- /dev/null +++ b/statediff/indexer/ipld/eth_header.go @@ -0,0 +1,293 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "encoding/json" + "fmt" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// EthHeader (eth-block, codec 0x90), represents an ethereum block header +type EthHeader struct { + *types.Header + + cid cid.Cid + rawdata []byte +} + +// Static (compile time) check that EthHeader satisfies the node.Node interface. +var _ node.Node = (*EthHeader)(nil) + +/* + INPUT +*/ + +// NewEthHeader converts a *types.Header into an EthHeader IPLD node +func NewEthHeader(header *types.Header) (*EthHeader, error) { + headerRLP, err := rlp.EncodeToBytes(header) + if err != nil { + return nil, err + } + c, err := RawdataToCid(MEthHeader, headerRLP, mh.KECCAK_256) + if err != nil { + return nil, err + } + return &EthHeader{ + Header: header, + cid: c, + rawdata: headerRLP, + }, nil +} + +/* + OUTPUT +*/ + +// DecodeEthHeader takes a cid and its raw binary data +// from IPFS and returns an EthTx object for further processing. +func DecodeEthHeader(c cid.Cid, b []byte) (*EthHeader, error) { + h := new(types.Header) + if err := rlp.DecodeBytes(b, h); err != nil { + return nil, err + } + return &EthHeader{ + Header: h, + cid: c, + rawdata: b, + }, nil +} + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the block header. +func (b *EthHeader) RawData() []byte { + return b.rawdata +} + +// Cid returns the cid of the block header. +func (b *EthHeader) Cid() cid.Cid { + return b.cid +} + +// String is a helper for output +func (b *EthHeader) String() string { + return fmt.Sprintf("", b.cid) +} + +// Loggable returns a map the type of IPLD Link. +func (b *EthHeader) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-header", + } +} + +/* + Node INTERFACE +*/ + +// Resolve resolves a path through this node, stopping at any link boundary +// and returning the object found as well as the remaining path to traverse +func (b *EthHeader) Resolve(p []string) (interface{}, []string, error) { + if len(p) == 0 { + return b, nil, nil + } + + first, rest := p[0], p[1:] + + switch first { + case "parent": + return &node.Link{Cid: commonHashToCid(MEthHeader, b.ParentHash)}, rest, nil + case "receipts": + return &node.Link{Cid: commonHashToCid(MEthTxReceiptTrie, b.ReceiptHash)}, rest, nil + case "root": + return &node.Link{Cid: commonHashToCid(MEthStateTrie, b.Root)}, rest, nil + case "tx": + return &node.Link{Cid: commonHashToCid(MEthTxTrie, b.TxHash)}, rest, nil + case "uncles": + return &node.Link{Cid: commonHashToCid(MEthHeaderList, b.UncleHash)}, rest, nil + } + + if len(p) != 1 { + return nil, nil, fmt.Errorf("unexpected path elements past %s", first) + } + + switch first { + case "bloom": + return b.Bloom, nil, nil + case "coinbase": + return b.Coinbase, nil, nil + case "difficulty": + return b.Difficulty, nil, nil + case "extra": + // This is a []byte. By default they are marshalled into Base64. + return fmt.Sprintf("0x%x", b.Extra), nil, nil + case "gaslimit": + return b.GasLimit, nil, nil + case "gasused": + return b.GasUsed, nil, nil + case "mixdigest": + return b.MixDigest, nil, nil + case "nonce": + return b.Nonce, nil, nil + case "number": + return b.Number, nil, nil + case "time": + return b.Time, nil, nil + default: + return nil, nil, ErrInvalidLink + } +} + +// Tree lists all paths within the object under 'path', and up to the given depth. +// To list the entire object (similar to `find .`) pass "" and -1 +func (b *EthHeader) Tree(p string, depth int) []string { + if p != "" || depth == 0 { + return nil + } + + return []string{ + "time", + "bloom", + "coinbase", + "difficulty", + "extra", + "gaslimit", + "gasused", + "mixdigest", + "nonce", + "number", + "parent", + "receipts", + "root", + "tx", + "uncles", + } +} + +// ResolveLink is a helper function that allows easier traversal of links through blocks +func (b *EthHeader) ResolveLink(p []string) (*node.Link, []string, error) { + obj, rest, err := b.Resolve(p) + if err != nil { + return nil, nil, err + } + + if lnk, ok := obj.(*node.Link); ok { + return lnk, rest, nil + } + + return nil, nil, fmt.Errorf("resolved item was not a link") +} + +// Copy will go away. It is here to comply with the Node interface. +func (b *EthHeader) Copy() node.Node { + panic("implement me") +} + +// Links is a helper function that returns all links within this object +// HINT: Use `ipfs refs ` +func (b *EthHeader) Links() []*node.Link { + return []*node.Link{ + {Cid: commonHashToCid(MEthHeader, b.ParentHash)}, + {Cid: commonHashToCid(MEthTxReceiptTrie, b.ReceiptHash)}, + {Cid: commonHashToCid(MEthStateTrie, b.Root)}, + {Cid: commonHashToCid(MEthTxTrie, b.TxHash)}, + {Cid: commonHashToCid(MEthHeaderList, b.UncleHash)}, + } +} + +// Stat will go away. It is here to comply with the Node interface. +func (b *EthHeader) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +// Size will go away. It is here to comply with the Node interface. +func (b *EthHeader) Size() (uint64, error) { + return 0, nil +} + +/* + EthHeader functions +*/ + +// MarshalJSON processes the block header into readable JSON format, +// converting the right links into their cids, and keeping the original +// hex hash, allowing the user to simplify external queries. +func (b *EthHeader) MarshalJSON() ([]byte, error) { + out := map[string]interface{}{ + "time": b.Time, + "bloom": b.Bloom, + "coinbase": b.Coinbase, + "difficulty": b.Difficulty, + "extra": fmt.Sprintf("0x%x", b.Extra), + "gaslimit": b.GasLimit, + "gasused": b.GasUsed, + "mixdigest": b.MixDigest, + "nonce": b.Nonce, + "number": b.Number, + "parent": commonHashToCid(MEthHeader, b.ParentHash), + "receipts": commonHashToCid(MEthTxReceiptTrie, b.ReceiptHash), + "root": commonHashToCid(MEthStateTrie, b.Root), + "tx": commonHashToCid(MEthTxTrie, b.TxHash), + "uncles": commonHashToCid(MEthHeaderList, b.UncleHash), + } + return json.Marshal(out) +} + +// objJSONHeader defines the output of the JSON RPC API for either +// "eth_BlockByHash" or "eth_BlockByHeader". +type objJSONHeader struct { + Result objJSONHeaderResult `json:"result"` +} + +// objJSONBLockResult is the nested struct that takes +// the contents of the JSON field "result". +type objJSONHeaderResult struct { + types.Header // Use its fields and unmarshaler + *objJSONHeaderResultExt // Add these fields to the parsing +} + +// objJSONBLockResultExt facilitates the composition +// of the field "result", adding to the +// `types.Header` fields, both ommers (their hashes) and transactions. +type objJSONHeaderResultExt struct { + OmmerHashes []common.Hash `json:"uncles"` + Transactions []*types.Transaction `json:"transactions"` +} + +// UnmarshalJSON overrides the function types.Header.UnmarshalJSON, allowing us +// to parse the fields of Header, plus ommer hashes and transactions. +// (yes, ommer hashes. You will need to "eth_getUncleCountByBlockHash" per each ommer) +func (o *objJSONHeaderResult) UnmarshalJSON(input []byte) error { + err := o.Header.UnmarshalJSON(input) + if err != nil { + return err + } + + o.objJSONHeaderResultExt = &objJSONHeaderResultExt{} + err = json.Unmarshal(input, o.objJSONHeaderResultExt) + return err +} diff --git a/statediff/indexer/ipld/eth_header_test.go b/statediff/indexer/ipld/eth_header_test.go new file mode 100644 index 000000000..31acb88dd --- /dev/null +++ b/statediff/indexer/ipld/eth_header_test.go @@ -0,0 +1,583 @@ +package ipld + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "os" + "runtime" + "strconv" + "testing" + + block "github.com/ipfs/go-block-format" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/core/types" +) + +func TestBlockBodyRlpParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-block-body-rlp-999999") + checkError(err, t) + + output, _, _, err := FromBlockRLP(fi) + checkError(err, t) + + testEthBlockFields(output, t) +} + +func TestBlockHeaderRlpParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-block-header-rlp-999999") + checkError(err, t) + + output, _, _, err := FromBlockRLP(fi) + checkError(err, t) + + testEthBlockFields(output, t) +} + +func TestBlockBodyJsonParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-block-body-json-999999") + checkError(err, t) + + output, _, _, err := FromBlockJSON(fi) + checkError(err, t) + + testEthBlockFields(output, t) +} + +func TestEthBlockProcessTransactionsError(t *testing.T) { + // Let's just change one byte in a field of one of these transactions. + fi, err := os.Open("test_data/error-tx-eth-block-body-json-999999") + checkError(err, t) + + _, _, _, err = FromBlockJSON(fi) + if err == nil { + t.Fatal("Expected an error") + } +} + +// TestDecodeBlockHeader should work for both inputs (block header and block body) +// as what we are storing is just the block header +func TestDecodeBlockHeader(t *testing.T) { + storedEthBlock := prepareStoredEthBlock("test_data/eth-block-header-rlp-999999", t) + + ethBlock, err := DecodeEthHeader(storedEthBlock.Cid(), storedEthBlock.RawData()) + checkError(err, t) + + testEthBlockFields(ethBlock, t) +} + +func TestEthBlockString(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + if ethBlock.String() != "" { + t.Fatalf("Wrong String()\r\nexpected %s\r\ngot %s", "", ethBlock.String()) + } +} + +func TestEthBlockLoggable(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + l := ethBlock.Loggable() + if _, ok := l["type"]; !ok { + t.Fatal("Loggable map expected the field 'type'") + } + + if l["type"] != "eth-header" { + t.Fatalf("Wrong Loggable 'type' value\r\nexpected %s\r\ngot %s", "eth-header", l["type"]) + } +} + +func TestEthBlockJSONMarshal(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + jsonOutput, err := ethBlock.MarshalJSON() + checkError(err, t) + + var data map[string]interface{} + err = json.Unmarshal(jsonOutput, &data) + checkError(err, t) + + // Testing all fields is boring, but can help us to avoid + // that dreaded regression + if data["bloom"].(string)[:10] != "0x00000000" { + t.Fatalf("Wrong Bloom\r\nexpected %s\r\ngot %s", "0x00000000", data["bloom"].(string)[:10]) + t.Fatal("Wrong Bloom") + } + if data["coinbase"] != "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5" { + t.Fatalf("Wrong coinbase\r\nexpected %s\r\ngot %s", "0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5", data["coinbase"]) + } + if parseFloat(data["difficulty"]) != "12555463106190" { + t.Fatalf("Wrong Difficulty\r\nexpected %s\r\ngot %s", "12555463106190", parseFloat(data["difficulty"])) + } + if data["extra"] != "0xd783010303844765746887676f312e342e32856c696e7578" { + t.Fatalf("Wrong Extra\r\nexpected %s\r\ngot %s", "0xd783010303844765746887676f312e342e32856c696e7578", data["extra"]) + } + if parseFloat(data["gaslimit"]) != "3141592" { + t.Fatalf("Wrong Gas limit\r\nexpected %s\r\ngot %s", "3141592", parseFloat(data["gaslimit"])) + } + if parseFloat(data["gasused"]) != "231000" { + t.Fatalf("Wrong Gas used\r\nexpected %s\r\ngot %s", "231000", parseFloat(data["gasused"])) + } + if data["mixdigest"] != "0x5b10f4a08a6c209d426f6158bd24b574f4f7b7aa0099c67c14a1f693b4dd04d0" { + t.Fatalf("Wrong Mix digest\r\nexpected %s\r\ngot %s", "0x5b10f4a08a6c209d426f6158bd24b574f4f7b7aa0099c67c14a1f693b4dd04d0", data["mixdigest"]) + } + if data["nonce"] != "0xf491f46b60fe04b3" { + t.Fatalf("Wrong nonce\r\nexpected %s\r\ngot %s", "0xf491f46b60fe04b3", data["nonce"]) + } + if parseFloat(data["number"]) != "999999" { + t.Fatalf("Wrong block number\r\nexpected %s\r\ngot %s", "999999", parseFloat(data["number"])) + } + if parseMapElement(data["parent"]) != "bagiacgza2m6j3xu774hlvjxhd2fsnuv5ufom6ei4ply3mm3jrleeozt7b62a" { + t.Fatalf("Wrong Parent cid\r\nexpected %s\r\ngot %s", "bagiacgza2m6j3xu774hlvjxhd2fsnuv5ufom6ei4ply3mm3jrleeozt7b62a", parseMapElement(data["parent"])) + } + if parseMapElement(data["receipts"]) != "bagkacgzap6qpnsrkagbdecgybaa63ljx4pr2aa5vlsetdg2f5mpzpbrk2iuq" { + t.Fatalf("Wrong Receipt root cid\r\nexpected %s\r\ngot %s", "bagkacgzap6qpnsrkagbdecgybaa63ljx4pr2aa5vlsetdg2f5mpzpbrk2iuq", parseMapElement(data["receipts"])) + } + if parseMapElement(data["root"]) != "baglacgza5wmkus23dhec7m2tmtyikcfobjw6yzs7uv3ghxfjjroxavkm3yia" { + t.Fatalf("Wrong root hash cid\r\nexpected %s\r\ngot %s", "baglacgza5wmkus23dhec7m2tmtyikcfobjw6yzs7uv3ghxfjjroxavkm3yia", parseMapElement(data["root"])) + } + if parseFloat(data["time"]) != "1455404037" { + t.Fatalf("Wrong Time\r\nexpected %s\r\ngot %s", "1455404037", parseFloat(data["time"])) + } + if parseMapElement(data["tx"]) != "bagjacgzair6l3dci6smknejlccbrzx7vtr737s56onoksked2t5anxgxvzka" { + t.Fatalf("Wrong Tx root cid\r\nexpected %s\r\ngot %s", "bagjacgzair6l3dci6smknejlccbrzx7vtr737s56onoksked2t5anxgxvzka", parseMapElement(data["tx"])) + } + if parseMapElement(data["uncles"]) != "bagiqcgzadxge32g6y5oxvk4fwvt3ntgudljreri3ssfhie7qufbp2qgusndq" { + t.Fatalf("Wrong Uncle hash cid\r\nexpected %s\r\ngot %s", "bagiqcgzadxge32g6y5oxvk4fwvt3ntgudljreri3ssfhie7qufbp2qgusndq", parseMapElement(data["uncles"])) + } +} + +func TestEthBlockLinks(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + links := ethBlock.Links() + if links[0].Cid.String() != "bagiacgza2m6j3xu774hlvjxhd2fsnuv5ufom6ei4ply3mm3jrleeozt7b62a" { + t.Fatalf("Wrong cid for parent link\r\nexpected: %s\r\ngot %s", "bagiacgza2m6j3xu774hlvjxhd2fsnuv5ufom6ei4ply3mm3jrleeozt7b62a", links[0].Cid.String()) + } + if links[1].Cid.String() != "bagkacgzap6qpnsrkagbdecgybaa63ljx4pr2aa5vlsetdg2f5mpzpbrk2iuq" { + t.Fatalf("Wrong cid for receipt root link\r\nexpected: %s\r\ngot %s", "bagkacgzap6qpnsrkagbdecgybaa63ljx4pr2aa5vlsetdg2f5mpzpbrk2iuq", links[1].Cid.String()) + } + if links[2].Cid.String() != "baglacgza5wmkus23dhec7m2tmtyikcfobjw6yzs7uv3ghxfjjroxavkm3yia" { + t.Fatalf("Wrong cid for state root link\r\nexpected: %s\r\ngot %s", "baglacgza5wmkus23dhec7m2tmtyikcfobjw6yzs7uv3ghxfjjroxavkm3yia", links[2].Cid.String()) + } + if links[3].Cid.String() != "bagjacgzair6l3dci6smknejlccbrzx7vtr737s56onoksked2t5anxgxvzka" { + t.Fatalf("Wrong cid for tx root link\r\nexpected: %s\r\ngot %s", "bagjacgzair6l3dci6smknejlccbrzx7vtr737s56onoksked2t5anxgxvzka", links[3].Cid.String()) + } + if links[4].Cid.String() != "bagiqcgzadxge32g6y5oxvk4fwvt3ntgudljreri3ssfhie7qufbp2qgusndq" { + t.Fatalf("Wrong cid for uncles root link\r\nexpected: %s\r\ngot %s", "bagiqcgzadxge32g6y5oxvk4fwvt3ntgudljreri3ssfhie7qufbp2qgusndq", links[4].Cid.String()) + } +} + +func TestEthBlockResolveEmptyPath(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + obj, rest, err := ethBlock.Resolve([]string{}) + checkError(err, t) + + if ethBlock != obj.(*EthHeader) { + t.Fatal("Should have returned the same eth-block object") + } + + if len(rest) != 0 { + t.Fatalf("Wrong len of rest of the path returned\r\nexpected %d\r\ngot %d", 0, len(rest)) + } +} + +func TestEthBlockResolveNoSuchLink(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + _, _, err := ethBlock.Resolve([]string{"wewonthavethisfieldever"}) + if err == nil { + t.Fatal("Should have failed with unknown field") + } + + if err != ErrInvalidLink { + t.Fatalf("Wrong error message\r\nexpected %s\r\ngot %s", ErrInvalidLink, err.Error()) + } +} + +func TestEthBlockResolveBloom(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + obj, rest, err := ethBlock.Resolve([]string{"bloom"}) + checkError(err, t) + + // The marshaler of types.Bloom should output it as 0x + bloomInText := fmt.Sprintf("%x", obj.(types.Bloom)) + if bloomInText[:10] != "0000000000" { + t.Fatalf("Wrong Bloom\r\nexpected %s\r\ngot %s", "0000000000", bloomInText[:10]) + } + + if len(rest) != 0 { + t.Fatalf("Wrong len of rest of the path returned\r\nexpected %d\r\ngot %d", 0, len(rest)) + } +} + +func TestEthBlockResolveBloomExtraPathElements(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + obj, rest, err := ethBlock.Resolve([]string{"bloom", "unexpected", "extra", "elements"}) + if obj != nil { + t.Fatal("Returned obj should be nil") + } + + if rest != nil { + t.Fatal("Returned rest should be nil") + } + + if err.Error() != "unexpected path elements past bloom" { + t.Fatalf("Wrong error\r\nexpected %s\r\ngot %s", "unexpected path elements past bloom", err.Error()) + } +} + +func TestEthBlockResolveNonLinkFields(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + testCases := map[string][]string{ + "coinbase": {"%x", "52bc44d5378309ee2abf1539bf71de1b7d7be3b5"}, + "difficulty": {"%s", "12555463106190"}, + "extra": {"%s", "0xd783010303844765746887676f312e342e32856c696e7578"}, + "gaslimit": {"%d", "3141592"}, + "gasused": {"%d", "231000"}, + "mixdigest": {"%x", "5b10f4a08a6c209d426f6158bd24b574f4f7b7aa0099c67c14a1f693b4dd04d0"}, + "nonce": {"%x", "f491f46b60fe04b3"}, + "number": {"%s", "999999"}, + "time": {"%d", "1455404037"}, + } + + for field, value := range testCases { + obj, rest, err := ethBlock.Resolve([]string{field}) + checkError(err, t) + + format := value[0] + result := value[1] + if fmt.Sprintf(format, obj) != result { + t.Fatalf("Wrong %v\r\nexpected %v\r\ngot %s", field, result, fmt.Sprintf(format, obj)) + } + + if len(rest) != 0 { + t.Fatalf("Wrong len of rest of the path returned\r\nexpected %d\r\ngot %d", 0, len(rest)) + } + } +} + +func TestEthBlockResolveNonLinkFieldsExtraPathElements(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + testCases := []string{ + "coinbase", + "difficulty", + "extra", + "gaslimit", + "gasused", + "mixdigest", + "nonce", + "number", + "time", + } + + for _, field := range testCases { + obj, rest, err := ethBlock.Resolve([]string{field, "unexpected", "extra", "elements"}) + if obj != nil { + t.Fatal("Returned obj should be nil") + } + + if rest != nil { + t.Fatal("Returned rest should be nil") + } + + if err.Error() != "unexpected path elements past "+field { + t.Fatalf("Wrong error\r\nexpected %s\r\ngot %s", "unexpected path elements past "+field, err.Error()) + } + } +} + +func TestEthBlockResolveLinkFields(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + testCases := map[string]string{ + "parent": "bagiacgza2m6j3xu774hlvjxhd2fsnuv5ufom6ei4ply3mm3jrleeozt7b62a", + "receipts": "bagkacgzap6qpnsrkagbdecgybaa63ljx4pr2aa5vlsetdg2f5mpzpbrk2iuq", + "root": "baglacgza5wmkus23dhec7m2tmtyikcfobjw6yzs7uv3ghxfjjroxavkm3yia", + "tx": "bagjacgzair6l3dci6smknejlccbrzx7vtr737s56onoksked2t5anxgxvzka", + "uncles": "bagiqcgzadxge32g6y5oxvk4fwvt3ntgudljreri3ssfhie7qufbp2qgusndq", + } + + for field, result := range testCases { + obj, rest, err := ethBlock.Resolve([]string{field, "anything", "goes", "here"}) + checkError(err, t) + + lnk, ok := obj.(*node.Link) + if !ok { + t.Fatal("Returned object is not a link") + } + + if lnk.Cid.String() != result { + t.Fatalf("Wrong %s cid\r\nexpected %v\r\ngot %v", field, result, lnk.Cid.String()) + } + + for i, p := range []string{"anything", "goes", "here"} { + if rest[i] != p { + t.Fatalf("Wrong rest of the path returned\r\nexpected %s\r\ngot %s", p, rest[i]) + } + } + } +} + +func TestEthBlockTreeBadParams(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + tree := ethBlock.Tree("non-empty-string", 0) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + tree = ethBlock.Tree("non-empty-string", 1) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + tree = ethBlock.Tree("", 0) + if tree != nil { + t.Fatal("Expected nil to be returned") + } +} + +func TestEThBlockTree(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + tree := ethBlock.Tree("", 1) + lookupElements := map[string]interface{}{ + "bloom": nil, + "coinbase": nil, + "difficulty": nil, + "extra": nil, + "gaslimit": nil, + "gasused": nil, + "mixdigest": nil, + "nonce": nil, + "number": nil, + "parent": nil, + "receipts": nil, + "root": nil, + "time": nil, + "tx": nil, + "uncles": nil, + } + + if len(tree) != len(lookupElements) { + t.Fatalf("Wrong number of elements\r\nexpected %d\r\ngot %d", len(lookupElements), len(tree)) + } + + for _, te := range tree { + if _, ok := lookupElements[te]; !ok { + t.Fatalf("Unexpected Element: %v", te) + } + } +} + +// The two functions above: TestEthBlockResolveNonLinkFields and +// TestEthBlockResolveLinkFields did all the heavy lifting. Then, we will +// just test two use cases. +func TestEthBlockResolveLinksBadLink(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + obj, rest, err := ethBlock.ResolveLink([]string{"supercalifragilist"}) + if obj != nil { + t.Fatalf("Expected obj to be nil") + } + if rest != nil { + t.Fatal("Expected rest to be nil") + } + + if err != ErrInvalidLink { + t.Fatalf("Expected error\r\nexpected %s\r\ngot %s", ErrInvalidLink, err) + } +} + +func TestEthBlockResolveLinksGoodLink(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + obj, rest, err := ethBlock.ResolveLink([]string{"tx", "0", "0", "0"}) + if obj == nil { + t.Fatalf("Expected valid *node.Link obj to be returned") + } + + if rest == nil { + t.Fatal("Expected rest to be returned") + } + for i, p := range []string{"0", "0", "0"} { + if rest[i] != p { + t.Fatalf("Wrong rest of the path returned\r\nexpected %s\r\ngot %s", p, rest[i]) + } + } + + if err != nil { + t.Fatal("Non error expected") + } +} + +/* +These functions below should go away +We are working on test coverage anyways... +*/ +func TestEthBlockCopy(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + defer func() { + r := recover() + if r == nil { + t.Fatal("Expected panic") + } + if r != "implement me" { + t.Fatalf("Wrong panic message\r\nexpected %s\r\ngot %s", "'implement me'", r) + } + }() + + _ = ethBlock.Copy() +} + +func TestEthBlockStat(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + obj, err := ethBlock.Stat() + if obj == nil { + t.Fatal("Expected a not null object node.NodeStat") + } + + if err != nil { + t.Fatal("Expected a nil error") + } +} + +func TestEthBlockSize(t *testing.T) { + ethBlock := prepareDecodedEthBlock("test_data/eth-block-header-rlp-999999", t) + + size, err := ethBlock.Size() + if size != 0 { + t.Fatalf("Wrong size\r\nexpected %d\r\ngot %d", 0, size) + } + + if err != nil { + t.Fatal("Expected a nil error") + } +} + +/* + AUXILIARS +*/ + +// checkError makes 3 lines into 1. +func checkError(err error, t *testing.T) { + if err != nil { + _, fn, line, _ := runtime.Caller(1) + t.Fatalf("[%v:%v] %v", fn, line, err) + } +} + +// parseFloat is a convenience function to test json output +func parseFloat(v interface{}) string { + return strconv.FormatFloat(v.(float64), 'f', 0, 64) +} + +// parseMapElement is a convenience function to tets json output +func parseMapElement(v interface{}) string { + return v.(map[string]interface{})["/"].(string) +} + +// prepareStoredEthBlock reads the block from a file source to get its rawdata +// and computes its cid, for then, feeding it into a new IPLD block function. +// So we can pretend that we got this block from the datastore +func prepareStoredEthBlock(filepath string, t *testing.T) *block.BasicBlock { + // Prepare the "fetched block". This one is supposed to be in the datastore + // and given away by github.com/ipfs/go-ipfs/merkledag + fi, err := os.Open(filepath) + checkError(err, t) + + b, err := ioutil.ReadAll(fi) + checkError(err, t) + + c, err := RawdataToCid(MEthHeader, b, multihash.KECCAK_256) + checkError(err, t) + + // It's good to clarify that this one below is an IPLD block + storedEthBlock, err := block.NewBlockWithCid(b, c) + checkError(err, t) + + return storedEthBlock +} + +// prepareDecodedEthBlock is more complex than function above, as it stores a +// basic block and RLP-decodes it +func prepareDecodedEthBlock(filepath string, t *testing.T) *EthHeader { + // Get the block from the datastore and decode it. + storedEthBlock := prepareStoredEthBlock("test_data/eth-block-header-rlp-999999", t) + ethBlock, err := DecodeEthHeader(storedEthBlock.Cid(), storedEthBlock.RawData()) + checkError(err, t) + + return ethBlock +} + +// testEthBlockFields checks the fields of EthBlock one by one. +func testEthBlockFields(ethBlock *EthHeader, t *testing.T) { + // Was the cid calculated? + if ethBlock.Cid().String() != "bagiacgzawt5236hkiuvrhfyy4jya3qitlt6icfcqgheew6vsptlraokppm4a" { + t.Fatalf("Wrong cid\r\nexpected %s\r\ngot %s", "bagiacgzawt5236hkiuvrhfyy4jya3qitlt6icfcqgheew6vsptlraokppm4a", ethBlock.Cid().String()) + } + + // Do we have the rawdata available? + if fmt.Sprintf("%x", ethBlock.RawData()[:10]) != "f90218a0d33c9dde9fff" { + t.Fatalf("Wrong Rawdata\r\nexpected %s\r\ngot %s", "f90218a0d33c9dde9fff", fmt.Sprintf("%x", ethBlock.RawData()[:10])) + } + + // Proper Fields of types.Header + if fmt.Sprintf("%x", ethBlock.ParentHash) != "d33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4" { + t.Fatalf("Wrong ParentHash\r\nexpected %s\r\ngot %s", "d33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4", fmt.Sprintf("%x", ethBlock.ParentHash)) + } + if fmt.Sprintf("%x", ethBlock.UncleHash) != "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347" { + t.Fatalf("Wrong UncleHash field\r\nexpected %s\r\ngot %s", "1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", fmt.Sprintf("%x", ethBlock.UncleHash)) + } + if fmt.Sprintf("%x", ethBlock.Coinbase) != "52bc44d5378309ee2abf1539bf71de1b7d7be3b5" { + t.Fatalf("Wrong Coinbase\r\nexpected %s\r\ngot %s", "52bc44d5378309ee2abf1539bf71de1b7d7be3b5", fmt.Sprintf("%x", ethBlock.Coinbase)) + } + if fmt.Sprintf("%x", ethBlock.Root) != "ed98aa4b5b19c82fb35364f08508ae0a6dec665fa57663dca94c5d70554cde10" { + t.Fatalf("Wrong Root\r\nexpected %s\r\ngot %s", "ed98aa4b5b19c82fb35364f08508ae0a6dec665fa57663dca94c5d70554cde10", fmt.Sprintf("%x", ethBlock.Root)) + } + if fmt.Sprintf("%x", ethBlock.TxHash) != "447cbd8c48f498a6912b10831cdff59c7fbfcbbe735ca92883d4fa06dcd7ae54" { + t.Fatalf("Wrong TxHash\r\nexpected %s\r\ngot %s", "447cbd8c48f498a6912b10831cdff59c7fbfcbbe735ca92883d4fa06dcd7ae54", fmt.Sprintf("%x", ethBlock.TxHash)) + } + if fmt.Sprintf("%x", ethBlock.ReceiptHash) != "7fa0f6ca2a01823208d80801edad37e3e3a003b55c89319b45eb1f97862ad229" { + t.Fatalf("Wrong ReceiptHash\r\nexpected %s\r\ngot %s", "7fa0f6ca2a01823208d80801edad37e3e3a003b55c89319b45eb1f97862ad229", fmt.Sprintf("%x", ethBlock.ReceiptHash)) + } + if len(ethBlock.Bloom) != 256 { + t.Fatalf("Wrong Bloom Length\r\nexpected %d\r\ngot %d", 256, len(ethBlock.Bloom)) + } + if fmt.Sprintf("%x", ethBlock.Bloom[71:76]) != "0000000000" { // You wouldn't want me to print out the whole bloom field? + t.Fatalf("Wrong Bloom\r\nexpected %s\r\ngot %s", "0000000000", fmt.Sprintf("%x", ethBlock.Bloom[71:76])) + } + if ethBlock.Difficulty.String() != "12555463106190" { + t.Fatalf("Wrong Difficulty\r\nexpected %s\r\ngot %s", "12555463106190", ethBlock.Difficulty.String()) + } + if ethBlock.Number.String() != "999999" { + t.Fatalf("Wrong Block Number\r\nexpected %s\r\ngot %s", "999999", ethBlock.Number.String()) + } + if ethBlock.GasLimit != uint64(3141592) { + t.Fatalf("Wrong Gas Limit\r\nexpected %d\r\ngot %d", 3141592, ethBlock.GasLimit) + } + if ethBlock.GasUsed != uint64(231000) { + t.Fatalf("Wrong Gas Used\r\nexpected %d\r\ngot %d", 231000, ethBlock.GasUsed) + } + if ethBlock.Time != uint64(1455404037) { + t.Fatalf("Wrong Time\r\nexpected %d\r\ngot %d", 1455404037, ethBlock.Time) + } + if fmt.Sprintf("%x", ethBlock.Extra) != "d783010303844765746887676f312e342e32856c696e7578" { + t.Fatalf("Wrong Extra\r\nexpected %s\r\ngot %s", "d783010303844765746887676f312e342e32856c696e7578", fmt.Sprintf("%x", ethBlock.Extra)) + } + if fmt.Sprintf("%x", ethBlock.Nonce) != "f491f46b60fe04b3" { + t.Fatalf("Wrong Nonce\r\nexpected %s\r\ngot %s", "f491f46b60fe04b3", fmt.Sprintf("%x", ethBlock.Nonce)) + } + if fmt.Sprintf("%x", ethBlock.MixDigest) != "5b10f4a08a6c209d426f6158bd24b574f4f7b7aa0099c67c14a1f693b4dd04d0" { + t.Fatalf("Wrong MixDigest\r\nexpected %s\r\ngot %s", "5b10f4a08a6c209d426f6158bd24b574f4f7b7aa0099c67c14a1f693b4dd04d0", fmt.Sprintf("%x", ethBlock.MixDigest)) + } +} diff --git a/statediff/indexer/ipld/eth_log.go b/statediff/indexer/ipld/eth_log.go new file mode 100644 index 000000000..225c44117 --- /dev/null +++ b/statediff/indexer/ipld/eth_log.go @@ -0,0 +1,158 @@ +package ipld + +import ( + "fmt" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// EthLog (eth-log, codec 0x9a), represents an ethereum block header +type EthLog struct { + *types.Log + + rawData []byte + cid cid.Cid +} + +// Static (compile time) check that EthLog satisfies the node.Node interface. +var _ node.Node = (*EthLog)(nil) + +// NewLog create a new EthLog IPLD node +func NewLog(log *types.Log) (*EthLog, error) { + logRaw, err := rlp.EncodeToBytes(log) + if err != nil { + return nil, err + } + c, err := RawdataToCid(MEthLog, logRaw, mh.KECCAK_256) + if err != nil { + return nil, err + } + return &EthLog{ + Log: log, + cid: c, + rawData: logRaw, + }, nil +} + +// DecodeEthLogs takes a cid and its raw binary data +func DecodeEthLogs(c cid.Cid, b []byte) (*EthLog, error) { + l := new(types.Log) + if err := rlp.DecodeBytes(b, l); err != nil { + return nil, err + } + return &EthLog{ + Log: l, + cid: c, + rawData: b, + }, nil +} + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the log. +func (l *EthLog) RawData() []byte { + return l.rawData +} + +// Cid returns the cid of the receipt log. +func (l *EthLog) Cid() cid.Cid { + return l.cid +} + +// String is a helper for output +func (l *EthLog) String() string { + return fmt.Sprintf("", l.cid) +} + +// Loggable returns in a map the type of IPLD Link. +func (l *EthLog) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-log", + } +} + +// Resolve resolves a path through this node, stopping at any link boundary +// and returning the object found as well as the remaining path to traverse +func (l *EthLog) Resolve(p []string) (interface{}, []string, error) { + if len(p) == 0 { + return l, nil, nil + } + + if len(p) > 1 { + return nil, nil, fmt.Errorf("unexpected path elements past %s", p[0]) + } + + switch p[0] { + case "address": + return l.Address, nil, nil + case "data": + // This is a []byte. By default they are marshalled into Base64. + return fmt.Sprintf("0x%x", l.Data), nil, nil + case "topics": + return l.Topics, nil, nil + case "logIndex": + return l.Index, nil, nil + case "removed": + return l.Removed, nil, nil + default: + return nil, nil, ErrInvalidLink + } +} + +// Tree lists all paths within the object under 'path', and up to the given depth. +// To list the entire object (similar to `find .`) pass "" and -1 +func (l *EthLog) Tree(p string, depth int) []string { + if p != "" || depth == 0 { + return nil + } + + return []string{ + "address", + "data", + "topics", + "logIndex", + "removed", + } +} + +// ResolveLink is a helper function that calls resolve and asserts the +// output is a link +func (l *EthLog) ResolveLink(p []string) (*node.Link, []string, error) { + obj, rest, err := l.Resolve(p) + if err != nil { + return nil, nil, err + } + + if lnk, ok := obj.(*node.Link); ok { + return lnk, rest, nil + } + + return nil, nil, fmt.Errorf("resolved item was not a link") +} + +// Copy will go away. It is here to comply with the Node interface. +func (l *EthLog) Copy() node.Node { + panic("implement me") +} + +// Links is a helper function that returns all links within this object +func (l *EthLog) Links() []*node.Link { + return nil +} + +// Stat will go away. It is here to comply with the interface. +func (l *EthLog) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +// Size will go away. It is here to comply with the interface. +func (l *EthLog) Size() (uint64, error) { + return 0, nil +} diff --git a/statediff/indexer/ipld/eth_log_trie.go b/statediff/indexer/ipld/eth_log_trie.go new file mode 100644 index 000000000..8e8af9c79 --- /dev/null +++ b/statediff/indexer/ipld/eth_log_trie.go @@ -0,0 +1,144 @@ +package ipld + +import ( + "fmt" + + node "github.com/ipfs/go-ipld-format" + + "github.com/ipfs/go-cid" + "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// EthLogTrie (eth-tx-trie codec 0x9p) represents +// a node from the transaction trie in ethereum. +type EthLogTrie struct { + *TrieNode +} + +/* + OUTPUT +*/ + +// DecodeEthLogTrie returns an EthLogTrie object from its cid and rawdata. +func DecodeEthLogTrie(c cid.Cid, b []byte) (*EthLogTrie, error) { + tn, err := decodeTrieNode(c, b, decodeEthLogTrieLeaf) + if err != nil { + return nil, err + } + return &EthLogTrie{TrieNode: tn}, nil +} + +// decodeEthLogTrieLeaf parses a eth-log-trie leaf +// from decoded RLP elements +func decodeEthLogTrieLeaf(i []interface{}) ([]interface{}, error) { + l := new(types.Log) + if err := rlp.DecodeBytes(i[1].([]byte), l); err != nil { + return nil, err + } + c, err := RawdataToCid(MEthLogTrie, i[1].([]byte), multihash.KECCAK_256) + if err != nil { + return nil, err + } + + return []interface{}{ + i[0].([]byte), + &EthLog{ + Log: l, + cid: c, + rawData: i[1].([]byte), + }, + }, nil +} + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the transaction. +func (t *EthLogTrie) RawData() []byte { + return t.rawdata +} + +// Cid returns the cid of the transaction. +func (t *EthLogTrie) Cid() cid.Cid { + return t.cid +} + +// String is a helper for output +func (t *EthLogTrie) String() string { + return fmt.Sprintf("", t.cid) +} + +// Loggable returns in a map the type of IPLD Link. +func (t *EthLogTrie) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-log-trie", + } +} + +// logTrie wraps a localTrie for use on the receipt trie. +type logTrie struct { + *localTrie +} + +// newLogTrie initializes and returns a logTrie. +func newLogTrie() *logTrie { + return &logTrie{ + localTrie: newLocalTrie(), + } +} + +// getNodes invokes the localTrie, which computes the root hash of the +// log trie and returns its sql keys, to return a slice +// of EthLogTrie nodes. +func (rt *logTrie) getNodes() ([]node.Node, error) { + keys, err := rt.getKeys() + if err != nil { + return nil, err + } + + out := make([]node.Node, 0, len(keys)) + for _, k := range keys { + n, err := rt.getNodeFromDB(k) + if err != nil { + return nil, err + } + out = append(out, n) + } + + return out, nil +} + +func (rt *logTrie) getNodeFromDB(key []byte) (*EthLogTrie, error) { + rawdata, err := rt.db.Get(key) + if err != nil { + return nil, err + } + tn := &TrieNode{ + cid: keccak256ToCid(MEthLogTrie, key), + rawdata: rawdata, + } + return &EthLogTrie{TrieNode: tn}, nil +} + +// getLeafNodes invokes the localTrie, which returns a slice +// of EthLogTrie leaf nodes. +func (rt *logTrie) getLeafNodes() ([]*EthLogTrie, []*nodeKey, error) { + keys, err := rt.getLeafKeys() + if err != nil { + return nil, nil, err + } + out := make([]*EthLogTrie, 0, len(keys)) + for _, k := range keys { + n, err := rt.getNodeFromDB(k.dbKey) + if err != nil { + return nil, nil, err + } + out = append(out, n) + } + + return out, keys, nil +} diff --git a/statediff/indexer/ipld/eth_parser.go b/statediff/indexer/ipld/eth_parser.go new file mode 100644 index 000000000..03061f828 --- /dev/null +++ b/statediff/indexer/ipld/eth_parser.go @@ -0,0 +1,302 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "bytes" + "encoding/json" + "fmt" + "io" + "io/ioutil" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" +) + +// FromBlockRLP takes an RLP message representing +// an ethereum block header or body (header, ommers and txs) +// to return it as a set of IPLD nodes for further processing. +func FromBlockRLP(r io.Reader) (*EthHeader, []*EthTx, []*EthTxTrie, error) { + // We may want to use this stream several times + rawdata, err := ioutil.ReadAll(r) + if err != nil { + return nil, nil, nil, err + } + + // Let's try to decode the received element as a block body + var decodedBlock types.Block + err = rlp.Decode(bytes.NewBuffer(rawdata), &decodedBlock) + if err != nil { + if err.Error()[:41] != "rlp: expected input list for types.Header" { + return nil, nil, nil, err + } + + // Maybe it is just a header... (body sans ommers and txs) + var decodedHeader types.Header + err := rlp.Decode(bytes.NewBuffer(rawdata), &decodedHeader) + if err != nil { + return nil, nil, nil, err + } + + c, err := RawdataToCid(MEthHeader, rawdata, multihash.KECCAK_256) + if err != nil { + return nil, nil, nil, err + } + // It was a header + return &EthHeader{ + Header: &decodedHeader, + cid: c, + rawdata: rawdata, + }, nil, nil, nil + } + + // This is a block body (header + ommers + txs) + // We'll extract the header bits here + headerRawData := getRLP(decodedBlock.Header()) + c, err := RawdataToCid(MEthHeader, headerRawData, multihash.KECCAK_256) + if err != nil { + return nil, nil, nil, err + } + ethBlock := &EthHeader{ + Header: decodedBlock.Header(), + cid: c, + rawdata: headerRawData, + } + + // Process the found eth-tx objects + ethTxNodes, ethTxTrieNodes, err := processTransactions(decodedBlock.Transactions(), + decodedBlock.Header().TxHash[:]) + if err != nil { + return nil, nil, nil, err + } + + return ethBlock, ethTxNodes, ethTxTrieNodes, nil +} + +// FromBlockJSON takes the output of an ethereum client JSON API +// (i.e. parity or geth) and returns a set of IPLD nodes. +func FromBlockJSON(r io.Reader) (*EthHeader, []*EthTx, []*EthTxTrie, error) { + var obj objJSONHeader + dec := json.NewDecoder(r) + err := dec.Decode(&obj) + if err != nil { + return nil, nil, nil, err + } + + headerRawData := getRLP(&obj.Result.Header) + c, err := RawdataToCid(MEthHeader, headerRawData, multihash.KECCAK_256) + if err != nil { + return nil, nil, nil, err + } + ethBlock := &EthHeader{ + Header: &obj.Result.Header, + cid: c, + rawdata: headerRawData, + } + + // Process the found eth-tx objects + ethTxNodes, ethTxTrieNodes, err := processTransactions(obj.Result.Transactions, + obj.Result.Header.TxHash[:]) + if err != nil { + return nil, nil, nil, err + } + + return ethBlock, ethTxNodes, ethTxTrieNodes, nil +} + +// FromBlockAndReceipts takes a block and processes it +// to return it a set of IPLD nodes for further processing. +func FromBlockAndReceipts(block *types.Block, receipts []*types.Receipt) (*EthHeader, []*EthHeader, []*EthTx, []*EthTxTrie, []*EthReceipt, []*EthRctTrie, [][]node.Node, [][]cid.Cid, []cid.Cid, error) { + // Process the header + headerNode, err := NewEthHeader(block.Header()) + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, nil, nil, err + } + + // Process the uncles + uncleNodes := make([]*EthHeader, len(block.Uncles())) + for i, uncle := range block.Uncles() { + uncleNode, err := NewEthHeader(uncle) + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, nil, nil, err + } + uncleNodes[i] = uncleNode + } + + // Process the txs + txNodes, txTrieNodes, err := processTransactions(block.Transactions(), + block.Header().TxHash[:]) + if err != nil { + return nil, nil, nil, nil, nil, nil, nil, nil, nil, err + } + + // Process the receipts and logs + rctNodes, tctTrieNodes, logTrieAndLogNodes, logLeafNodeCIDs, rctLeafNodeCIDs, err := processReceiptsAndLogs(receipts, + block.Header().ReceiptHash[:]) + + return headerNode, uncleNodes, txNodes, txTrieNodes, rctNodes, tctTrieNodes, logTrieAndLogNodes, logLeafNodeCIDs, rctLeafNodeCIDs, err +} + +// processTransactions will take the found transactions in a parsed block body +// to return IPLD node slices for eth-tx and eth-tx-trie +func processTransactions(txs []*types.Transaction, expectedTxRoot []byte) ([]*EthTx, []*EthTxTrie, error) { + var ethTxNodes []*EthTx + transactionTrie := newTxTrie() + + for idx, tx := range txs { + ethTx, err := NewEthTx(tx) + if err != nil { + return nil, nil, err + } + ethTxNodes = append(ethTxNodes, ethTx) + if err := transactionTrie.Add(idx, ethTx.RawData()); err != nil { + return nil, nil, err + } + } + + if !bytes.Equal(transactionTrie.rootHash(), expectedTxRoot) { + return nil, nil, fmt.Errorf("wrong transaction hash computed") + } + txTrieNodes, err := transactionTrie.getNodes() + return ethTxNodes, txTrieNodes, err +} + +// processReceiptsAndLogs will take in receipts +// to return IPLD node slices for eth-rct, eth-rct-trie, eth-log, eth-log-trie, eth-log-trie-CID, eth-rct-trie-CID +func processReceiptsAndLogs(rcts []*types.Receipt, expectedRctRoot []byte) ([]*EthReceipt, []*EthRctTrie, [][]node.Node, [][]cid.Cid, []cid.Cid, error) { + // Pre allocating memory. + ethRctNodes := make([]*EthReceipt, 0, len(rcts)) + ethLogleafNodeCids := make([][]cid.Cid, 0, len(rcts)) + ethLogTrieAndLogNodes := make([][]node.Node, 0, len(rcts)) + + receiptTrie := NewRctTrie() + + for idx, rct := range rcts { + // Process logs for each receipt. + logTrieNodes, leafNodeCids, logTrieHash, err := processLogs(rct.Logs) + if err != nil { + return nil, nil, nil, nil, nil, err + } + rct.LogRoot = logTrieHash + ethLogTrieAndLogNodes = append(ethLogTrieAndLogNodes, logTrieNodes) + ethLogleafNodeCids = append(ethLogleafNodeCids, leafNodeCids) + + ethRct, err := NewReceipt(rct) + if err != nil { + return nil, nil, nil, nil, nil, err + } + + ethRctNodes = append(ethRctNodes, ethRct) + if err = receiptTrie.Add(idx, ethRct.RawData()); err != nil { + return nil, nil, nil, nil, nil, err + } + } + + if !bytes.Equal(receiptTrie.rootHash(), expectedRctRoot) { + return nil, nil, nil, nil, nil, fmt.Errorf("wrong receipt hash computed") + } + + rctTrieNodes, err := receiptTrie.GetNodes() + if err != nil { + return nil, nil, nil, nil, nil, err + } + + rctLeafNodes, keys, err := receiptTrie.GetLeafNodes() + if err != nil { + return nil, nil, nil, nil, nil, err + } + + ethRctleafNodeCids := make([]cid.Cid, len(rctLeafNodes)) + for i, rln := range rctLeafNodes { + var idx uint + + r := bytes.NewReader(keys[i].TrieKey) + err = rlp.Decode(r, &idx) + if err != nil { + return nil, nil, nil, nil, nil, err + } + ethRctleafNodeCids[idx] = rln.Cid() + } + + return ethRctNodes, rctTrieNodes, ethLogTrieAndLogNodes, ethLogleafNodeCids, ethRctleafNodeCids, err +} + +const keccak256Length = 32 + +func processLogs(logs []*types.Log) ([]node.Node, []cid.Cid, common.Hash, error) { + logTr := newLogTrie() + shortLog := make(map[uint64]*EthLog, len(logs)) + for idx, log := range logs { + logRaw, err := rlp.EncodeToBytes(log) + if err != nil { + return nil, nil, common.Hash{}, err + } + // if len(logRaw) <= keccak256Length it is possible this value's "leaf node" + // will be stored in its parent branch but only if len(partialPathOfTheNode) + len(logRaw) <= keccak256Length + // But we can't tell what the partial path will be until the trie is Commit()-ed + // So wait until we collect all the leaf nodes, and if we are missing any at the indexes we note in shortLogCIDs + // we know that these "leaf nodes" were internalized into their parent branch node and we move forward with + // using the cid.Cid we cached in shortLogCIDs + if len(logRaw) <= keccak256Length { + logNode, err := NewLog(log) + if err != nil { + return nil, nil, common.Hash{}, err + } + shortLog[uint64(idx)] = logNode + } + if err = logTr.Add(idx, logRaw); err != nil { + return nil, nil, common.Hash{}, err + } + } + + logTrieNodes, err := logTr.getNodes() + if err != nil { + return nil, nil, common.Hash{}, err + } + + leafNodes, keys, err := logTr.getLeafNodes() + if err != nil { + return nil, nil, common.Hash{}, err + } + leafNodeCids := make([]cid.Cid, len(logs)) + for i, ln := range leafNodes { + var idx uint + + r := bytes.NewReader(keys[i].TrieKey) + err = rlp.Decode(r, &idx) + if err != nil { + return nil, nil, common.Hash{}, err + } + leafNodeCids[idx] = ln.Cid() + } + // this is where we check which logs <= keccak256Length were actually internalized into parent branch node + // and replace those that were with the cid.Cid for the raw log IPLD + for i, l := range shortLog { + if !leafNodeCids[i].Defined() { + leafNodeCids[i] = l.Cid() + // if the leaf node was internalized, we append an IPLD for log itself to the list of IPLDs we need to publish + logTrieNodes = append(logTrieNodes, l) + } + } + + return logTrieNodes, leafNodeCids, common.BytesToHash(logTr.rootHash()), err +} diff --git a/statediff/indexer/ipld/eth_parser_test.go b/statediff/indexer/ipld/eth_parser_test.go new file mode 100644 index 000000000..bcf28efde --- /dev/null +++ b/statediff/indexer/ipld/eth_parser_test.go @@ -0,0 +1,108 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "io/ioutil" + "path/filepath" + "testing" + + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" +) + +type kind string + +const ( + legacy kind = "legacy" + eip1559 kind = "eip2930" +) + +var blockFileNames = []string{ + "eth-block-12252078", + "eth-block-12365585", + "eth-block-12365586", +} + +var receiptsFileNames = []string{ + "eth-receipts-12252078", + "eth-receipts-12365585", + "eth-receipts-12365586", +} + +var kinds = []kind{ + eip1559, + eip1559, + legacy, +} + +type testCase struct { + kind kind + block *types.Block + receipts types.Receipts +} + +func loadBlockData(t *testing.T) []testCase { + fileDir := "./eip2930_test_data" + testCases := make([]testCase, len(blockFileNames)) + for i, blockFileName := range blockFileNames { + blockRLP, err := ioutil.ReadFile(filepath.Join(fileDir, blockFileName)) + if err != nil { + t.Fatalf("failed to load blockRLP from file, err %v", err) + } + block := new(types.Block) + if err := rlp.DecodeBytes(blockRLP, block); err != nil { + t.Fatalf("failed to decode blockRLP, err %v", err) + } + receiptsFileName := receiptsFileNames[i] + receiptsRLP, err := ioutil.ReadFile(filepath.Join(fileDir, receiptsFileName)) + if err != nil { + t.Fatalf("failed to load receiptsRLP from file, err %s", err) + } + receipts := make(types.Receipts, 0) + if err := rlp.DecodeBytes(receiptsRLP, &receipts); err != nil { + t.Fatalf("failed to decode receiptsRLP, err %s", err) + } + testCases[i] = testCase{ + block: block, + receipts: receipts, + kind: kinds[i], + } + } + return testCases +} + +func TestFromBlockAndReceipts(t *testing.T) { + testCases := loadBlockData(t) + for _, tc := range testCases { + _, _, _, _, _, _, _, _, _, err := FromBlockAndReceipts(tc.block, tc.receipts) + if err != nil { + t.Fatalf("error generating IPLDs from block and receipts, err %v, kind %s, block hash %s", err, tc.kind, tc.block.Hash()) + } + } +} + +func TestProcessLogs(t *testing.T) { + logs := []*types.Log{mocks.MockLog1, mocks.MockLog2} + nodes, cids, _, err := processLogs(logs) + require.NoError(t, err) + require.GreaterOrEqual(t, len(nodes), len(logs)) + require.Equal(t, len(logs), len(cids)) +} diff --git a/statediff/indexer/ipld/eth_receipt.go b/statediff/indexer/ipld/eth_receipt.go new file mode 100644 index 000000000..ccd785515 --- /dev/null +++ b/statediff/indexer/ipld/eth_receipt.go @@ -0,0 +1,205 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "encoding/json" + "fmt" + "strconv" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/core/types" +) + +type EthReceipt struct { + *types.Receipt + + rawdata []byte + cid cid.Cid +} + +// Static (compile time) check that EthReceipt satisfies the node.Node interface. +var _ node.Node = (*EthReceipt)(nil) + +/* + INPUT +*/ + +// NewReceipt converts a types.ReceiptForStorage to an EthReceipt IPLD node +func NewReceipt(receipt *types.Receipt) (*EthReceipt, error) { + rctRaw, err := receipt.MarshalBinary() + if err != nil { + return nil, err + } + c, err := RawdataToCid(MEthTxReceipt, rctRaw, mh.KECCAK_256) + if err != nil { + return nil, err + } + return &EthReceipt{ + Receipt: receipt, + cid: c, + rawdata: rctRaw, + }, nil +} + +/* + OUTPUT +*/ + +// DecodeEthReceipt takes a cid and its raw binary data +// from IPFS and returns an EthTx object for further processing. +func DecodeEthReceipt(c cid.Cid, b []byte) (*EthReceipt, error) { + r := new(types.Receipt) + if err := r.UnmarshalBinary(b); err != nil { + return nil, err + } + return &EthReceipt{ + Receipt: r, + cid: c, + rawdata: b, + }, nil +} + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the receipt. +func (r *EthReceipt) RawData() []byte { + return r.rawdata +} + +// Cid returns the cid of the receipt. +func (r *EthReceipt) Cid() cid.Cid { + return r.cid +} + +// String is a helper for output +func (r *EthReceipt) String() string { + return fmt.Sprintf("", r.cid) +} + +// Loggable returns in a map the type of IPLD Link. +func (r *EthReceipt) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-receipt", + } +} + +// Resolve resolves a path through this node, stopping at any link boundary +// and returning the object found as well as the remaining path to traverse +func (r *EthReceipt) Resolve(p []string) (interface{}, []string, error) { + if len(p) == 0 { + return r, nil, nil + } + + first, rest := p[0], p[1:] + if first != "logs" && len(p) != 1 { + return nil, nil, fmt.Errorf("unexpected path elements past %s", first) + } + + switch first { + case "logs": + return &node.Link{Cid: commonHashToCid(MEthLog, r.LogRoot)}, rest, nil + case "root": + return r.PostState, nil, nil + case "status": + return r.Status, nil, nil + case "cumulativeGasUsed": + return r.CumulativeGasUsed, nil, nil + case "logsBloom": + return r.Bloom, nil, nil + case "transactionHash": + return r.TxHash, nil, nil + case "contractAddress": + return r.ContractAddress, nil, nil + case "gasUsed": + return r.GasUsed, nil, nil + case "type": + return r.Type, nil, nil + default: + return nil, nil, ErrInvalidLink + } +} + +// Tree lists all paths within the object under 'path', and up to the given depth. +// To list the entire object (similar to `find .`) pass "" and -1 +func (r *EthReceipt) Tree(p string, depth int) []string { + if p != "" || depth == 0 { + return nil + } + return []string{"type", "root", "status", "cumulativeGasUsed", "logsBloom", "logs", "transactionHash", "contractAddress", "gasUsed"} +} + +// ResolveLink is a helper function that calls resolve and asserts the +// output is a link +func (r *EthReceipt) ResolveLink(p []string) (*node.Link, []string, error) { + obj, rest, err := r.Resolve(p) + if err != nil { + return nil, nil, err + } + + if lnk, ok := obj.(*node.Link); ok { + return lnk, rest, nil + } + + return nil, nil, fmt.Errorf("resolved item was not a link") +} + +// Copy will go away. It is here to comply with the Node interface. +func (r *EthReceipt) Copy() node.Node { + panic("implement me") +} + +// Links is a helper function that returns all links within this object +func (r *EthReceipt) Links() []*node.Link { + return []*node.Link{ + {Cid: commonHashToCid(MEthLog, r.LogRoot)}, + } +} + +// Stat will go away. It is here to comply with the interface. +func (r *EthReceipt) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +// Size will go away. It is here to comply with the interface. +func (r *EthReceipt) Size() (uint64, error) { + return strconv.ParseUint(r.Receipt.Size().String(), 10, 64) +} + +/* + EthReceipt functions +*/ + +// MarshalJSON processes the receipt into readable JSON format. +func (r *EthReceipt) MarshalJSON() ([]byte, error) { + out := map[string]interface{}{ + "root": r.PostState, + "status": r.Status, + "cumulativeGasUsed": r.CumulativeGasUsed, + "logsBloom": r.Bloom, + "logs": r.Logs, + "transactionHash": r.TxHash, + "contractAddress": r.ContractAddress, + "gasUsed": r.GasUsed, + } + return json.Marshal(out) +} diff --git a/statediff/indexer/ipld/eth_receipt_trie.go b/statediff/indexer/ipld/eth_receipt_trie.go new file mode 100644 index 000000000..592429f94 --- /dev/null +++ b/statediff/indexer/ipld/eth_receipt_trie.go @@ -0,0 +1,174 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" +) + +// EthRctTrie (eth-tx-trie codec 0x92) represents +// a node from the transaction trie in ethereum. +type EthRctTrie struct { + *TrieNode +} + +// Static (compile time) check that EthRctTrie satisfies the node.Node interface. +var _ node.Node = (*EthRctTrie)(nil) + +/* + INPUT +*/ + +// To create a proper trie of the eth-tx-trie objects, it is required +// to input all transactions belonging to a forest in a single step. +// We are adding the transactions, and creating its trie on +// block body parsing time. + +/* + OUTPUT +*/ + +// DecodeEthRctTrie returns an EthRctTrie object from its cid and rawdata. +func DecodeEthRctTrie(c cid.Cid, b []byte) (*EthRctTrie, error) { + tn, err := decodeTrieNode(c, b, decodeEthRctTrieLeaf) + if err != nil { + return nil, err + } + return &EthRctTrie{TrieNode: tn}, nil +} + +// decodeEthRctTrieLeaf parses a eth-rct-trie leaf +// from decoded RLP elements +func decodeEthRctTrieLeaf(i []interface{}) ([]interface{}, error) { + r := new(types.Receipt) + if err := r.UnmarshalBinary(i[1].([]byte)); err != nil { + return nil, err + } + c, err := RawdataToCid(MEthTxReceipt, i[1].([]byte), multihash.KECCAK_256) + if err != nil { + return nil, err + } + return []interface{}{ + i[0].([]byte), + &EthReceipt{ + Receipt: r, + cid: c, + rawdata: i[1].([]byte), + }, + }, nil +} + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the transaction. +func (t *EthRctTrie) RawData() []byte { + return t.rawdata +} + +// Cid returns the cid of the transaction. +func (t *EthRctTrie) Cid() cid.Cid { + return t.cid +} + +// String is a helper for output +func (t *EthRctTrie) String() string { + return fmt.Sprintf("", t.cid) +} + +// Loggable returns in a map the type of IPLD Link. +func (t *EthRctTrie) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-rct-trie", + } +} + +/* + EthRctTrie functions +*/ + +// rctTrie wraps a localTrie for use on the receipt trie. +type rctTrie struct { + *localTrie +} + +// NewRctTrie initializes and returns a rctTrie. +func NewRctTrie() *rctTrie { + return &rctTrie{ + localTrie: newLocalTrie(), + } +} + +// GetNodes invokes the localTrie, which computes the root hash of the +// transaction trie and returns its sql keys, to return a slice +// of EthRctTrie nodes. +func (rt *rctTrie) GetNodes() ([]*EthRctTrie, error) { + keys, err := rt.getKeys() + if err != nil { + return nil, err + } + var out []*EthRctTrie + + for _, k := range keys { + n, err := rt.getNodeFromDB(k) + if err != nil { + return nil, err + } + out = append(out, n) + } + + return out, nil +} + +// GetLeafNodes invokes the localTrie, which returns a slice +// of EthRctTrie leaf nodes. +func (rt *rctTrie) GetLeafNodes() ([]*EthRctTrie, []*nodeKey, error) { + keys, err := rt.getLeafKeys() + if err != nil { + return nil, nil, err + } + + out := make([]*EthRctTrie, 0, len(keys)) + for _, k := range keys { + n, err := rt.getNodeFromDB(k.dbKey) + if err != nil { + return nil, nil, err + } + out = append(out, n) + } + + return out, keys, nil +} + +func (rt *rctTrie) getNodeFromDB(key []byte) (*EthRctTrie, error) { + rawdata, err := rt.db.Get(key) + if err != nil { + return nil, err + } + tn := &TrieNode{ + cid: keccak256ToCid(MEthTxReceiptTrie, key), + rawdata: rawdata, + } + + return &EthRctTrie{TrieNode: tn}, nil +} diff --git a/statediff/indexer/ipld/eth_state.go b/statediff/indexer/ipld/eth_state.go new file mode 100644 index 000000000..9a2c230e2 --- /dev/null +++ b/statediff/indexer/ipld/eth_state.go @@ -0,0 +1,126 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "fmt" + "io" + "io/ioutil" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/rlp" +) + +// EthStateTrie (eth-state-trie, codec 0x96), represents +// a node from the satte trie in ethereum. +type EthStateTrie struct { + *TrieNode +} + +// Static (compile time) check that EthStateTrie satisfies the node.Node interface. +var _ node.Node = (*EthStateTrie)(nil) + +/* + INPUT +*/ + +// FromStateTrieRLPFile takes the RLP representation of an ethereum +// state trie node to return it as an IPLD node for further processing. +func FromStateTrieRLPFile(r io.Reader) (*EthStateTrie, error) { + raw, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + return FromStateTrieRLP(raw) +} + +// FromStateTrieRLP takes the RLP representation of an ethereum +// state trie node to return it as an IPLD node for further processing. +func FromStateTrieRLP(raw []byte) (*EthStateTrie, error) { + c, err := RawdataToCid(MEthStateTrie, raw, multihash.KECCAK_256) + if err != nil { + return nil, err + } + // Let's run the whole mile and process the nodeKind and + // its elements, in case somebody would need this function + // to parse an RLP element from the filesystem + return DecodeEthStateTrie(c, raw) +} + +/* + OUTPUT +*/ + +// DecodeEthStateTrie returns an EthStateTrie object from its cid and rawdata. +func DecodeEthStateTrie(c cid.Cid, b []byte) (*EthStateTrie, error) { + tn, err := decodeTrieNode(c, b, decodeEthStateTrieLeaf) + if err != nil { + return nil, err + } + return &EthStateTrie{TrieNode: tn}, nil +} + +// decodeEthStateTrieLeaf parses a eth-tx-trie leaf +// from decoded RLP elements +func decodeEthStateTrieLeaf(i []interface{}) ([]interface{}, error) { + var account EthAccount + err := rlp.DecodeBytes(i[1].([]byte), &account) + if err != nil { + return nil, err + } + c, err := RawdataToCid(MEthAccountSnapshot, i[1].([]byte), multihash.KECCAK_256) + if err != nil { + return nil, err + } + return []interface{}{ + i[0].([]byte), + &EthAccountSnapshot{ + EthAccount: &account, + cid: c, + rawdata: i[1].([]byte), + }, + }, nil +} + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the state trie node. +func (st *EthStateTrie) RawData() []byte { + return st.rawdata +} + +// Cid returns the cid of the state trie node. +func (st *EthStateTrie) Cid() cid.Cid { + return st.cid +} + +// String is a helper for output +func (st *EthStateTrie) String() string { + return fmt.Sprintf("", st.cid) +} + +// Loggable returns in a map the type of IPLD Link. +func (st *EthStateTrie) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-state-trie", + } +} diff --git a/statediff/indexer/ipld/eth_state_test.go b/statediff/indexer/ipld/eth_state_test.go new file mode 100644 index 000000000..49eea96f3 --- /dev/null +++ b/statediff/indexer/ipld/eth_state_test.go @@ -0,0 +1,321 @@ +package ipld + +import ( + "fmt" + "os" + "testing" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" +) + +func TestStateTrieNodeEvenExtensionParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-eb2f5f") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + if output.nodeKind != "extension" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "extension", output.nodeKind) + } + + if len(output.elements) != 2 { + t.Fatalf("Wrong number of elements for an extension node\r\nexpected %d\r\ngot %d", 2, len(output.elements)) + } + + if fmt.Sprintf("%x", output.elements[0]) != "0d08" { + t.Fatalf("Wrong key\r\nexpected %s\r\ngot %s", "0d08", fmt.Sprintf("%x", output.elements[0])) + } + + if output.elements[1].(cid.Cid).String() != + "baglacgzalnzmhhnxudxtga6t3do2rctb6ycgyj6mjnycoamlnc733nnbkd6q" { + t.Fatalf("Wrong CID\r\nexpected %s\r\ngot %s", "baglacgzalnzmhhnxudxtga6t3do2rctb6ycgyj6mjnycoamlnc733nnbkd6q", output.elements[1].(cid.Cid).String()) + } +} + +func TestStateTrieNodeOddExtensionParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-56864f") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + if output.nodeKind != "extension" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "extension", output.nodeKind) + } + + if len(output.elements) != 2 { + t.Fatalf("Wrong number of elements for an extension node\r\nexpected %d\r\ngot %d", 2, len(output.elements)) + } + + if fmt.Sprintf("%x", output.elements[0]) != "02" { + t.Fatalf("Wrong key\r\nexpected %s\r\ngot %s", "02", fmt.Sprintf("%x", output.elements[0])) + } + + if output.elements[1].(cid.Cid).String() != + "baglacgzaizf2czb7wztoox4lu23qkwkbfamqsdzcmejzr3rsszrvkaktpfeq" { + t.Fatalf("Wrong CID\r\nexpected %s\r\ngot %s", "baglacgzaizf2czb7wztoox4lu23qkwkbfamqsdzcmejzr3rsszrvkaktpfeq", output.elements[1].(cid.Cid).String()) + } +} + +func TestStateTrieNodeEvenLeafParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-0e8b34") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + if output.nodeKind != "leaf" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "leaf", output.nodeKind) + } + + if len(output.elements) != 2 { + t.Fatalf("Wrong number of elements for an extension node\r\nexpected %d\r\ngot %d", 2, len(output.elements)) + } + + // bd66f60e5b954e1af93ded1b02cb575ff0ed6d9241797eff7576b0bf0637 + if fmt.Sprintf("%x", output.elements[0].([]byte)[0:10]) != "0b0d06060f06000e050b" { + t.Fatalf("Wrong key\r\nexpected %s\r\ngot %s", "0b0d06060f06000e050b", fmt.Sprintf("%x", output.elements[0].([]byte)[0:10])) + } + + if output.elements[1].(*EthAccountSnapshot).String() != + "" { + t.Fatalf("Wrong String()\r\nexpected %s\r\ngot %s", "", output.elements[1].(*EthAccountSnapshot).String()) + } +} + +func TestStateTrieNodeOddLeafParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-c9070d") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + if output.nodeKind != "leaf" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "leaf", output.nodeKind) + } + + if len(output.elements) != 2 { + t.Fatalf("Wrong number of elements for an extension node\r\nexpected %d\r\ngot %d", 2, len(output.elements)) + } + + // 6c9db9bb545a03425e300f3ee72bae098110336dd3eaf48c20a2e5b6865fc + if fmt.Sprintf("%x", output.elements[0].([]byte)[0:10]) != "060c090d0b090b0b0504" { + t.Fatalf("Wrong key\r\nexpected %s\r\ngot %s", "060c090d0b090b0b0504", fmt.Sprintf("%x", output.elements[0].([]byte)[0:10])) + } + + if output.elements[1].(*EthAccountSnapshot).String() != + "" { + t.Fatalf("Wrong String()\r\nexpected %s\r\ngot %s", "", output.elements[1].(*EthAccountSnapshot).String()) + } +} + +/* +Block INTERFACE +*/ +func TestStateTrieBlockElements(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-d7f897") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + if fmt.Sprintf("%x", output.RawData())[:10] != "f90211a090" { + t.Fatalf("Wrong Data\r\nexpected %s\r\ngot %s", "f90211a090", fmt.Sprintf("%x", output.RawData())[:10]) + } + + if output.Cid().String() != + "baglacgza274jot5vvr4ntlajtonnkaml5xbm4cts3liye6qxbhndawapavca" { + t.Fatalf("Wrong Cid\r\nexpected %s\r\ngot %s", "baglacgza274jot5vvr4ntlajtonnkaml5xbm4cts3liye6qxbhndawapavca", output.Cid().String()) + } +} + +func TestStateTrieString(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-d7f897") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + if output.String() != + "" { + t.Fatalf("Wrong String()\r\nexpected %s\r\ngot %s", "", output.String()) + } +} + +func TestStateTrieLoggable(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-d7f897") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + l := output.Loggable() + if _, ok := l["type"]; !ok { + t.Fatal("Loggable map expected the field 'type'") + } + + if l["type"] != "eth-state-trie" { + t.Fatalf("Wrong Loggable 'type' value\r\nexpected %s\r\ngot %s", "eth-state-trie", l["type"]) + } +} + +/* + TRIE NODE (Through EthStateTrie) + Node INTERFACE +*/ + +func TestTraverseStateTrieWithResolve(t *testing.T) { + var err error + + stMap := prepareStateTrieMap(t) + + // This is the cid of the root of the block 0 + // baglacgza274jot5vvr4ntlajtonnkaml5xbm4cts3liye6qxbhndawapavca + currentNode := stMap["baglacgza274jot5vvr4ntlajtonnkaml5xbm4cts3liye6qxbhndawapavca"] + + // This is the path we want to traverse + // The eth address is 0x5abfec25f74cd88437631a7731906932776356f9 + // Its keccak-256 is cdd3e25edec0a536a05f5e5ab90a5603624c0ed77453b2e8f955cf8b43d4d0fb + // We use the keccak-256(addr) to traverse the state trie in ethereum. + var traversePath []string + for _, s := range "cdd3e25edec0a536a05f5e5ab90a5603624c0ed77453b2e8f955cf8b43d4d0fb" { + traversePath = append(traversePath, string(s)) + } + traversePath = append(traversePath, "balance") + + var obj interface{} + for { + obj, traversePath, err = currentNode.Resolve(traversePath) + link, ok := obj.(*node.Link) + if !ok { + break + } + if err != nil { + t.Fatal("Error should be nil") + } + + currentNode = stMap[link.Cid.String()] + if currentNode == nil { + t.Fatal("state trie node not found in memory map") + } + } + + if fmt.Sprintf("%v", obj) != "11901484239480000000000000" { + t.Fatalf("Wrong balance value\r\nexpected %s\r\ngot %s", "11901484239480000000000000", fmt.Sprintf("%v", obj)) + } +} + +func TestStateTrieResolveLinks(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-eb2f5f") + checkError(err, t) + + stNode, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + // bad case + obj, rest, err := stNode.ResolveLink([]string{"supercalifragilist"}) + if obj != nil { + t.Fatalf("Expected obj to be nil") + } + if rest != nil { + t.Fatal("Expected rest to be nil") + } + if err.Error() != "invalid path element" { + t.Fatalf("Wrong error\r\nexpected %s\r\ngot %s", "invalid path element", err.Error()) + } + + // good case + obj, rest, err = stNode.ResolveLink([]string{"d8"}) + if obj == nil { + t.Fatalf("Expected a not nil obj to be returned") + } + if rest != nil { + t.Fatal("Expected rest to be nil") + } + if err != nil { + t.Fatal("Expected error to be nil") + } +} + +func TestStateTrieCopy(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-eb2f5f") + checkError(err, t) + + stNode, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + defer func() { + r := recover() + if r == nil { + t.Fatal("Expected panic") + } + if r != "implement me" { + t.Fatalf("Wrong panic message\r\nexpected %s\r\ngot %s", "'implement me'", r) + } + }() + + _ = stNode.Copy() +} + +func TestStateTrieStat(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-eb2f5f") + checkError(err, t) + + stNode, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + obj, err := stNode.Stat() + if obj == nil { + t.Fatal("Expected a not null object node.NodeStat") + } + + if err != nil { + t.Fatal("Expected a nil error") + } +} + +func TestStateTrieSize(t *testing.T) { + fi, err := os.Open("test_data/eth-state-trie-rlp-eb2f5f") + checkError(err, t) + + stNode, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + size, err := stNode.Size() + if size != uint64(0) { + t.Fatalf("Wrong size\r\nexpected %d\r\ngot %d", 0, size) + } + + if err != nil { + t.Fatal("Expected a nil error") + } +} + +func prepareStateTrieMap(t *testing.T) map[string]*EthStateTrie { + filepaths := []string{ + "test_data/eth-state-trie-rlp-0e8b34", + "test_data/eth-state-trie-rlp-56864f", + "test_data/eth-state-trie-rlp-6fc2d7", + "test_data/eth-state-trie-rlp-727994", + "test_data/eth-state-trie-rlp-c9070d", + "test_data/eth-state-trie-rlp-d5be90", + "test_data/eth-state-trie-rlp-d7f897", + "test_data/eth-state-trie-rlp-eb2f5f", + } + + out := make(map[string]*EthStateTrie) + + for _, fp := range filepaths { + fi, err := os.Open(fp) + checkError(err, t) + + stateTrieNode, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + out[stateTrieNode.Cid().String()] = stateTrieNode + } + + return out +} diff --git a/statediff/indexer/ipld/eth_storage.go b/statediff/indexer/ipld/eth_storage.go new file mode 100644 index 000000000..8b4d6234d --- /dev/null +++ b/statediff/indexer/ipld/eth_storage.go @@ -0,0 +1,112 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "fmt" + "io" + "io/ioutil" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" +) + +// EthStorageTrie (eth-storage-trie, codec 0x98), represents +// a node from the storage trie in ethereum. +type EthStorageTrie struct { + *TrieNode +} + +// Static (compile time) check that EthStorageTrie satisfies the node.Node interface. +var _ node.Node = (*EthStorageTrie)(nil) + +/* + INPUT +*/ + +// FromStorageTrieRLPFile takes the RLP representation of an ethereum +// storage trie node to return it as an IPLD node for further processing. +func FromStorageTrieRLPFile(r io.Reader) (*EthStorageTrie, error) { + raw, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + return FromStorageTrieRLP(raw) +} + +// FromStorageTrieRLP takes the RLP representation of an ethereum +// storage trie node to return it as an IPLD node for further processing. +func FromStorageTrieRLP(raw []byte) (*EthStorageTrie, error) { + c, err := RawdataToCid(MEthStorageTrie, raw, multihash.KECCAK_256) + if err != nil { + return nil, err + } + + // Let's run the whole mile and process the nodeKind and + // its elements, in case somebody would need this function + // to parse an RLP element from the filesystem + return DecodeEthStorageTrie(c, raw) +} + +/* + OUTPUT +*/ + +// DecodeEthStorageTrie returns an EthStorageTrie object from its cid and rawdata. +func DecodeEthStorageTrie(c cid.Cid, b []byte) (*EthStorageTrie, error) { + tn, err := decodeTrieNode(c, b, decodeEthStorageTrieLeaf) + if err != nil { + return nil, err + } + return &EthStorageTrie{TrieNode: tn}, nil +} + +// decodeEthStorageTrieLeaf parses a eth-tx-trie leaf +// from decoded RLP elements +func decodeEthStorageTrieLeaf(i []interface{}) ([]interface{}, error) { + return []interface{}{ + i[0].([]byte), + i[1].([]byte), + }, nil +} + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the storage trie node. +func (st *EthStorageTrie) RawData() []byte { + return st.rawdata +} + +// Cid returns the cid of the storage trie node. +func (st *EthStorageTrie) Cid() cid.Cid { + return st.cid +} + +// String is a helper for output +func (st *EthStorageTrie) String() string { + return fmt.Sprintf("", st.cid) +} + +// Loggable returns in a map the type of IPLD Link. +func (st *EthStorageTrie) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-storage-trie", + } +} diff --git a/statediff/indexer/ipld/eth_storage_test.go b/statediff/indexer/ipld/eth_storage_test.go new file mode 100644 index 000000000..8e385c83d --- /dev/null +++ b/statediff/indexer/ipld/eth_storage_test.go @@ -0,0 +1,132 @@ +package ipld + +import ( + "fmt" + "os" + "testing" + + "github.com/ipfs/go-cid" +) + +func TestStorageTrieNodeExtensionParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-storage-trie-rlp-113049") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + if output.nodeKind != "extension" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "extension", output.nodeKind) + } + + if len(output.elements) != 2 { + t.Fatalf("Wrong number of elements for an extension node\r\nexpected %d\r\ngot %d", 2, len(output.elements)) + } + + if fmt.Sprintf("%x", output.elements[0]) != "0a" { + t.Fatalf("Wrong key\r\nexpected %s\r\ngot %s", "0a", fmt.Sprintf("%x", output.elements[0])) + } + + if output.elements[1].(cid.Cid).String() != + "baglacgzautxeutufae7owyrezfvwpan2vusocmxgzwqhzrhjbwprp2texgsq" { + t.Fatalf("Wrong CID\r\nexpected %s\r\ngot %s", "baglacgzautxeutufae7owyrezfvwpan2vusocmxgzwqhzrhjbwprp2texgsq", output.elements[1].(cid.Cid).String()) + } +} + +func TestStateTrieNodeLeafParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-storage-trie-rlp-ffbcad") + checkError(err, t) + + output, err := FromStorageTrieRLPFile(fi) + checkError(err, t) + + if output.nodeKind != "leaf" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "leaf", output.nodeKind) + } + + if len(output.elements) != 2 { + t.Fatalf("Wrong number of elements for an leaf node\r\nexpected %d\r\ngot %d", 2, len(output.elements)) + } + + // 2ee1ae9c502e48e0ed528b7b39ac569cef69d7844b5606841a7f3fe898a2 + if fmt.Sprintf("%x", output.elements[0].([]byte)[:10]) != "020e0e010a0e090c0500" { + t.Fatalf("Wrong key\r\nexpected %s\r\ngot %s", "020e0e010a0e090c0500", fmt.Sprintf("%x", output.elements[0].([]byte)[:10])) + } + + if fmt.Sprintf("%x", output.elements[1]) != "89056c31f304b2530000" { + t.Fatalf("Wrong Value\r\nexpected %s\r\ngot %s", "89056c31f304b2530000", fmt.Sprintf("%x", output.elements[1])) + } +} + +func TestStateTrieNodeBranchParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-storage-trie-rlp-ffc25c") + checkError(err, t) + + output, err := FromStateTrieRLPFile(fi) + checkError(err, t) + + if output.nodeKind != "branch" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "branch", output.nodeKind) + } + + if len(output.elements) != 17 { + t.Fatalf("Wrong number of elements for an branch node\r\nexpected %d\r\ngot %d", 17, len(output.elements)) + } + + if fmt.Sprintf("%s", output.elements[4]) != + "baglacgzadqhbmlxrxtw5hplcq5jn74p4dceryzw664w3237ra52dnghbjpva" { + t.Fatalf("Wrong Cid\r\nexpected %s\r\ngot %s", "baglacgzadqhbmlxrxtw5hplcq5jn74p4dceryzw664w3237ra52dnghbjpva", fmt.Sprintf("%s", output.elements[4])) + } + + if fmt.Sprintf("%s", output.elements[10]) != + "baglacgza77d37i2v6uhtzeeq4vngragjbgbwq3lylpoc3lihenvzimybzxmq" { + t.Fatalf("Wrong Cid\r\nexpected %s\r\ngot %s", "baglacgza77d37i2v6uhtzeeq4vngragjbgbwq3lylpoc3lihenvzimybzxmq", fmt.Sprintf("%s", output.elements[10])) + } +} + +func TestStorageTrieBlockElements(t *testing.T) { + fi, err := os.Open("test_data/eth-storage-trie-rlp-ffbcad") + checkError(err, t) + + output, err := FromStorageTrieRLPFile(fi) + checkError(err, t) + + if fmt.Sprintf("%x", output.RawData())[:10] != "eb9f202ee1" { + t.Fatalf("Wrong Data\r\nexpected %s\r\ngot %s", "eb9f202ee1", fmt.Sprintf("%x", output.RawData())[:10]) + } + + if output.Cid().String() != + "bagmacgza766k3oprj2qxn36eycw55pogmu3dwtfay6zdh6ajrhvw3b2nqg5a" { + t.Fatalf("Wrong Cid\r\nexpected %s\r\ngot %s", "bagmacgza766k3oprj2qxn36eycw55pogmu3dwtfay6zdh6ajrhvw3b2nqg5a", output.Cid().String()) + } +} + +func TestStorageTrieString(t *testing.T) { + fi, err := os.Open("test_data/eth-storage-trie-rlp-ffbcad") + checkError(err, t) + + output, err := FromStorageTrieRLPFile(fi) + checkError(err, t) + + if output.String() != + "" { + t.Fatalf("Wrong String()\r\nexpected %s\r\ngot %s", "", output.String()) + } +} + +func TestStorageTrieLoggable(t *testing.T) { + fi, err := os.Open("test_data/eth-storage-trie-rlp-ffbcad") + checkError(err, t) + + output, err := FromStorageTrieRLPFile(fi) + checkError(err, t) + + l := output.Loggable() + if _, ok := l["type"]; !ok { + t.Fatal("Loggable map expected the field 'type'") + } + + if l["type"] != "eth-storage-trie" { + t.Fatalf("Wrong Loggable 'type' value\r\nexpected %s\r\ngot %s", "eth-storage-trie", l["type"]) + } +} diff --git a/statediff/indexer/ipld/eth_tx.go b/statediff/indexer/ipld/eth_tx.go new file mode 100644 index 000000000..19df52701 --- /dev/null +++ b/statediff/indexer/ipld/eth_tx.go @@ -0,0 +1,236 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "encoding/json" + "fmt" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + mh "github.com/multiformats/go-multihash" +) + +// EthTx (eth-tx codec 0x93) represents an ethereum transaction +type EthTx struct { + *types.Transaction + + cid cid.Cid + rawdata []byte +} + +// Static (compile time) check that EthTx satisfies the node.Node interface. +var _ node.Node = (*EthTx)(nil) + +/* + INPUT +*/ + +// NewEthTx converts a *types.Transaction to an EthTx IPLD node +func NewEthTx(tx *types.Transaction) (*EthTx, error) { + txRaw, err := tx.MarshalBinary() + if err != nil { + return nil, err + } + c, err := RawdataToCid(MEthTx, txRaw, mh.KECCAK_256) + if err != nil { + return nil, err + } + return &EthTx{ + Transaction: tx, + cid: c, + rawdata: txRaw, + }, nil +} + +/* + OUTPUT +*/ + +// DecodeEthTx takes a cid and its raw binary data +// from IPFS and returns an EthTx object for further processing. +func DecodeEthTx(c cid.Cid, b []byte) (*EthTx, error) { + t := new(types.Transaction) + if err := t.UnmarshalBinary(b); err != nil { + return nil, err + } + return &EthTx{ + Transaction: t, + cid: c, + rawdata: b, + }, nil +} + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the transaction. +func (t *EthTx) RawData() []byte { + return t.rawdata +} + +// Cid returns the cid of the transaction. +func (t *EthTx) Cid() cid.Cid { + return t.cid +} + +// String is a helper for output +func (t *EthTx) String() string { + return fmt.Sprintf("", t.cid) +} + +// Loggable returns in a map the type of IPLD Link. +func (t *EthTx) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-tx", + } +} + +/* + Node INTERFACE +*/ + +// Resolve resolves a path through this node, stopping at any link boundary +// and returning the object found as well as the remaining path to traverse +func (t *EthTx) Resolve(p []string) (interface{}, []string, error) { + if len(p) == 0 { + return t, nil, nil + } + + if len(p) > 1 { + return nil, nil, fmt.Errorf("unexpected path elements past %s", p[0]) + } + + switch p[0] { + case "type": + return t.Type(), nil, nil + case "gas": + return t.Gas(), nil, nil + case "gasPrice": + return t.GasPrice(), nil, nil + case "input": + return fmt.Sprintf("%x", t.Data()), nil, nil + case "nonce": + return t.Nonce(), nil, nil + case "r": + _, r, _ := t.RawSignatureValues() + return hexutil.EncodeBig(r), nil, nil + case "s": + _, _, s := t.RawSignatureValues() + return hexutil.EncodeBig(s), nil, nil + case "toAddress": + return t.To(), nil, nil + case "v": + v, _, _ := t.RawSignatureValues() + return hexutil.EncodeBig(v), nil, nil + case "value": + return hexutil.EncodeBig(t.Value()), nil, nil + default: + return nil, nil, ErrInvalidLink + } +} + +// Tree lists all paths within the object under 'path', and up to the given depth. +// To list the entire object (similar to `find .`) pass "" and -1 +func (t *EthTx) Tree(p string, depth int) []string { + if p != "" || depth == 0 { + return nil + } + return []string{"type", "gas", "gasPrice", "input", "nonce", "r", "s", "toAddress", "v", "value"} +} + +// ResolveLink is a helper function that calls resolve and asserts the +// output is a link +func (t *EthTx) ResolveLink(p []string) (*node.Link, []string, error) { + obj, rest, err := t.Resolve(p) + if err != nil { + return nil, nil, err + } + + if lnk, ok := obj.(*node.Link); ok { + return lnk, rest, nil + } + + return nil, nil, fmt.Errorf("resolved item was not a link") +} + +// Copy will go away. It is here to comply with the interface. +func (t *EthTx) Copy() node.Node { + panic("implement me") +} + +// Links is a helper function that returns all links within this object +func (t *EthTx) Links() []*node.Link { + return nil +} + +// Stat will go away. It is here to comply with the interface. +func (t *EthTx) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +// Size will go away. It is here to comply with the interface. It returns the byte size for the transaction +func (t *EthTx) Size() (uint64, error) { + return t.Transaction.Size(), nil + //spl := strings.Split(t.Transaction.Size().String(), " ") + //size, units := spl[0], spl[1] + //floatSize, err := strconv.ParseFloat(size, 64) + //if err != nil { + // return 0, err + //} + //var byteSize uint64 + //switch units { + //case "B": + // byteSize = uint64(floatSize) + //case "KB": + // byteSize = uint64(floatSize * 1000) + //case "MB": + // byteSize = uint64(floatSize * 1000000) + //case "GB": + // byteSize = uint64(floatSize * 1000000000) + //case "TB": + // byteSize = uint64(floatSize * 1000000000000) + //default: + // return 0, fmt.Errorf("unreconginized units %s", units) + //} + //return byteSize, nil +} + +/* + EthTx functions +*/ + +// MarshalJSON processes the transaction into readable JSON format. +func (t *EthTx) MarshalJSON() ([]byte, error) { + v, r, s := t.RawSignatureValues() + + out := map[string]interface{}{ + "gas": t.Gas(), + "gasPrice": hexutil.EncodeBig(t.GasPrice()), + "input": fmt.Sprintf("%x", t.Data()), + "nonce": t.Nonce(), + "r": hexutil.EncodeBig(r), + "s": hexutil.EncodeBig(s), + "toAddress": t.To(), + "v": hexutil.EncodeBig(v), + "value": hexutil.EncodeBig(t.Value()), + } + return json.Marshal(out) +} diff --git a/statediff/indexer/ipld/eth_tx_test.go b/statediff/indexer/ipld/eth_tx_test.go new file mode 100644 index 000000000..bc332f446 --- /dev/null +++ b/statediff/indexer/ipld/eth_tx_test.go @@ -0,0 +1,391 @@ +package ipld + +import ( + "encoding/hex" + "fmt" + "os" + "testing" + + block "github.com/ipfs/go-block-format" + "github.com/multiformats/go-multihash" +) + +/* + EthBlock + INPUT +*/ + +func TestTxInBlockBodyRlpParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-block-body-rlp-999999") + checkError(err, t) + + _, output, _, err := FromBlockRLP(fi) + checkError(err, t) + + if len(output) != 11 { + t.Fatalf("Wrong number of parsed txs\r\nexpected %d\r\ngot %d", 11, len(output)) + } + + // Oh, let's just grab the last element and one from the middle + testTx05Fields(output[5], t) + testTx10Fields(output[10], t) +} + +func TestTxInBlockHeaderRlpParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-block-header-rlp-999999") + checkError(err, t) + + _, output, _, err := FromBlockRLP(fi) + checkError(err, t) + + if len(output) != 0 { + t.Fatalf("Wrong number of txs\r\nexpected %d\r\ngot %d", 0, len(output)) + } +} + +func TestTxInBlockBodyJsonParsing(t *testing.T) { + fi, err := os.Open("test_data/eth-block-body-json-999999") + checkError(err, t) + + _, output, _, err := FromBlockJSON(fi) + checkError(err, t) + + if len(output) != 11 { + t.Fatalf("Wrong number of parsed txs\r\nexpected %d\r\ngot %d", 11, len(output)) + } + + testTx05Fields(output[5], t) + testTx10Fields(output[10], t) +} + +/* + OUTPUT +*/ + +func TestDecodeTransaction(t *testing.T) { + // Prepare the "fetched transaction". + // This one is supposed to be in the datastore already, + // and given away by github.com/ipfs/go-ipfs/merkledag + rawTransactionString := + "f86c34850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880f25" + + "8512af0d4000801ba0e9a25c929c26d1a95232ba75aef419a91b470651eb77614695e16c" + + "5ba023e383a0679fb2fc0d0b0f3549967c0894ee7d947f07d238a83ef745bc3ced5143a4af36" + rawTransaction, err := hex.DecodeString(rawTransactionString) + checkError(err, t) + c, err := RawdataToCid(MEthTx, rawTransaction, multihash.KECCAK_256) + checkError(err, t) + + // Just to clarify: This `block` is an IPFS block + storedTransaction, err := block.NewBlockWithCid(rawTransaction, c) + checkError(err, t) + + // Now the proper test + ethTransaction, err := DecodeEthTx(storedTransaction.Cid(), storedTransaction.RawData()) + checkError(err, t) + + testTx05Fields(ethTransaction, t) +} + +/* + Block INTERFACE +*/ + +func TestEthTxLoggable(t *testing.T) { + txs := prepareParsedTxs(t) + + l := txs[0].Loggable() + if _, ok := l["type"]; !ok { + t.Fatal("Loggable map expected the field 'type'") + } + + if l["type"] != "eth-tx" { + t.Fatalf("Wrong Loggable 'type' value\r\nexpected %s\r\ngot %s", "eth-tx", l["type"]) + } +} + +/* + Node INTERFACE +*/ + +func TestEthTxResolve(t *testing.T) { + tx := prepareParsedTxs(t)[0] + + // Empty path + obj, rest, err := tx.Resolve([]string{}) + rtx, ok := obj.(*EthTx) + if !ok { + t.Fatal("Wrong type of returned object") + } + if rtx.Cid() != tx.Cid() { + t.Fatalf("Wrong CID\r\nexpected %s\r\ngot %s", tx.Cid().String(), rtx.Cid().String()) + } + if rest != nil { + t.Fatal("est should be nil") + } + if err != nil { + t.Fatal("err should be nil") + } + + // len(p) > 1 + badCases := [][]string{ + {"two", "elements"}, + {"here", "three", "elements"}, + {"and", "here", "four", "elements"}, + } + + for _, bc := range badCases { + obj, rest, err = tx.Resolve(bc) + if obj != nil { + t.Fatal("obj should be nil") + } + if rest != nil { + t.Fatal("rest should be nil") + } + if err.Error() != fmt.Sprintf("unexpected path elements past %s", bc[0]) { + t.Fatalf("wrong error\r\nexpected %s\r\ngot %s", fmt.Sprintf("unexpected path elements past %s", bc[0]), err.Error()) + } + } + + moreBadCases := []string{ + "i", + "am", + "not", + "a", + "tx", + "field", + } + for _, mbc := range moreBadCases { + obj, rest, err = tx.Resolve([]string{mbc}) + if obj != nil { + t.Fatal("obj should be nil") + } + if rest != nil { + t.Fatal("rest should be nil") + } + + if err != ErrInvalidLink { + t.Fatalf("wrong error\r\nexpected %s\r\ngot %s", ErrInvalidLink, err) + } + } + + goodCases := []string{ + "gas", + "gasPrice", + "input", + "nonce", + "r", + "s", + "toAddress", + "v", + "value", + } + for _, gc := range goodCases { + _, _, err = tx.Resolve([]string{gc}) + if err != nil { + t.Fatalf("error should be nil %v", gc) + } + } +} + +func TestEthTxTree(t *testing.T) { + tx := prepareParsedTxs(t)[0] + _ = tx + + // Bad cases + tree := tx.Tree("non-empty-string", 0) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + tree = tx.Tree("non-empty-string", 1) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + tree = tx.Tree("", 0) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + // Good cases + tree = tx.Tree("", 1) + lookupElements := map[string]interface{}{ + "type": nil, + "gas": nil, + "gasPrice": nil, + "input": nil, + "nonce": nil, + "r": nil, + "s": nil, + "toAddress": nil, + "v": nil, + "value": nil, + } + + if len(tree) != len(lookupElements) { + t.Fatalf("Wrong number of elements\r\nexpected %d\r\ngot %d", len(lookupElements), len(tree)) + } + + for _, te := range tree { + if _, ok := lookupElements[te]; !ok { + t.Fatalf("Unexpected Element: %v", te) + } + } +} + +func TestEthTxResolveLink(t *testing.T) { + tx := prepareParsedTxs(t)[0] + + // bad case + obj, rest, err := tx.ResolveLink([]string{"supercalifragilist"}) + if obj != nil { + t.Fatalf("Expected obj to be nil") + } + if rest != nil { + t.Fatal("Expected rest to be nil") + } + if err != ErrInvalidLink { + t.Fatalf("Wrong error\r\nexpected %s\r\ngot %s", ErrInvalidLink, err.Error()) + } + + // good case + obj, rest, err = tx.ResolveLink([]string{"nonce"}) + if obj != nil { + t.Fatalf("Expected obj to be nil") + } + if rest != nil { + t.Fatal("Expected rest to be nil") + } + if err.Error() != "resolved item was not a link" { + t.Fatalf("Wrong error\r\nexpected %s\r\ngot %s", "resolved item was not a link", err.Error()) + } +} + +func TestEthTxCopy(t *testing.T) { + tx := prepareParsedTxs(t)[0] + + defer func() { + r := recover() + if r == nil { + t.Fatal("Expected panic") + } + if r != "implement me" { + t.Fatalf("Wrong panic message\r\nexpected %s\r\ngot %s", "'implement me'", r) + } + }() + + _ = tx.Copy() +} + +func TestEthTxLinks(t *testing.T) { + tx := prepareParsedTxs(t)[0] + + if tx.Links() != nil { + t.Fatal("Links() expected to return nil") + } +} + +func TestEthTxStat(t *testing.T) { + tx := prepareParsedTxs(t)[0] + + obj, err := tx.Stat() + if obj == nil { + t.Fatal("Expected a not null object node.NodeStat") + } + + if err != nil { + t.Fatal("Expected a nil error") + } +} + +func TestEthTxSize(t *testing.T) { + tx := prepareParsedTxs(t)[0] + + size, err := tx.Size() + checkError(err, t) + + expectedSize := tx.Transaction.Size() + + if size != expectedSize { + t.Fatalf("Wrong size\r\nexpected %d\r\ngot %d", expectedSize, size) + } +} + +/* + AUXILIARS +*/ + +// prepareParsedTxs is a convenienve method +func prepareParsedTxs(t *testing.T) []*EthTx { + fi, err := os.Open("test_data/eth-block-body-rlp-999999") + checkError(err, t) + + _, output, _, err := FromBlockRLP(fi) + checkError(err, t) + + return output +} + +func testTx05Fields(ethTx *EthTx, t *testing.T) { + // Was the cid calculated? + if ethTx.Cid().String() != "bagjqcgzawhfnvdnpmpcfoug7d3tz53k2ht3cidr45pnw3y7snpd46azbpp2a" { + t.Fatalf("Wrong cid\r\nexpected %s\r\ngot %s\r\n", "bagjqcgzawhfnvdnpmpcfoug7d3tz53k2ht3cidr45pnw3y7snpd46azbpp2a", ethTx.Cid().String()) + } + + // Do we have the rawdata available? + if fmt.Sprintf("%x", ethTx.RawData()[:10]) != "f86c34850df847580082" { + t.Fatalf("Wrong Rawdata\r\nexpected %s\r\ngot %s", "f86c34850df847580082", fmt.Sprintf("%x", ethTx.RawData()[:10])) + } + + // Proper Fields of types.Transaction + if fmt.Sprintf("%x", ethTx.To()) != "32be343b94f860124dc4fee278fdcbd38c102d88" { + t.Fatalf("Wrong Recipient\r\nexpected %s\r\ngot %s", "32be343b94f860124dc4fee278fdcbd38c102d88", fmt.Sprintf("%x", ethTx.To())) + } + if len(ethTx.Data()) != 0 { + t.Fatalf("Wrong len of Data\r\nexpected %d\r\ngot %d", 0, len(ethTx.Data())) + } + if fmt.Sprintf("%v", ethTx.Gas()) != "21000" { + t.Fatalf("Wrong Gas\r\nexpected %s\r\ngot %s", "21000", fmt.Sprintf("%v", ethTx.Gas())) + } + if fmt.Sprintf("%v", ethTx.Value()) != "1091424800000000000" { + t.Fatalf("Wrong Value\r\nexpected %s\r\ngot %s", "1091424800000000000", fmt.Sprintf("%v", ethTx.Value())) + } + if fmt.Sprintf("%v", ethTx.Nonce()) != "52" { + t.Fatalf("Wrong Nonce\r\nexpected %s\r\ngot %s", "52", fmt.Sprintf("%v", ethTx.Nonce())) + } + if fmt.Sprintf("%v", ethTx.GasPrice()) != "60000000000" { + t.Fatalf("Wrong Gas Price\r\nexpected %s\r\ngot %s", "60000000000", fmt.Sprintf("%v", ethTx.GasPrice())) + } +} + +func testTx10Fields(ethTx *EthTx, t *testing.T) { + // Was the cid calculated? + if ethTx.Cid().String() != "bagjqcgzaykakwayoec6j55zmq62cbvmplgf5u5j67affge3ksi4ermgitjoa" { + t.Fatalf("Wrong Cid\r\nexpected %s\r\ngot %s", "bagjqcgzaykakwayoec6j55zmq62cbvmplgf5u5j67affge3ksi4ermgitjoa", ethTx.Cid().String()) + } + + // Do we have the rawdata available? + if fmt.Sprintf("%x", ethTx.RawData()[:10]) != "f8708302a120850ba43b" { + t.Fatalf("Wrong Rawdata\r\nexpected %s\r\ngot %s", "f8708302a120850ba43b", fmt.Sprintf("%x", ethTx.RawData()[:10])) + } + + // Proper Fields of types.Transaction + if fmt.Sprintf("%x", ethTx.To()) != "1c51bf013add0857c5d9cf2f71a7f15ca93d4816" { + t.Fatalf("Wrong Recipient\r\nexpected %s\r\ngot %s", "1c51bf013add0857c5d9cf2f71a7f15ca93d4816", fmt.Sprintf("%x", ethTx.To())) + } + if len(ethTx.Data()) != 0 { + t.Fatalf("Wrong len of Data\r\nexpected %d\r\ngot %d", 0, len(ethTx.Data())) + } + if fmt.Sprintf("%v", ethTx.Gas()) != "90000" { + t.Fatalf("Wrong Gas\r\nexpected %s\r\ngot %s", "90000", fmt.Sprintf("%v", ethTx.Gas())) + } + if fmt.Sprintf("%v", ethTx.Value()) != "1049756850000000000" { + t.Fatalf("Wrong Value\r\nexpected %s\r\ngot %s", "1049756850000000000", fmt.Sprintf("%v", ethTx.Value())) + } + if fmt.Sprintf("%v", ethTx.Nonce()) != "172320" { + t.Fatalf("Wrong Nonce\r\nexpected %s\r\ngot %s", "172320", fmt.Sprintf("%v", ethTx.Nonce())) + } + if fmt.Sprintf("%v", ethTx.GasPrice()) != "50000000000" { + t.Fatalf("Wrong Gas Price\r\nexpected %s\r\ngot %s", "50000000000", fmt.Sprintf("%v", ethTx.GasPrice())) + } +} diff --git a/statediff/indexer/ipld/eth_tx_trie.go b/statediff/indexer/ipld/eth_tx_trie.go new file mode 100644 index 000000000..c215a36a9 --- /dev/null +++ b/statediff/indexer/ipld/eth_tx_trie.go @@ -0,0 +1,146 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "fmt" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" + + "github.com/ethereum/go-ethereum/core/types" +) + +// EthTxTrie (eth-tx-trie codec 0x92) represents +// a node from the transaction trie in ethereum. +type EthTxTrie struct { + *TrieNode +} + +// Static (compile time) check that EthTxTrie satisfies the node.Node interface. +var _ node.Node = (*EthTxTrie)(nil) + +/* + INPUT +*/ + +// To create a proper trie of the eth-tx-trie objects, it is required +// to input all transactions belonging to a forest in a single step. +// We are adding the transactions, and creating its trie on +// block body parsing time. + +/* + OUTPUT +*/ + +// DecodeEthTxTrie returns an EthTxTrie object from its cid and rawdata. +func DecodeEthTxTrie(c cid.Cid, b []byte) (*EthTxTrie, error) { + tn, err := decodeTrieNode(c, b, decodeEthTxTrieLeaf) + if err != nil { + return nil, err + } + return &EthTxTrie{TrieNode: tn}, nil +} + +// decodeEthTxTrieLeaf parses a eth-tx-trie leaf +// from decoded RLP elements +func decodeEthTxTrieLeaf(i []interface{}) ([]interface{}, error) { + t := new(types.Transaction) + if err := t.UnmarshalBinary(i[1].([]byte)); err != nil { + return nil, err + } + c, err := RawdataToCid(MEthTx, i[1].([]byte), multihash.KECCAK_256) + if err != nil { + return nil, err + } + return []interface{}{ + i[0].([]byte), + &EthTx{ + Transaction: t, + cid: c, + rawdata: i[1].([]byte), + }, + }, nil +} + +/* + Block INTERFACE +*/ + +// RawData returns the binary of the RLP encode of the transaction. +func (t *EthTxTrie) RawData() []byte { + return t.rawdata +} + +// Cid returns the cid of the transaction. +func (t *EthTxTrie) Cid() cid.Cid { + return t.cid +} + +// String is a helper for output +func (t *EthTxTrie) String() string { + return fmt.Sprintf("", t.cid) +} + +// Loggable returns in a map the type of IPLD Link. +func (t *EthTxTrie) Loggable() map[string]interface{} { + return map[string]interface{}{ + "type": "eth-tx-trie", + } +} + +/* + EthTxTrie functions +*/ + +// txTrie wraps a localTrie for use on the transaction trie. +type txTrie struct { + *localTrie +} + +// newTxTrie initializes and returns a txTrie. +func newTxTrie() *txTrie { + return &txTrie{ + localTrie: newLocalTrie(), + } +} + +// getNodes invokes the localTrie, which computes the root hash of the +// transaction trie and returns its sql keys, to return a slice +// of EthTxTrie nodes. +func (tt *txTrie) getNodes() ([]*EthTxTrie, error) { + keys, err := tt.getKeys() + if err != nil { + return nil, err + } + var out []*EthTxTrie + + for _, k := range keys { + rawdata, err := tt.db.Get(k) + if err != nil { + return nil, err + } + tn := &TrieNode{ + cid: keccak256ToCid(MEthTxTrie, k), + rawdata: rawdata, + } + out = append(out, &EthTxTrie{TrieNode: tn}) + } + + return out, nil +} diff --git a/statediff/indexer/ipld/eth_tx_trie_test.go b/statediff/indexer/ipld/eth_tx_trie_test.go new file mode 100644 index 000000000..b067d0ea4 --- /dev/null +++ b/statediff/indexer/ipld/eth_tx_trie_test.go @@ -0,0 +1,503 @@ +package ipld + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "os" + "testing" + + block "github.com/ipfs/go-block-format" + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + "github.com/multiformats/go-multihash" +) + +/* + EthBlock +*/ + +func TestTxTriesInBlockBodyJSONParsing(t *testing.T) { + // HINT: 306 txs + // cat test_data/eth-block-body-json-4139497 | jsontool | grep transactionIndex | wc -l + // or, https://etherscan.io/block/4139497 + fi, err := os.Open("test_data/eth-block-body-json-4139497") + checkError(err, t) + + _, _, output, err := FromBlockJSON(fi) + checkError(err, t) + if len(output) != 331 { + t.Fatalf("Wrong number of obtained tx trie nodes\r\nexpected %d\r\n got %d", 331, len(output)) + } +} + +/* + OUTPUT +*/ + +func TestTxTrieDecodeExtension(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieExtension(t) + + if ethTxTrie.nodeKind != "extension" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "extension", ethTxTrie.nodeKind) + } + + if len(ethTxTrie.elements) != 2 { + t.Fatalf("Wrong number of elements for an extension node\r\nexpected %d\r\ngot %d", 2, len(ethTxTrie.elements)) + } + + if fmt.Sprintf("%x", ethTxTrie.elements[0].([]byte)) != "0001" { + t.Fatalf("Wrong key\r\nexpected %s\r\ngot %s", "0001", fmt.Sprintf("%x", ethTxTrie.elements[0].([]byte))) + } + + if ethTxTrie.elements[1].(cid.Cid).String() != + "bagjacgzak6wdjvshdtb7lrvlteweyd7f5qjr3dmzmh7g2xpi4xrwoujsio2a" { + t.Fatalf("Wrong CID\r\nexpected %s\r\ngot %s", "bagjacgzak6wdjvshdtb7lrvlteweyd7f5qjr3dmzmh7g2xpi4xrwoujsio2a", ethTxTrie.elements[1].(cid.Cid).String()) + } +} + +func TestTxTrieDecodeLeaf(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieLeaf(t) + + if ethTxTrie.nodeKind != "leaf" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "leaf", ethTxTrie.nodeKind) + } + + if len(ethTxTrie.elements) != 2 { + t.Fatalf("Wrong number of elements for a leaf node\r\nexpected %d\r\ngot %d", 2, len(ethTxTrie.elements)) + } + + if fmt.Sprintf("%x", ethTxTrie.elements[0].([]byte)) != "" { + t.Fatalf("Wrong key\r\nexpected %s\r\ngot %s", "", fmt.Sprintf("%x", ethTxTrie.elements[0].([]byte))) + } + + if _, ok := ethTxTrie.elements[1].(*EthTx); !ok { + t.Fatal("Expected element to be an EthTx") + } + + if ethTxTrie.elements[1].(*EthTx).String() != + "" { + t.Fatalf("Wrong String()\r\nexpected %s\r\ngot %s", "", ethTxTrie.elements[1].(*EthTx).String()) + } +} + +func TestTxTrieDecodeBranch(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieBranch(t) + + if ethTxTrie.nodeKind != "branch" { + t.Fatalf("Wrong nodeKind\r\nexpected %s\r\ngot %s", "branch", ethTxTrie.nodeKind) + } + + if len(ethTxTrie.elements) != 17 { + t.Fatalf("Wrong number of elements for a branch node\r\nexpected %d\r\ngot %d", 17, len(ethTxTrie.elements)) + } + + for i, element := range ethTxTrie.elements { + switch { + case i < 9: + if _, ok := element.(cid.Cid); !ok { + t.Fatal("Expected element to be a cid") + } + continue + default: + if element != nil { + t.Fatal("Expected element to be a nil") + } + } + } +} + +/* + Block INTERFACE +*/ + +func TestEthTxTrieBlockElements(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieExtension(t) + + if fmt.Sprintf("%x", ethTxTrie.RawData())[:10] != "e4820001a0" { + t.Fatalf("Wrong Data\r\nexpected %s\r\ngot %s", "e4820001a0", fmt.Sprintf("%x", ethTxTrie.RawData())[:10]) + } + + if ethTxTrie.Cid().String() != + "bagjacgzaw6ccgrfc3qnrl6joodbjjiet4haufnt2xww725luwgfhijnmg36q" { + t.Fatalf("Wrong Cid\r\nexpected %s\r\ngot %s", "bagjacgzaw6ccgrfc3qnrl6joodbjjiet4haufnt2xww725luwgfhijnmg36q", ethTxTrie.Cid().String()) + } +} + +func TestEthTxTrieString(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieExtension(t) + + if ethTxTrie.String() != "" { + t.Fatalf("Wrong String()\r\nexpected %s\r\ngot %s", "", ethTxTrie.String()) + } +} + +func TestEthTxTrieLoggable(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieExtension(t) + l := ethTxTrie.Loggable() + if _, ok := l["type"]; !ok { + t.Fatal("Loggable map expected the field 'type'") + } + + if l["type"] != "eth-tx-trie" { + t.Fatalf("Wrong Loggable 'type' value\r\nexpected %s\r\ngot %s", "eth-tx-trie", l["type"]) + } +} + +/* + Node INTERFACE +*/ + +func TestTxTrieResolveExtension(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieExtension(t) + + _ = ethTxTrie +} + +func TestTxTrieResolveLeaf(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieLeaf(t) + + _ = ethTxTrie +} + +func TestTxTrieResolveBranch(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieBranch(t) + + indexes := []string{"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"} + + for j, index := range indexes { + obj, rest, err := ethTxTrie.Resolve([]string{index, "nonce"}) + + switch { + case j < 9: + _, ok := obj.(*node.Link) + if !ok { + t.Fatalf("Returned object is not a link (index: %d)", j) + } + + if rest[0] != "nonce" { + t.Fatalf("Wrong rest of the path returned\r\nexpected %s\r\ngot %s", "nonce", rest[0]) + } + + if err != nil { + t.Fatal("Error should be nil") + } + + default: + if obj != nil { + t.Fatalf("Returned object should have been nil") + } + + if rest != nil { + t.Fatalf("Rest of the path returned should be nil") + } + + if err.Error() != "no such link in this branch" { + t.Fatalf("Wrong error") + } + } + } + + otherSuccessCases := [][]string{ + {"0", "1", "banana"}, + {"1", "banana"}, + {"7bc", "def"}, + {"bc", "def"}, + } + + for i := 0; i < len(otherSuccessCases); i = i + 2 { + osc := otherSuccessCases[i] + expectedRest := otherSuccessCases[i+1] + + obj, rest, err := ethTxTrie.Resolve(osc) + _, ok := obj.(*node.Link) + if !ok { + t.Fatalf("Returned object is not a link") + } + + for j := range expectedRest { + if rest[j] != expectedRest[j] { + t.Fatalf("Wrong rest of the path returned\r\nexpected %s\r\ngot %s", expectedRest[j], rest[j]) + } + } + + if err != nil { + t.Fatal("Error should be nil") + } + } +} + +func TestTraverseTxTrieWithResolve(t *testing.T) { + var err error + + txMap := prepareTxTrieMap(t) + + // This is the cid of the tx root at the block 4,139,497 + currentNode := txMap["bagjacgzaqolvvlyflkdiylijcu4ts6myxczkb2y3ewxmln5oyrsrkfc4v7ua"] + + // This is the path we want to traverse + // the transaction id 256, which is RLP encoded to 820100 + var traversePath []string + for _, s := range "820100" { + traversePath = append(traversePath, string(s)) + } + traversePath = append(traversePath, "value") + + var obj interface{} + for { + obj, traversePath, err = currentNode.Resolve(traversePath) + link, ok := obj.(*node.Link) + if !ok { + break + } + if err != nil { + t.Fatal("Error should be nil") + } + + currentNode = txMap[link.Cid.String()] + if currentNode == nil { + t.Fatal("transaction trie node not found in memory map") + } + } + + if fmt.Sprintf("%v", obj) != "0xc495a958603400" { + t.Fatalf("Wrong value\r\nexpected %s\r\ngot %s", "0xc495a958603400", fmt.Sprintf("%v", obj)) + } +} + +func TestTxTrieTreeBadParams(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieBranch(t) + + tree := ethTxTrie.Tree("non-empty-string", 0) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + tree = ethTxTrie.Tree("non-empty-string", 1) + if tree != nil { + t.Fatal("Expected nil to be returned") + } + + tree = ethTxTrie.Tree("", 0) + if tree != nil { + t.Fatal("Expected nil to be returned") + } +} + +func TestTxTrieTreeExtension(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieExtension(t) + + tree := ethTxTrie.Tree("", -1) + + if len(tree) != 1 { + t.Fatalf("An extension should have one element") + } + + if tree[0] != "01" { + t.Fatalf("Wrong trie element\r\nexpected %s\r\ngot %s", "01", tree[0]) + } +} + +func TestTxTrieTreeBranch(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieBranch(t) + + tree := ethTxTrie.Tree("", -1) + + lookupElements := map[string]interface{}{ + "0": nil, + "1": nil, + "2": nil, + "3": nil, + "4": nil, + "5": nil, + "6": nil, + "7": nil, + "8": nil, + } + + if len(tree) != len(lookupElements) { + t.Fatalf("Wrong number of elements\r\nexpected %d\r\ngot %d", len(lookupElements), len(tree)) + } + + for _, te := range tree { + if _, ok := lookupElements[te]; !ok { + t.Fatalf("Unexpected Element: %v", te) + } + } +} + +func TestTxTrieLinksBranch(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieBranch(t) + + desiredValues := []string{ + "bagjacgzakhtcfpja453ydiaqxgidqmxhh7jwmxujib663deebwfs3m2n3hoa", + "bagjacgza2p2fuqh4vumknq6x5w7i47usvtu5ixqins6qjjtcks4zge3vx3qq", + "bagjacgza4fkhn7et3ra66yjkzbtvbxjefuketda6jctlut6it7gfahxhywga", + "bagjacgzacnryeybs52xryrka5uxi4eg4hi2mh66esaghu7cetzu6fsukrynq", + "bagjacgzastu5tc7lwz4ap3gznjwkyyepswquub7gvhags5mgdyfynnwbi43a", + "bagjacgza5qgp76ovvorkydni2lchew6ieu5wb55w6hdliiu6vft7zlxtdhjq", + "bagjacgzafnssc4yvln6zxmks5roskw4ckngta5n4yfy2skhlu435ve4b575a", + "bagjacgzagkuei7qxfxefufme2d3xizxokkq4ad3rzl2x4dq2uao6dcr4va2a", + "bagjacgzaxpaehtananrdxjghwukh2wwkkzcqwveppf6xclkrtd26rm27kqwq", + } + + links := ethTxTrie.Links() + + for i, v := range desiredValues { + if links[i].Cid.String() != v { + t.Fatalf("Wrong cid for link %d\r\nexpected %s\r\ngot %s", i, v, links[i].Cid.String()) + } + } +} + +/* + EthTxTrie Functions +*/ + +func TestTxTrieJSONMarshalExtension(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieExtension(t) + + jsonOutput, err := ethTxTrie.MarshalJSON() + checkError(err, t) + + var data map[string]interface{} + err = json.Unmarshal(jsonOutput, &data) + checkError(err, t) + + if parseMapElement(data["01"]) != + "bagjacgzak6wdjvshdtb7lrvlteweyd7f5qjr3dmzmh7g2xpi4xrwoujsio2a" { + t.Fatalf("Wrong Marshaled Value\r\nexpected %s\r\ngot %s", "bagjacgzak6wdjvshdtb7lrvlteweyd7f5qjr3dmzmh7g2xpi4xrwoujsio2a", parseMapElement(data["01"])) + } + + if data["type"] != "extension" { + t.Fatalf("Wrong node type\r\nexpected %s\r\ngot %s", "extension", data["type"]) + } +} + +func TestTxTrieJSONMarshalLeaf(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieLeaf(t) + + jsonOutput, err := ethTxTrie.MarshalJSON() + checkError(err, t) + + var data map[string]interface{} + err = json.Unmarshal(jsonOutput, &data) + checkError(err, t) + + if data["type"] != "leaf" { + t.Fatalf("Wrong node type\r\nexpected %s\r\ngot %s", "leaf", data["type"]) + } + + if fmt.Sprintf("%v", data[""].(map[string]interface{})["nonce"]) != + "40243" { + t.Fatalf("Wrong nonce value\r\nexepcted %s\r\ngot %s", "40243", fmt.Sprintf("%v", data[""].(map[string]interface{})["nonce"])) + } +} + +func TestTxTrieJSONMarshalBranch(t *testing.T) { + ethTxTrie := prepareDecodedEthTxTrieBranch(t) + + jsonOutput, err := ethTxTrie.MarshalJSON() + checkError(err, t) + + var data map[string]interface{} + err = json.Unmarshal(jsonOutput, &data) + checkError(err, t) + + desiredValues := map[string]string{ + "0": "bagjacgzakhtcfpja453ydiaqxgidqmxhh7jwmxujib663deebwfs3m2n3hoa", + "1": "bagjacgza2p2fuqh4vumknq6x5w7i47usvtu5ixqins6qjjtcks4zge3vx3qq", + "2": "bagjacgza4fkhn7et3ra66yjkzbtvbxjefuketda6jctlut6it7gfahxhywga", + "3": "bagjacgzacnryeybs52xryrka5uxi4eg4hi2mh66esaghu7cetzu6fsukrynq", + "4": "bagjacgzastu5tc7lwz4ap3gznjwkyyepswquub7gvhags5mgdyfynnwbi43a", + "5": "bagjacgza5qgp76ovvorkydni2lchew6ieu5wb55w6hdliiu6vft7zlxtdhjq", + "6": "bagjacgzafnssc4yvln6zxmks5roskw4ckngta5n4yfy2skhlu435ve4b575a", + "7": "bagjacgzagkuei7qxfxefufme2d3xizxokkq4ad3rzl2x4dq2uao6dcr4va2a", + "8": "bagjacgzaxpaehtananrdxjghwukh2wwkkzcqwveppf6xclkrtd26rm27kqwq", + } + + for k, v := range desiredValues { + if parseMapElement(data[k]) != v { + t.Fatalf("Wrong Marshaled Value %s\r\nexpected %s\r\ngot %s", k, v, parseMapElement(data[k])) + } + } + + for _, v := range []string{"a", "b", "c", "d", "e", "f"} { + if data[v] != nil { + t.Fatal("Expected value to be nil") + } + } + + if data["type"] != "branch" { + t.Fatalf("Wrong node type\r\nexpected %s\r\ngot %s", "branch", data["type"]) + } +} + +/* + AUXILIARS +*/ + +// prepareDecodedEthTxTrie simulates an IPLD block available in the datastore, +// checks the source RLP and tests for the absence of errors during the decoding fase. +func prepareDecodedEthTxTrie(branchDataRLP string, t *testing.T) *EthTxTrie { + b, err := hex.DecodeString(branchDataRLP) + checkError(err, t) + + c, err := RawdataToCid(MEthTxTrie, b, multihash.KECCAK_256) + checkError(err, t) + + storedEthTxTrie, err := block.NewBlockWithCid(b, c) + checkError(err, t) + + ethTxTrie, err := DecodeEthTxTrie(storedEthTxTrie.Cid(), storedEthTxTrie.RawData()) + checkError(err, t) + + return ethTxTrie +} + +func prepareDecodedEthTxTrieExtension(t *testing.T) *EthTxTrie { + extensionDataRLP := + "e4820001a057ac34d6471cc3f5c6ab992c4c0fe5ec131d8d9961fe6d5de8e5e367513243b4" + return prepareDecodedEthTxTrie(extensionDataRLP, t) +} + +func prepareDecodedEthTxTrieLeaf(t *testing.T) *EthTxTrie { + leafDataRLP := + "f87220b86ff86d829d3384ee6b280083015f9094e0e6c781b8cba08bc840" + + "7eac0101b668d1fa6f4987c495a9586034008026a0981b6223c9d3c31971" + + "6da3cf057da84acf0fef897f4003d8a362d7bda42247dba066be134c4bc4" + + "32125209b5056ef274b7423bcac7cc398cf60b83aaff7b95469f" + return prepareDecodedEthTxTrie(leafDataRLP, t) +} + +func prepareDecodedEthTxTrieBranch(t *testing.T) *EthTxTrie { + branchDataRLP := + "f90131a051e622bd20e77781a010b9903832e73fd3665e89407ded8c840d8b2db34dd9" + + "dca0d3f45a40fcad18a6c3d7edbe8e7e92ace9d45e086cbd04a66254b9931375bee1a0" + + "e15476fc93dc41ef612ac86750dd242d14498c1e48a6ba4fc89fcc501ee7c58ca01363" + + "826032eeaf1c4540ed2e8e10dc3a34c3fbc4900c7a7c449e69e2ca8a8e1ba094e9d98b" + + "ebb67807ecd96a6cac608f95a14a07e6a9c06975861e0b86b6c14736a0ec0cfff9d5ab" + + "a2ac0da8d2c4725bc8253b60f7b6f1c6b4229ea967fcaef319d3a02b652173155b7d9b" + + "b152ec5d255b82534d3075bcc171a928eba737da9381effaa032a8447e172dc85a1584" + + "d0f77466ee52a1c00f71caf57e0e1aa01de18a3ca834a0bbc043cc0d03623ba4c7b514" + + "7d5aca56450b548f797d712d5198f5e8b35f542d8080808080808080" + return prepareDecodedEthTxTrie(branchDataRLP, t) +} + +func prepareTxTrieMap(t *testing.T) map[string]*EthTxTrie { + fi, err := os.Open("test_data/eth-block-body-json-4139497") + checkError(err, t) + + _, _, txTrieNodes, err := FromBlockJSON(fi) + checkError(err, t) + + out := make(map[string]*EthTxTrie) + + for _, txTrieNode := range txTrieNodes { + decodedNode, err := DecodeEthTxTrie(txTrieNode.Cid(), txTrieNode.RawData()) + checkError(err, t) + out[txTrieNode.Cid().String()] = decodedNode + } + + return out +} diff --git a/statediff/indexer/ipld/shared.go b/statediff/indexer/ipld/shared.go new file mode 100644 index 000000000..89c0a285f --- /dev/null +++ b/statediff/indexer/ipld/shared.go @@ -0,0 +1,212 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "bytes" + "errors" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/rlp" + sdtrie "github.com/ethereum/go-ethereum/statediff/trie_helpers" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" + "github.com/ethereum/go-ethereum/trie" + "github.com/ipfs/go-cid" + mh "github.com/multiformats/go-multihash" +) + +// IPLD Codecs for Ethereum +// See the authoritative document: +// https://github.com/multiformats/multicodec/blob/master/table.csv +const ( + RawBinary = 0x55 + MEthHeader = 0x90 + MEthHeaderList = 0x91 + MEthTxTrie = 0x92 + MEthTx = 0x93 + MEthTxReceiptTrie = 0x94 + MEthTxReceipt = 0x95 + MEthStateTrie = 0x96 + MEthAccountSnapshot = 0x97 + MEthStorageTrie = 0x98 + MEthLogTrie = 0x99 + MEthLog = 0x9a +) + +var ( + nullHashBytes = common.Hex2Bytes("0000000000000000000000000000000000000000000000000000000000000000") + ErrInvalidLink = errors.New("no such link") +) + +// RawdataToCid takes the desired codec and a slice of bytes +// and returns the proper cid of the object. +func RawdataToCid(codec uint64, rawdata []byte, multiHash uint64) (cid.Cid, error) { + c, err := cid.Prefix{ + Codec: codec, + Version: 1, + MhType: multiHash, + MhLength: -1, + }.Sum(rawdata) + if err != nil { + return cid.Cid{}, err + } + return c, nil +} + +// keccak256ToCid takes a keccak256 hash and returns its cid based on +// the codec given. +func keccak256ToCid(codec uint64, h []byte) cid.Cid { + buf, err := mh.Encode(h, mh.KECCAK_256) + if err != nil { + panic(err) + } + + return cid.NewCidV1(codec, mh.Multihash(buf)) +} + +// commonHashToCid takes a go-ethereum common.Hash and returns its +// cid based on the codec given, +func commonHashToCid(codec uint64, h common.Hash) cid.Cid { + mhash, err := mh.Encode(h[:], mh.KECCAK_256) + if err != nil { + panic(err) + } + + return cid.NewCidV1(codec, mhash) +} + +// localTrie wraps a go-ethereum trie and its underlying memory db. +// It contributes to the creation of the trie node objects. +type localTrie struct { + db ethdb.Database + trieDB *trie.Database + trie *trie.Trie +} + +// newLocalTrie initializes and returns a localTrie object +func newLocalTrie() *localTrie { + var err error + lt := &localTrie{} + lt.db = rawdb.NewMemoryDatabase() + lt.trieDB = trie.NewDatabase(lt.db) + lt.trie, err = trie.New(trie.StateTrieID(common.Hash{}), lt.trieDB) + if err != nil { + panic(err) + } + return lt +} + +// Add receives the index of an object and its rawdata value +// and includes it into the localTrie +func (lt *localTrie) Add(idx int, rawdata []byte) error { + key, err := rlp.EncodeToBytes(uint(idx)) + if err != nil { + panic(err) + } + return lt.trie.TryUpdate(key, rawdata) +} + +// rootHash returns the computed trie root. +// Useful for sanity checks on parsed data. +func (lt *localTrie) rootHash() []byte { + return lt.trie.Hash().Bytes() +} + +func (lt *localTrie) commit() error { + // commit trie nodes to trieDB + ltHash, trieNodes := lt.trie.Commit(true) + + //new trie.Commit method signature also requires Update with returned NodeSet + if trieNodes != nil { + lt.trieDB.Update(trie.NewWithNodeSet(trieNodes)) + } + + // commit trieDB to the underlying ethdb.Database + if err := lt.trieDB.Commit(ltHash, false); err != nil { + return err + } + return nil +} + +// getKeys returns the stored keys of the memory sql +// of the localTrie for further processing. +func (lt *localTrie) getKeys() ([][]byte, error) { + if err := lt.commit(); err != nil { + return nil, err + } + + // collect all of the node keys + it := lt.trie.NodeIterator([]byte{}) + keyBytes := make([][]byte, 0) + for it.Next(true) { + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + keyBytes = append(keyBytes, it.Hash().Bytes()) + } + return keyBytes, nil +} + +type nodeKey struct { + dbKey []byte + TrieKey []byte +} + +// getLeafKeys returns the stored leaf keys from the memory sql +// of the localTrie for further processing. +func (lt *localTrie) getLeafKeys() ([]*nodeKey, error) { + if err := lt.commit(); err != nil { + return nil, err + } + + it := lt.trie.NodeIterator([]byte{}) + leafKeys := make([]*nodeKey, 0) + for it.Next(true) { + if it.Leaf() || bytes.Equal(nullHashBytes, it.Hash().Bytes()) { + continue + } + + node, nodeElements, err := sdtrie.ResolveNode(it, lt.trieDB) + if err != nil { + return nil, err + } + + if node.NodeType != sdtypes.Leaf { + continue + } + + partialPath := trie.CompactToHex(nodeElements[0].([]byte)) + valueNodePath := append(node.Path, partialPath...) + encodedPath := trie.HexToCompact(valueNodePath) + leafKey := encodedPath[1:] + + leafKeys = append(leafKeys, &nodeKey{dbKey: it.Hash().Bytes(), TrieKey: leafKey}) + } + return leafKeys, nil +} + +// getRLP encodes the given object to RLP returning its bytes. +func getRLP(object interface{}) []byte { + buf := new(bytes.Buffer) + if err := rlp.Encode(buf, object); err != nil { + panic(err) + } + + return buf.Bytes() +} diff --git a/statediff/indexer/ipld/test_data/error-tx-eth-block-body-json-999999 b/statediff/indexer/ipld/test_data/error-tx-eth-block-body-json-999999 new file mode 100644 index 000000000..8654b53a9 --- /dev/null +++ b/statediff/indexer/ipld/test_data/error-tx-eth-block-body-json-999999 @@ -0,0 +1 @@ +{"jsonrpc":"2.0","result":{"author":"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5","difficulty":"0xb6b4beb1e8e","extraData":"0xd783010303844765746887676f312e342e32856c696e7578","gasLimit":"0x2fefd8","gasUsed":"0x38658","hash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5","mixHash":"0x5b10f4a08a6c209d426f6158bd24b574f4f7b7aa0099c67c14a1f693b4dd04d0","nonce":"0xf491f46b60fe04b3","number":"0xf423f","parentHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","receiptsRoot":"0x7fa0f6ca2a01823208d80801edad37e3e3a003b55c89319b45eb1f97862ad229","sealFields":["0xa05b10f4a08a6c209d426f6158bd24b574f4f7b7aa0099c67c14a1f693b4dd04d0","0x88f491f46b60fe04b3"],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x6e8","stateRoot":"0xed98aa4b5b19c82fb35364f08508ae0a6dec665fa57663dca94c5d70554cde10","timestamp":"0x56bfb405","totalDifficulty":"0x6305496c80ab5c3f","transactions":[{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0xc3665b8a9224ba8da9a20322f31d599cafa52c5c","gas":"0x5209","gasPrice":"0xdf8475800","hash":"0x22879e0bc9602fef59dc0602f9bc385f12632da5cb4eee4b813a0c27159c4d24","input":"0x","networkId":null,"nonce":"0x1d3","publicKey":"0xc3dbee74f1b2b8dbedc417244b7f5a134c6f7769faf9ffe784b3f0fdda7ca52cf914d3f2b3164c009bf939796b77f047ccb4cc113d3bde5b06555b781e0c7149","r":"0x43531017f1569ec692c0bf1ad710ddb5158b60505ea33fb7a21245738539e2d5","raw":"0xf86e8201d3850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d8888102363ac310a4000801ca043531017f1569ec692c0bf1ad710ddb5158b60505ea33fb7a21245738539e2d5a03856c6a1117ff71e9b769ccb6960674038a3326c3dd84c152fc83ada28145a07","s":"0x3856c6a1117ff71e9b769ccb6960674038a3326c3dd84c152fc83ada28145a07","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x0","v":"0x1c","value":"0x102363ac310a4000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x4ce758b0c8aa655b77c14f16bd0190b5715be75a","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x3c634bf5f09f6b5b5ea377df7abb483f422ae5d4ba389c395f14f833de25d362","input":"0x","networkId":null,"nonce":"0x9","publicKey":"0x75022ee25c702fc6a53853843e00e87877e737f9c631a9d831c11693d7e31877a1b09755ab3a5c112decf57339839364b8b9a3c23ada01761b1e3a044e297316","r":"0x8219a4f30cb8dd7d5e1163ac433f207b599d804b0d74ee54c8694014db647700","raw":"0xf86c09850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880ed350879ce50000801ba08219a4f30cb8dd7d5e1163ac433f207b599d804b0d74ee54c8694014db647700a03db2e806986a746d44d675fdbbd7594bb2856946ba257209abfffdd1628141af","s":"0x3db2e806986a746d44d675fdbbd7594bb2856946ba257209abfffdd1628141af","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x1","v":"0x1b","value":"0xed350879ce50000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x30906581413d556de1a018adbe6cc63c88d58512","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x59feccaad599e776cd6635e68b5e19254cca3b38e49437044f1e1d15d00b0576","input":"0x","networkId":null,"nonce":"0x59","publicKey":"0xccf6be26c1eb1c89d5fe958db0112a46e3ac23a95ac0f709ce84a49ae3f20bcf143909bfe67f685caaf362066e1c7e224899f57678bbcecb7a720175bcbb387d","r":"0x1ca26859a6eed116312010359c2e8351d126f31b078a0e2e19aae0acc98d9488","raw":"0xf86c59850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88882b0ca8b9f5f02000801ba01ca26859a6eed116312010359c2e8351d126f31b078a0e2e19aae0acc98d9488a0172c1a299737440a9063af6547d567ca7d269bfc2a9e81ec1de21aa8bd8e17b1","s":"0x172c1a299737440a9063af6547d567ca7d269bfc2a9e81ec1de21aa8bd8e17b1","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x2","v":"0x1b","value":"0x2b0ca8b9f5f02000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x8bec4e6fb1a28820eb1e8ec2d4eae4842ed2f923","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x98a03afa804e248ada5f26e9118ae927d4d3cb60e78c54938dced1cf25ee3567","input":"0x","networkId":null,"nonce":"0x2","publicKey":"0xbc8c89a85804c7859069c13561dbbd8d1d4739ec7d18514c42b3ffea64529cee522a5e20d93373d0074e94c4c7b6eba51c7d2f18ef7c64c37520342acb233795","r":"0xa5aca100a264a8da4a58bef77c5116a6dde42186ac249623c0edcb30189640a","raw":"0xf86c02850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880fd037ba87693800801ba00a5aca100a264a8da4a58bef77c5116a6dde42186ac249623c0edcb30189640aa0783e9439755023b919897574f94337aaac4a1ddc20217e3ac264a7edf813ffdd","s":"0x783e9439755023b919897574f94337aaac4a1ddc20217e3ac264a7edf813ffdd","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x3","v":"0x1b","value":"0xfd037ba87693800"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x4835a9626b02369546502d2949e16b0fda110b0c","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x18f1e6430334ad548bc36fc317016bc9f7a076d1fa50a89fe4e1d095ed3f9562","input":"0x","networkId":null,"nonce":"0xd9","publicKey":"0x91b3b4fe89d112cfc7308619e8aa7de86f14af3f6b6e4e92becb6e29e98207835bbe1a69109c16b14b0eb7285d2b952a9cde6007932afe95e81eefc183f75314","r":"0xb93c6f8dce800a1ec57d70813c4d35e3ffe25a6f1ae9057cf706636cf34d662","raw":"0xf86d81d9850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d888814bac05c835a5400801ba00b93c6f8dce800a1ec57d70813c4d35e3ffe25a6f1ae9057cf706636cf34d662a06d254a5557b7716ef01dd28aa84cc919f397c0a778f3a109a1ee9df2fc530ec0","s":"0x6d254a5557b7716ef01dd28aa84cc919f397c0a778f3a109a1ee9df2fc530ec0","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x4","v":"0x1b","value":"0x14bac05c835a5400"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x9cc72ebf3daaf12c72e48605e1e67b47c95a1911","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0xb1cada8daf63c45750df1ee79eed5a3cf6240e3cebdb6de3f26bc7cf03217bf4","input":"0x","networkId":null,"nonce":"0x34","publicKey":"0x90dff18c1c01d566e6d8bf0190e3e965f98e7f51ccbbe6040f9a9972e88f4ad19f1547406454fbc9e1ebcf4c5f2f1e2df9b9371028fe0a552ecca5f5f0aa4129","r":"0xe9a25c929c26d1a95232ba75aef419a91b470651eb77614695e16c5ba023e383","raw":"0xf86c34850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880f258512af0d4000801ba0e9a25c929c26d1a95232ba75aef419a91b470651eb77614695e16c5ba023e383a0679fb2fc0d0b0f3549967c0894ee7d947f07d238a83ef745bc3ced5143a4af36","s":"0x679fb2fc0d0b0f3549967c0894ee7d947f07d238a83ef745bc3ced5143a4af36","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x5","v":"0x1b","value":"0xf258512af0d4000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x5c51467399bc655f0cc6db88df15946717534633","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x4fa879b491e0779fc035758ec77b93c4e51d528d65b64eb055c015a58deff103","input":"0x","networkId":null,"nonce":"0x6f","publicKey":"0x0b7e2532afc2daa33763002525aa6c7edc25ea97d63baeeb2c6f5094f18dca4a0212b52061f9a9091aad5c4380a6506f9a51ddd2d014e78742bf144a58d6ffa0","r":"0x9e0b8360a36d6d0320aef19bd811431b1a692504549da9f05f9b4d9e329993b9","raw":"0xf86c6f850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88881c54e302456eb400801ca09e0b8360a36d6d0320aef19bd811431b1a692504549da9f05f9b4d9e329993b9a05acff70bd8cf82d9d70b11d4e59dc5d54937475ec394ec846263495f61e5e6ee","s":"0x5acff70bd8cf82d9d70b11d4e59dc5d54937475ec394ec846263495f61e5e6ee","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x6","v":"0x1c","value":"0x1c54e302456eb400"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x055d9d7ec193d1e062c6ec4fa80ef89b5c1258f4","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x1bea59827ab153b20cee79890d221a80fa6a04e552d667504c592ed314fb6d76","input":"0x","networkId":null,"nonce":"0x46","publicKey":"0xfae19a0ac08d36f0229663d45d0c41ca52c4e295c7af82a1b39515a79025175293400d026e0d41767aac42f8b7e4a6687c5762161457d753f1fc0766614868f9","r":"0xb2803f1bfa237bda762d214f71a4c71a7306f55df2880c77d746024e81ccbaa2","raw":"0xf86c46850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880f0447b1edca4000801ca0b2803f1bfa237bda762d214f71a4c71a7306f55df2880c77d746024e81ccbaa2a07aeed35c0cbfbe0ed6552fd55b3f57fdc054eeabd02fc61bf66d9a8843aa593a","s":"0x7aeed35c0cbfbe0ed6552fd55b3f57fdc054eeabd02fc61bf66d9a8843aa593a","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x7","v":"0x1c","value":"0xf0447b1edca4000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x8e68c0c9b5275fa684291304af9cafe6ceaf2772","gas":"0x15f90","gasPrice":"0xba43b7400","hash":"0x73e87db1108a2aa852f48e088ca1a2771f9b7c18af8d1bd77a3cdcc72a750c56","input":"0x","networkId":null,"nonce":"0x3","publicKey":"0xa5e423dfcbdbba1fdbb785367a88235fa2569061d72b6c715111ac21cbef8fc1db860acdef85f1408c760f34b28a4f07d950ac15c4b85d5e528e50f546a89b6d","r":"0x6dccb1349919662c40455aee04472ae307195580837510ecf2e6fc428876eb03","raw":"0xf86d03850ba43b740083015f909426016a2b5d872adc1b131a4cd9d4b18789d0d9eb88016345785d8a0000801ba06dccb1349919662c40455aee04472ae307195580837510ecf2e6fc428876eb03a03b84ea9c3c6462ac086a1d789a167c2735896a6b5a40e85a6e45da8884fe27de","s":"0x3b84ea9c3c6462ac086a1d789a167c2735896a6b5a40e85a6e45da8884fe27de","standardV":"0x0","to":"0x26016a2b5d872adc1b131a4cd9d4b18789d0d9eb","transactionIndex":"0x8","v":"0x1b","value":"0x16345785d8a0000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x2a65aca4d5fc5b5c859090a6c34d164135398226","gas":"0x15f90","gasPrice":"0xba43b7400","hash":"0x337a5e90b73f44ffebea73cb3d97738c524f63e1032b30735e43212cff731aee","input":"0x","networkId":null,"nonce":"0x2a11f","publicKey":"0x4c3eb5e19c71d8245eaaaba21ef8f94a70e9250848d10ade086f893a7a33a06d7063590e9e6ca88f918d7704840d903298fe802b6047fa7f6d09603eba690c39","r":"0xaa8909295ff178639df961126970f44b5d894326eb47cead161f6910799a98b8","raw":"0xf8708302a11f850ba43b740083015f90945275c3371ece4d4a5b1e14cf6dbfc2277d58ef92880e93ea6a35f2e000801ba0aa8909295ff178639df961126970f44b5d894326eb47cead161f6910799a98b8a0254d7742eccaf2f4c44bfe638378dcf42bdde9465f231b89003cc7927de5d46e","s":"0x254d7742eccaf2f4c44bfe638378dcf42bdde9465f231b89003cc7927de5d46e","standardV":"0x0","to":"0x5275c3371ece4d4a5b1e14cf6dbfc2277d58ef92","transactionIndex":"0x9","v":"0x1b","value":"0xe93ea6a35f2e000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x2a65aca4d5fc5b5c859090a6c34d164135398226","gas":"0x15f90","gasPrice":"0xba43b7400","hash":"0xc280ab030e20bc9ef72c87b420d58f598bda753ef80a53136a923848b0c89a5c","input":"0x","networkId":null,"nonce":"0x2a120","publicKey":"0x4c3eb5e19c71d8245eaaaba21ef8f94a70e9250848d10ade086f893a7a33a06d7063590e9e6ca88f918d7704840d903298fe802b6047fa7f6d09603eba690c39","r":"0xcfe3ad31d6612f8d787c45f115cc5b43fb22bcc210b62ae71dc7cbf0a6bea8df","raw":"0xf8708302a120850ba43b740083015f90941c51bf013add0857c5d9cf2f71a7f15ca93d4816880e917c4b10c87400801ca0cfe3ad31d6612f8d787c45f115cc5b43fb22bcc210b62ae71dc7cbf0a6bea8dfa057db8998114fae3c337e99dbd8573d4085691880f4576c6c1f6c5bbfe67d6cf0","s":"0x57db8998114fae3c337e99dbd8573d4085691880f4576c6c1f6c5bbfe67d6cf0","standardV":"0x1","to":"0x1c51bf013add0857c5d9cf2f71a7f15ca93d4816","transactionIndex":"0xa","v":"0x1c","value":"0xe917c4b10c87400"}],"transactionsRoot":"0x447cbd8c48f498a6912b10831cdff59c7fbfcbbe735ca92883d4fa06dcd7ae54","uncles":[]},"id":1} diff --git a/statediff/indexer/ipld/test_data/eth-block-body-json-0 b/statediff/indexer/ipld/test_data/eth-block-body-json-0 new file mode 100644 index 000000000..e7dfbca84 --- /dev/null +++ b/statediff/indexer/ipld/test_data/eth-block-body-json-0 @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":1,"result":{"author":"0x0000000000000000000000000000000000000000","difficulty":"0x400000000","extraData":"0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa","gasLimit":"0x1388","gasUsed":"0x0","hash":"0xd4e56740f876aef8c010b86a40d5f56745a118d0906a34e69aec8c0db1cb8fa3","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x0000000000000000000000000000000000000000","mixHash":"0x0000000000000000000000000000000000000000000000000000000000000000","nonce":"0x0000000000000042","number":"0x0","parentHash":"0x0000000000000000000000000000000000000000000000000000000000000000","receiptsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","sealFields":["0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000042"],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x21c","stateRoot":"0xd7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544","timestamp":"0x0","totalDifficulty":"0x400000000","transactions":[],"transactionsRoot":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421","uncles":[]}} \ No newline at end of file diff --git a/statediff/indexer/ipld/test_data/eth-block-body-json-4139497 b/statediff/indexer/ipld/test_data/eth-block-body-json-4139497 new file mode 100644 index 000000000..02ef39584 --- /dev/null +++ b/statediff/indexer/ipld/test_data/eth-block-body-json-4139497 @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":1,"result":{"difficulty":"0x5c647cfc07f1a","extraData":"0x65746865726d696e652d6173696137","gasLimit":"0x668fd6","gasUsed":"0x655bf3","hash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","logsBloom":"0x00004000840000000004000400000006008800000000000000900000000000000002000000100000000000000000020000000000004000000000080000080000000000000200000000000008000000000001000000000000000000000800000000014000000200000000804040000200000000000100008004000110001000200000020400000000800200000008000000400080008000200000001040000100002000000000000002000000000000000000010000000010080000000000000010080002000000000000002001000000000000040000000120200000000000000100000100000000000000000000000000000000000000000000040800000000","miner":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","mixHash":"0x2a65887132d93df4ad543ea9ab69b2de12bf1ef0d9a5b9128fe557a7cf6e365c","nonce":"0x68b593b0029de941","number":"0x3f29e9","parentHash":"0xf8ef0dc32d00fe925c9ac3039f3fe202ac6988f37b3710840848ecf29a4905d9","receiptsRoot":"0xf17608f36b1fc813fefd9cbd1fd653195de20ab72f2efcc95f7e00c6576080d6","sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x8a42","stateRoot":"0x3258ad3d8a73140be9d3895166f3f88b0f65a5575d8176f10dc2a6dddac36b64","timestamp":"0x598c1020","totalDifficulty":"0x23bcce551ec1d5055c","transactions":[{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0x55335d56e95151bce1635bce649175ea954aecee","gas":"0x2117a","gasPrice":"0xbdfd63e00","hash":"0x51f9d60ce19d4174224f91be402d4504553f127511a630a18a8735b4c1db072e","input":"0x0f2c9329000000000000000000000000fbb1b73c4f0bda4f67dca266ce6ef42f520fbb98000000000000000000000000e592b0d8baa2cb677034389b76a71b0d1823e0d1","nonce":"0x1","to":"0xe94b04a0fed112f3664e45adb2b8915693dd5ff3","transactionIndex":"0x0","value":"0xb7ce92a6fa0400","v":"0x26","r":"0xaa97e8fb84036ed395fab0e05f4432e219e855539a17a73444e915a3f18d7f15","s":"0x117401fbe04f6c8316ba4c344b37de5d1b5a6fc252160a093e7270d6fd37c2c4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98","gas":"0x2d9dc","gasPrice":"0xbdfd63e00","hash":"0x57a6c52559d193fef65f8b99fdd46f341f0739ba7d4a772a87d8fad89fc2cff5","input":"0xa9059cbb000000000000000000000000744346c50253300694aea6d7e03f55a3ea91f8a30000000000000000000000000000000000000000000000000000013061e0a9ab","nonce":"0xc104d","to":"0x41e5560054824ea6b0732e656e3ad64e20e94e45","transactionIndex":"0x1","value":"0x0","v":"0x25","r":"0xe925321edf5dc905fa0ebf9a08d8915e0ce90463d55c19e8bdf0dc8e5e6ddc73","s":"0x328a5099139ae2e3f3be2736dec30fd2b3240892b77575e588b8f84a0e11307b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xa624ceb708a1e9a3962de82c5a3c5850db0097f1","gas":"0x2117a","gasPrice":"0xbdfd63e00","hash":"0x616694b9e9aea8d913797a50958a9343e18451ccb2abffa1b10b2d06378c612f","input":"0x0f2c9329000000000000000000000000fbb1b73c4f0bda4f67dca266ce6ef42f520fbb98000000000000000000000000e592b0d8baa2cb677034389b76a71b0d1823e0d1","nonce":"0x24","to":"0xe94b04a0fed112f3664e45adb2b8915693dd5ff3","transactionIndex":"0x2","value":"0xa9f1b6b74205400","v":"0x26","r":"0x4b6f583ee70f4aabad8da3c97a0b1d7bd18ef6463aa08fb730696b758abe255c","s":"0x1a13f3c8fef9b92c28151db22b03b9b9894b2d7ef103a38b204ac5ba970073fe"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xb083a0287b4e7f8319eee74b27e42bdd77da4e1a","gas":"0x2117a","gasPrice":"0xbdfd63e00","hash":"0x92a84244da41cd93c1c0ab7b7d13556453d3fd76317a71fa89ba129ad4c9d80e","input":"0x0f2c9329000000000000000000000000fbb1b73c4f0bda4f67dca266ce6ef42f520fbb98000000000000000000000000e592b0d8baa2cb677034389b76a71b0d1823e0d1","nonce":"0x3","to":"0xe94b04a0fed112f3664e45adb2b8915693dd5ff3","transactionIndex":"0x3","value":"0xd51851e1dacc00","v":"0x26","r":"0xc8304a7acbaddcdd4ac10216697ea88d1b154c9d0de42fb75ad9a301fef38cc1","s":"0x76cdd85171fb9da403def3fbfafb8545835aebeb9a541e6207d9d373914e1e8d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xc348b6a2758fb408e5cce34d43feee1726692e0d","gas":"0x13880","gasPrice":"0x719f11100","hash":"0x164a9b95e7914ef6071b6228699635e8e8d58b4d60fd4736aabd87b5bcf8d5fb","input":"0x","nonce":"0x3b","to":"0x7727e5113d1d161373623e5f49fd568b4f543a9e","transactionIndex":"0x4","value":"0x18f7be6e64863700","v":"0x25","r":"0xfb14159445060e4a1809e7d959210da4151fe1535c8b9aa9158b5d7536b0fbac","s":"0x3563cf5da676135b36d9d2305f1ee133452280e2c1abe16bda50fe502557d1d9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xd3273eba07248020bf98a8b560ec1576a612102f","gas":"0x5208","gasPrice":"0x6fc23ac00","hash":"0x5d6f0ac462923b852080c3b96afa862bc93a4bc605e5feb9bda64780d6c89089","input":"0x","nonce":"0x67ac","to":"0xd66f7b11c7da581406d62a501fdee675466f4593","transactionIndex":"0x5","value":"0x5bd6662df2c3c400","v":"0x1c","r":"0xf042ec51b11a4c14cb7f48e50e3c4278965530f9e5c4a17926e47f83dbf09fe5","s":"0x5eee0c65eacdabfb60688656d108ab5dc74dce9ad79f661148bbba7694a5c191"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0x3b0bc51ab9de1e5b7b6e34e5b960285805c41736","gas":"0x5208","gasPrice":"0x6fc23ac00","hash":"0x8c951abf8f855e94f1059a0b9f9de8e23e12ffc7d4511e0dcbfe73060ff2e9ee","input":"0x","nonce":"0x6595","to":"0x7c402ca59a701f6b3f077f175b4c964122043221","transactionIndex":"0x6","value":"0x5bd6662df2c3c400","v":"0x1c","r":"0x36d4084792312a9aafd676e0570acc14b29b590bc3f38e0c643ff278653628ae","s":"0x4f25d719cd23e3fb88bd205e955d8127c819d208046e83f9ac9a47c35ec2a814"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0x093177dbaa25a001e3ee343d3ec492e71b9367aa","gas":"0x6271","gasPrice":"0x6c7fc3b40","hash":"0xecc2c35c2ca748c7eb2970d76288e34ab514a48c60670ba5fa04ec50d59be1f5","input":"0x","nonce":"0x2","to":"0xda1b2aeac0196d39658186604609fff185e1774d","transactionIndex":"0x7","value":"0x5b09cd3e5e90000","v":"0x26","r":"0xef0a0125e0984c9a59fbe475df19bed2fcbfbe02ced04ad9f5f25530e276a527","s":"0x7ce66b31396aaf02a34d966e87e03ba9f04ac021f56e8ca1cd6124434df61ab1"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xf04ad0c7eb4ed654c52477f8e756800bde9f2341","gas":"0x5208","gasPrice":"0x4e3b29200","hash":"0x7475e0a920d21ee08b85f0ec61b02ed646190ff23ae2805dfef4cfe81c59a46e","input":"0x","nonce":"0x427","to":"0x1e4f986d287bacf4283d35ca61fb342ca91674d6","transactionIndex":"0x8","value":"0x3d48c89a6020000","v":"0x26","r":"0xdab319aff51e0755b832a17fba0e4778895980eb6cb87a2aa4b35edd418163ef","s":"0x10dc3f986fe67347e293177acdd0dbfa7a910d64c9c484a0635221dd652a6191"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xb2930b35844a230f00e51431acae96fe543a0347","gas":"0x186a0","gasPrice":"0x4a817c800","hash":"0x070599a9b0a4e550cdb1b5068d0d3bfe3fc0d60302973d3b3abad3a4762ae81c","input":"0x","nonce":"0x569fe","to":"0x79d56207445e24f5eeb391358924a39c620dd1e0","transactionIndex":"0x9","value":"0x21c60092fff800","v":"0x26","r":"0x77ba2e5b7c617e6ad54a7d4ca14362837cdd3138648a0855436a6fef99033d4d","s":"0x6714b8b257a8c714b2395fca0a8bfd9299fa3d759da9c01a2582d7114a316f05"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xcbf44ffb74ae94a4b696e716964b1d69400c7749","gas":"0x11170","gasPrice":"0x4a817c800","hash":"0xa3031fce94886738b6666b8a58233e845e9fd4ced150f65c043738fc54ccc7bb","input":"0xa9059cbb000000000000000000000000e74db956a107baa7cadc1258a6f539f40fc4fec100000000000000000000000000000000000000000000000000000002caa8e180","nonce":"0x0","to":"0x93e682107d1e9defb0b5ee701c71707a4b2e46bc","transactionIndex":"0xa","value":"0x0","v":"0x26","r":"0xda99eedee485f9f789cc183307b139b63e0885c7135796fbcca1d20415fd884e","s":"0x5103dc4b2fe14ec65fe2c98c331cf9177ffee86a89ab5b8079a3ee285bdab7c"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfc203c5f867be784726ef4198c0e8fc1313074db","gas":"0x5208","gasPrice":"0x4a817c800","hash":"0xaf654ac5eaecca624725c4236adcbee10a9b4c76f4bb71c893c373c659a4305a","input":"0x","nonce":"0x1","to":"0xa3da2a2f864a180297adedc48ad51e562d7a9f8a","transactionIndex":"0xb","value":"0x1e81bba24c058138c1","v":"0x25","r":"0x6e1989c52a8d07f84ad0701cc6eae4e9fbb2ca79476b03422098d03e52e6a594","s":"0x6d36b9c8ed63abab0ada4fd9c53541d4b948b23c79ae118cd2f205a010f2c0ee"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0xb2f6b98129aad387041bfe8710bc1bf363bb208f15d49a482b5d15bbd13d1cec","input":"0x","nonce":"0x2aaab9","to":"0xabcd334c3504100e6d26d895c8c658e35fe515f7","transactionIndex":"0xc","value":"0xaf069a8a72ee91","v":"0x25","r":"0x5b5bdfabd8a099a056af2ecef44bc142aa5bfe7623a14505fc0c6f3f059eee0","s":"0x336f76890622529392f3eabbd793be3ec6367b31b65737d6ea2ebedcc934f3d6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0x75814b803794e796a4b496765af343121020238e","gas":"0x5208","gasPrice":"0x4a817c800","hash":"0xcf257e096c2cd20debbb4608d00ca28b3c576b705de8109090caead53ccfab17","input":"0x","nonce":"0x1","to":"0xd0bcd02f598c2473395842d647011b6d1cdd0e5c","transactionIndex":"0xd","value":"0x1ee647737e6ec208c1","v":"0x26","r":"0xcd5de53b8c661068d31053854e4e562f276e8481cba387d6853910d415a8e213","s":"0x2d209a8658c9411087c389f3bdeaa9c2ff70eac8950f0b4db413fcc39a4fee2b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0x8f5aae245398626bc162b47b862fa09e49190b38","gas":"0xbb00","gasPrice":"0x2540be400","hash":"0xb16f7c1b61134c155cb820d8f51d77e93fa7212c8f46be42dbfc8a3767d176fb","input":"0xa9059cbb0000000000000000000000004f5151785e03b47d0c6641872bb6b29b6de1b77c00000000000000000000000000000000000000000000000bbc4849990fa54400","nonce":"0x0","to":"0x888666ca69e0f178ded6d75b5726cee99a87d698","transactionIndex":"0xe","value":"0x0","v":"0x1c","r":"0x25dca29942900fe444e2e3e27ea41648d6a22947a9d8a38e11ae367b0a064d0f","s":"0x52e06101618b2fe1f3a845f4f39a3092016e920855be9c9b447e3d6828e1b263"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0x22b84d5ffea8b801c0422afe752377a64aa738c2","gas":"0x186a0","gasPrice":"0x2540be400","hash":"0xf40a89152e66d51b54ae72df0712e08fd6c121fd1d58f7cbc38f63249a139963","input":"0x","nonce":"0x1af86","to":"0x444d80ab1f1540642d69b3eaeb790903cf4872bd","transactionIndex":"0xf","value":"0x53444835ec580000","v":"0x25","r":"0xebadeffaf6e5a8b53f482372e9b33db8c0380f4a21a388f499b0f0072e8e2afa","s":"0x455bd8083723fbb895f0fe62c02ad1882bc3daa76443e4a77494f984824e9c73"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x5ee4fb7764e28e71b9d0ce72741d6df027b4a79f969a71364db380de686cc1f1","input":"0x","nonce":"0x9c5c","to":"0x3c13a69380e27bfd16a5bc5528f4c1d6cc4993ac","transactionIndex":"0x10","value":"0xbec8544eceac00","v":"0x26","r":"0xe7eb23823262f600e33b526a953ac7e32dcc0cf86d9f1febbf8db30edea03b02","s":"0x595d98353ad032557caf00ebe14f21ebe66fab85394a421d8bbd9a47b3ae6627"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5","gas":"0xc350","gasPrice":"0xee6b2800","hash":"0xc0e565782181943c4697199214db1d21a535835b665b2ba771fbe4693ce52de0","input":"0x","nonce":"0x292ad7","to":"0x0fbb3c7bcac281b97f8a8a3292a026d67c3230f1","transactionIndex":"0x11","value":"0xb2e25606328960","v":"0x26","r":"0x837849bae28e40b752586ce7135cee1a4741eb3f68b089cb6ef4dfb4b6291738","s":"0x312d8f5e8a25836687d6eb69be151016074355ee5b580793111314daba9da1a6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98","gas":"0x2d99c","gasPrice":"0xbdfd63e00","hash":"0xc092388bd2e7626c53e3c580b4a5d57de3442b28c97b34fe1ff68042b9026137","input":"0xa9059cbb000000000000000000000000cd2e8348d2f58f02f1859ecdef07d1ecf1f0ced9000000000000000000000000000000000000000000000000000000174867a5c0","nonce":"0xc104e","to":"0x41e5560054824ea6b0732e656e3ad64e20e94e45","transactionIndex":"0x12","value":"0x0","v":"0x26","r":"0xec60ffa5508b41567c20a68f26df77c3de22fa3b11fa853c7562f693df12cc03","s":"0x5fff6d9220b4da3f68358ead8b782e52de0f2ae2def4c07e5d547d513fcfe80"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x34ee80fe753728be177a1e6ed5541565b2c94da9ac8fb5d16e7cc757cea3692a","input":"0x","nonce":"0x2aaaba","to":"0xfd15c258b4191b73c7dde5df066f4732e4392f7f","transactionIndex":"0x13","value":"0xdee2eb356bf15a2","v":"0x25","r":"0xa5737391f905649e6ed6604db0b4040e94aec8bc6ad47afcbb1f1cbd934a7dc2","s":"0x5a52547c6fce0aaf436c26033f92ef7542629b8cfad92a5137979f072f6371af"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfc203c5f867be784726ef4198c0e8fc1313074db","gas":"0x5208","gasPrice":"0x4a817c800","hash":"0x8c9d7cbc1629acab3c2b0a6423a84025e5bc11f15eec3bcfe2e224a505bdd5d2","input":"0x","nonce":"0x2","to":"0x42bd724618c19fd396b95891621e267968707dd3","transactionIndex":"0x14","value":"0x17b2a64c0adf2a073f","v":"0x26","r":"0xe40d950eeef37b63fd058ad8e0e9510b858ba5a67e033d99f89c9023a6fa227e","s":"0x791f7b441d70533f9670b7db0b224921944fea8820b5dfb2f06704f75872bea5"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbe853e3717ddcec5f9d57ed55e6ec1dc6fa1e9545c901b52a156f7b1b9c9cd3b","input":"0x","nonce":"0x9c5d","to":"0x7cb1e28cf73698e0474bf1b7b98d01a8e71204b1","transactionIndex":"0x15","value":"0xf1591cc0b131a400","v":"0x25","r":"0xd96f474d79e265d9dc5bf6bd09c46b54a25627caff37ff549c726e0ea7812920","s":"0x7630e1a32cdd1e3eaee6c00b38d349dfa3048ccbc20431cf651a218c124c1ab3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5","gas":"0xc350","gasPrice":"0xee6b2800","hash":"0xfaacce929d5e0f054479cb584dab3490770c43e616c3bba0c2f8bfd0a074a603","input":"0x","nonce":"0x292ad8","to":"0xda6b3b1bd62b06ca13fb37f660e8daf848b60330","transactionIndex":"0x16","value":"0x2e7c5072cf1e9e0","v":"0x26","r":"0x7d51a1209d5475564a4df31fef6d0a09c8b8aa1cc6d1c87cda42f02a58db4da6","s":"0x5ab60244b91d00e7d588151bd9f51f4fec1349c5c146b2178c2bca94610cbe3d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98","gas":"0x2d99c","gasPrice":"0xbdfd63e00","hash":"0xff1d6ee564b1be371792551a5b047ccdf519e74f3d5513da008318baf6915715","input":"0xa9059cbb00000000000000000000000091b1053eb9486b0b63d44a5cba021c324991027d0000000000000000000000000000000000000000000000000000005981122544","nonce":"0xc104f","to":"0x41e5560054824ea6b0732e656e3ad64e20e94e45","transactionIndex":"0x17","value":"0x0","v":"0x26","r":"0xe13fe6b5356d9abc156dffe6395f7b724a9b35ec58fc4026811241b03bad7a92","s":"0x33ae3ea46a35263b6d5e96574317c233affa15aea7d79209facbe88ce2eed013"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x4a2db708d569b49383b1d8abbff178b574affc87f879d57b5798904b52d0d4fb","input":"0x","nonce":"0x2aaabb","to":"0x029f13b14a1c4c65aa19f03fb12c0d761fc9e662","transactionIndex":"0x18","value":"0xb0297da2f04b2c","v":"0x26","r":"0xbad7b74d953063bb260fd27fc57c3ce40f46ab872fd44d62e30edd2a2da91e02","s":"0x7e513fa35422c73d96c51b455cfd09bd846ae5ea1f6047c6c84151cbfa68e6bd"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x5fa1fc424acb1df5a2efe579d9cf301ee4b7415b7086800fe48a1fd2f4127fee","input":"0x","nonce":"0x9c5e","to":"0x1f70dbf8b8c7a47dceea01ffe6749382245fa10f","transactionIndex":"0x19","value":"0x1a21d8eef282000","v":"0x25","r":"0xac50ff5d7c54b976fb08d24e235a1ba4e611a017332e20747818b1091cdf3a2f","s":"0x1523cdd85db8b8fd1e6dbc29bffef1583744f5a5ed278a97999fe44642e6b77f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98","gas":"0x2d9dc","gasPrice":"0xbdfd63e00","hash":"0x231bcf683e12cb3cb50d2979154e5537822b30974a3bf08596a231ae7ffde4e2","input":"0xa9059cbb00000000000000000000000018e3dfeaebe76cfacc75fd724e2c6e4ba140d56a00000000000000000000000000000000000000000000000000000107a24798c0","nonce":"0xc1050","to":"0x41e5560054824ea6b0732e656e3ad64e20e94e45","transactionIndex":"0x1a","value":"0x0","v":"0x25","r":"0x942337149235dbe45a6fb9596ca5bfd47f3d48a49bf17980bb7a424203f48130","s":"0x673e537d0a7edc66bfb3bfd7918adc7541f1850cb5249113cd6af089d25a75d3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x2809c2c670b3a0a57ab0279e369f34972e8aa818743a7b462e6c3812b139aa85","input":"0x","nonce":"0x2aaabc","to":"0x54da15b491babc978b2a3fc31841911a12c5ca0b","transactionIndex":"0x1b","value":"0xae56830ea32b52","v":"0x25","r":"0x8d0aa2d9e685b918186da550d2b00c51a0c471fc78493f6c6427d69b5e25def0","s":"0x79e64a26af42c415adba3b41dd899d030d683bb0c2c18289f0024bec84a34189"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb38ef7a0d9f4ec185696f9328171e38586d5f0c0c725cb2b1adf8a5c8a32b33e","input":"0x","nonce":"0x9c5f","to":"0x55b840e722a5a73b34320a34c48463e67993c0e2","transactionIndex":"0x1c","value":"0xd923293ec5e400","v":"0x26","r":"0x71e3e7c505606dfd773f53badb0f2d081207cbea0000c288781a18bcd6b75c14","s":"0x264bb04158b749785485323ba868ba7ada155985af7951bf948c4fb35bdc0ae7"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98","gas":"0x2d99c","gasPrice":"0xbdfd63e00","hash":"0x7b3c92175534b96e35797ba00deb87f606edac372bd573f06ff6636140938f6e","input":"0xa9059cbb000000000000000000000000be69390fbf8871caf82e2b70a92a4f7a87d161c20000000000000000000000000000000000000000000000000000004b585bb7f3","nonce":"0xc1051","to":"0x41e5560054824ea6b0732e656e3ad64e20e94e45","transactionIndex":"0x1d","value":"0x0","v":"0x25","r":"0x8863a36a60b2fa5a621cb01f1d80c324b519c8cd3bc3db559b47cc5e6777d26d","s":"0x3b5ff01f46e137f33f273ab3eaf3d6afb12959d19f8f01a9119d40fa9beb90ea"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x8f0b09787e0356ce6e2f43a2b5a15245137a0f6066a9fbcdf519e8df37a92aa7","input":"0x","nonce":"0x2aaabd","to":"0x863b65fe3b44db9f60dbace119fb08fdd4d2c62e","transactionIndex":"0x1e","value":"0xde5381edb9bafe8","v":"0x25","r":"0x61f134af94880a42bbfaffd277bbd8c80a6fc978e562dff4ca29e9c8b61968ce","s":"0x8a02c26b769e22e966d35d44acc175eb747f57bb9d3fa2c057e23b1529ba9e9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbe4bc2e52dc8bcb6df1a935ddcbd84958a1de639fbefe1da5ed829f8f4f4486b","input":"0x","nonce":"0x9c60","to":"0x585366a5ad43dc56ccbb54e94c48c6f1d931710a","transactionIndex":"0x1f","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x62674294331a2dfb96a2d7480331f18fe9003869e52f32f0a5b88a0094fbff63","s":"0xbf8f9286718f28e13473f4136b8e8989ca247db1075f6cc633fac869532e754"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98","gas":"0x2d9dc","gasPrice":"0xbdfd63e00","hash":"0x3eebb2d806a9ed429d460178c89d72364dd35719d1865942234bdd70bdfb258b","input":"0xa9059cbb0000000000000000000000004c59f430c6ebadaad6ccd25f4b9eeeb8f7a22108000000000000000000000000000000000000000000000000000001029f447f3e","nonce":"0xc1052","to":"0x41e5560054824ea6b0732e656e3ad64e20e94e45","transactionIndex":"0x20","value":"0x0","v":"0x25","r":"0x9e20b3b1429b5672d9f05a859633e1e4facb71e308924277811db2e3ebaefedd","s":"0x24803ead950f32f9863811c17f914ae9e831c48973183c036605d96750ee93a3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0xc94b14d966d087f09dc1bab45d5684d5c1f00167a27042e48391c4b97dbec90a","input":"0x","nonce":"0x2aaabe","to":"0x872bad809a1b1ec9a7dd38ac4d7e9b19920a1faf","transactionIndex":"0x21","value":"0xaf0a678d3ca95b","v":"0x25","r":"0xfad929edfbe500b2be3dffed3b9ebe4d9662bbdd211ae388a1c05a693c0054d8","s":"0x69f5962685c91ce1559d9e350b6322539f6d02dfa824d5253f381fda61f8f663"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x3cfa69cea575486acd281c7517bb9e4c74e6e8179065b5210b8ed06054a1c1a6","input":"0x","nonce":"0x9c61","to":"0x7d1340884d2b767da3e87daa3b59960c4e98b791","transactionIndex":"0x22","value":"0x17aadf094fd1c00","v":"0x25","r":"0xcf01d52255575cd6e8cc9045187c293bb950b56e69d152880fd672f026b71213","s":"0x131fe537936d809d1eebf72caa0019142e348d282bb59394f0a6c531338d95f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98","gas":"0x2d9dc","gasPrice":"0xbdfd63e00","hash":"0x8e2cad0763aea7b8a1e9b45b394aa0b62343dab30a230948bfdbe19988da31ad","input":"0xa9059cbb0000000000000000000000006ccecb1bdbf8f464f2b58adb417d5a88d0300f0a000000000000000000000000000000000000000000000000000002388f52ea80","nonce":"0xc1053","to":"0x41e5560054824ea6b0732e656e3ad64e20e94e45","transactionIndex":"0x23","value":"0x0","v":"0x26","r":"0x12ceb52c978e7a7e67f58068def1924fd7a500fcace1c39840f19dfdef82a130","s":"0x3d3e4826ade71f3e9079b31d9b8942c9f4f0cfc09bcc1cd66a9fefa9f2dcc8af"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0xd49fd3809e5349c4425c5712ab9fc2c69c825161ab706c1bf3179f30a4e8c5fb","input":"0x","nonce":"0x2aaabf","to":"0x959cd73ae36c115df8ee9d20f5d3101ff3181466","transactionIndex":"0x24","value":"0x17057457ca587d4","v":"0x26","r":"0x707870910fb23d9091244655fa4d6b317939f9e0011b89097ce4903f25ee6e8b","s":"0x16707cf3e313a11f694b881e1463322b07730b79f3133f74befa570fbc78ce78"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x4c56dac6f3503162683ae12d2445155aa1f705bb131c14742424944bede67517","input":"0x","nonce":"0x9c62","to":"0xc567f4a3d18d42fc49a5f8c54eaeaad0cc0713d0","transactionIndex":"0x25","value":"0xbe0d6ff05a3800","v":"0x26","r":"0xccb97060a133d58c8f40b7d2ecdba4447b19246f40a154f6e69b91368526f0f0","s":"0x5a6006fe0a064b9e378ee5f3ad329735f844b73b7a3837643737b9f02136824a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x90a0eba75638bce9ebe5554c4695fa9c25e95f85fa7ccb3ab134dddd24912f06","input":"0x","nonce":"0x2aaac0","to":"0x02eee5b2f34918340694c0aece742dc7f8ee0ff9","transactionIndex":"0x26","value":"0x161d70598349dc5","v":"0x25","r":"0x347bbd3db97596d8b48e281437e4038078582d6380ce2bdbe5621f2b04cd9acf","s":"0x9996abfaa8d6fa128c3801b033e6980306ec0185fcdf603b1ef425117023a54"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x448da8c7d24be59ec445f4df143cae6782fc194b1dbd61d07d1fbce99a525d2d","input":"0x","nonce":"0x9c63","to":"0x4530afe8ae24f91875b74da5fe251170177bcbfb","transactionIndex":"0x27","value":"0xc4a234146d6000","v":"0x26","r":"0x85303903f9f1301a6479d32cb6dea765c2a1bf114e59a50fb5b05e37a5b23631","s":"0x17478bce1de2c9fe6a984aeed9f831343376a145164c92277df4e63bcfcaabc3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0xd3ac8ce2a58d2f93adb88cfcf9241e1a682f71f69e61e0da04f3de056c0f3f28","input":"0x","nonce":"0x2aaac1","to":"0x04bdde4339294d8a521a28dc696f2286f0acd3d2","transactionIndex":"0x28","value":"0x185f9a12e284964","v":"0x26","r":"0x67403bb19a16ff477d30e264e4e4c0b6664c220e43b85c89c1fb0459085c0362","s":"0x617a3affb24dc4d38376c3ad4d33e972b3721e8ceadb779151a81aac031641d3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x96f04f1c4a5d8f81e8f541871ca1661662fee633aad36c65089a42418bc5dc5d","input":"0x","nonce":"0x9c64","to":"0x14fc32d88632e190beb08c1929c928954c06e336","transactionIndex":"0x29","value":"0xc3d6fc66994000","v":"0x26","r":"0xc567df5c64232efae75e1285c43f542ea8834aa9459674391e59dfe258598bb8","s":"0xf47712241b38e13645d6b07f8e8f95d4a2ac79b98052f04841100341a3fad1c"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x5723eeeb5059dd1f44a3edba5d51f584e8a75fc99633990f9aaf1e23e2516079","input":"0x","nonce":"0x2aaac2","to":"0x30d82cc8a274716b616e858e8fa9d2e7c0fe111b","transactionIndex":"0x2a","value":"0xaeaa14152dfe1e","v":"0x26","r":"0xae89dca52ea390dbca8a00900a19a3dd1165a02c4585efa702777acdf3f87115","s":"0x448a134ad23ee92f3674b827374977336d0cad450c341e4e3972c6cd67b2ecf7"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xa5e865c2964b73e24fede17686ef1df138230decd74fe82e4e39b1a0e0caf4d6","input":"0x","nonce":"0x9c65","to":"0xb29f1c22590d62d3b19eee1e10936263588cbf2b","transactionIndex":"0x2b","value":"0xb83e6e7e3cd000","v":"0x26","r":"0x1f479ee111fb49c8de1095073ab81fb8b048ddcccd272350f8ec4dd00a9ad22e","s":"0x2623cd338a54b042288111c855d915961c5941d1cca6489b46d46d010bc0ca98"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x52cd214a2ee626e53b235b9e87b443ab64c4dec4c45fe50a076d51df2ef6e12a","input":"0x","nonce":"0x2aaac3","to":"0x59ee98400e1456902ab7235d3af1e2fe08ccaf68","transactionIndex":"0x2c","value":"0x160138685419374","v":"0x26","r":"0x5a01a830c72bf2b2942c4f3b1a320117efd63d5e612edf4898db840cba35df0c","s":"0x3a5f1675cf8223cb3d72e226775d2ebe71c76cd0c07607cd747e9ef8edabe43f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x5db68a27e4f85fbf00dca00110b4e276a70472b09a253fa0b7c480def7554b7d","input":"0x","nonce":"0x9c66","to":"0x662978339d457e3c5de9ac99177d237cb577de7b","transactionIndex":"0x2d","value":"0x14c9782ba97f000","v":"0x26","r":"0xb244055b1b5e403b97f5f6e34e63b3726f8e5edfecd657895787157b6141e4fd","s":"0x4fab23be1914b18772b54af940f55c30dc6b944ab7c289381c48f2e1fc3164bc"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x3c00053e6b0cb4c2c82cc08df1de2886c527bceb37400af19d151c779b691ac2","input":"0x","nonce":"0x2aaac4","to":"0x1060044fb45772fdb205a7880bf10d98b3faa010","transactionIndex":"0x2e","value":"0x7203ddf4a7d9e58","v":"0x26","r":"0x61d38abdee2ec7eec8604f90900c110ecfb09c583433539ba09fc9987b6aa31e","s":"0x2d66a3034838de7aff0bda31653ee67698bde27a029a89c60f65ebc22a60739f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x5e8df31f2e5ca74f0b9cc072bcedd6b1aa9c890aae72747b386b35653bde4699","input":"0x","nonce":"0x9c67","to":"0x2b3c2f34d384a84a2db92861ef766d074d5dfe76","transactionIndex":"0x2f","value":"0xe036e48b422c00","v":"0x26","r":"0x147dce0b15914b2a5b9f3d6aceb62efab94a0fc3313bdfafc75456b65a7a850e","s":"0x5ca05bd2af4de11aa5faff07586b28d064365ef30ca9374e2746a68496139cb5"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0xf29b1ee3b69fd803e6a4336e1c2878a369c3b7d26a899502525a3e0a3988b1b1","input":"0x","nonce":"0x2aaac5","to":"0x49c059de3c341674028d3c4bd5438695423d673b","transactionIndex":"0x30","value":"0xae22078638a6d8","v":"0x25","r":"0xc6dc245f7ead2b2ea13a7c521e681733cfaed11e3f96d563cecc7f84689db1b1","s":"0x1a2837bfcc1b8eb5195d795fcdc6804c68058ea0328b42cb1ca3d90f897bc8be"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xefe29afe3225aae766b3698218cdc2ff8334871d2cd3e5a73331e8351a01cc3a","input":"0x","nonce":"0x9c68","to":"0x5ab9c59a3924a89fbeebfb614660ef5cb1dc9b27","transactionIndex":"0x31","value":"0xc510558adcf400","v":"0x25","r":"0x730a25ff42566dbd6acf5493b3dde8dc843b0954bf6474effe8a9ff36cf3a7f7","s":"0x29f4d2b0d9a042604db2082c527c42b0c12379e4b018630878caffedf5f1c8f6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x006a5d2207ef79083b3de8cc384fe4afcd78e28ff9603264eb487553292334d9","input":"0x","nonce":"0x2aaac6","to":"0xd97a422673e9f08c3a48c77fe2d880083745aba7","transactionIndex":"0x32","value":"0xae1e77264ee623","v":"0x26","r":"0x78e26d0ec880a8abbd47750dc27189756cbb45d097201de5524361b5dc1d6d4f","s":"0xe80f78a08e838680f1178a00c49750c6af34c0ff211c6472b22b5e65710b13b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8d2a63ae663da52ae3bbce4b0b193c806d920775cbfe78f1a9e2ce5fea730610","input":"0x","nonce":"0x9c69","to":"0x79e53465796e3ed6e4cfbb6108ed5dff81319a3c","transactionIndex":"0x33","value":"0xc96df5268c8400","v":"0x25","r":"0xbbce5c139e0cdfa424dd768acc1bceda22f89707e186987ea5cd652c541ff63","s":"0x3ae7cf7bcb887a14113e91574067abf179268084a6e4bfc64c97465fc7608532"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x8ec819436b821ad573f6a1fbed2a549cb8352c0035916fbfcb0cbbf007cd651c","input":"0x","nonce":"0x2aaac7","to":"0x1b9e602c4cac19e87b5faa3774414f54e362cc94","transactionIndex":"0x34","value":"0x160eb475460c2ef","v":"0x25","r":"0x9c67f12fd81232cc9b4f35fa39a5869efaf9290426a5b707e43373f2b78e726c","s":"0x14fff7e4a5d2fd57046c32273300541d87b1b8fdb89ca1f6e29083d925e29cdf"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x0f3cda751fbf72166bf419f483ef93fe40d4eceef994330d78bacf0ed1ac217e","input":"0x","nonce":"0x9c6a","to":"0x1c01da024f8674268128229b4486282e3091218e","transactionIndex":"0x35","value":"0xc3d6fc66994000","v":"0x26","r":"0xee64ba98405ef13c1046e20add36f83cffba6ec663217dcbe16cdef00866d781","s":"0x4353e70604753d5df5414b44949e6d5d3b0099ac9e908d3f386761a08dcc7681"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0x7b065e3308d58c1509f1af243bae91e6bf59b3af923b90089da3723d6ec0fd29","input":"0x","nonce":"0x2aaac8","to":"0x24702bcaba2cb34d081740605e57b1c0247fa668","transactionIndex":"0x36","value":"0xaf8e4871185ee8","v":"0x26","r":"0x6a3a5d089e0e69fac6406684950d7f8565ef20128d1bd864a2f885e70c45db67","s":"0x320c30498d3aed57d6549a4d89c96e5f35080177162396178a2c5bd7b465143f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x2a06d6d2c3af82096cb73bf602258342876c73b5072f7861b7f8abadafc28385","input":"0x","nonce":"0x9c6b","to":"0x6860e92acb529568c2c529db2e418ff9d39cb1fd","transactionIndex":"0x37","value":"0xb48cc1d8b16800","v":"0x26","r":"0x740010af0df82d950d2e77c857bf35b394573092008920faf64447a747eedcbc","s":"0x12b85f4e1dda634b7412f9707272036fdda220d5e1ffa867deda3231c1ff4945"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xea674fdde714fd979de3edf0f56aa9716b898ec8","gas":"0xc350","gasPrice":"0x4a817c800","hash":"0xfec8c03831f0a5cd907df0ba7e215ad87762b21771b1fef3ad324ad3825f14bb","input":"0x","nonce":"0x2aaac9","to":"0xba0d3ca997f8a5588dadbb7ce8000ca8ca8f79d7","transactionIndex":"0x38","value":"0x162ee6572dc409a","v":"0x26","r":"0x9f9c5920aa859759ab112d6eaf01c03bd4f8d7229224160d30446217f1ffa66a","s":"0x736877ecd30dbbc288f4f04e0e71da02f2cbf2abb52cc552af92d32fdd07089f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xca44697c858a5c081db2d5d27f0b89f30e8c4eaa92d9405cee3dcf674594753b","input":"0x","nonce":"0x9c6c","to":"0xd80e0dad2034dafbf1e56f9fbd9cf05e6d8f385e","transactionIndex":"0x39","value":"0xbfd66e5a367400","v":"0x26","r":"0x2b93cf57287f3ec365155ed3f511e4a653350e97ee21007de2f64f87821380a","s":"0x326f442a483cdfb9fceeefbefa7433bb2703cac555b583d22551f03b870cfb41"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x63cab64fa2fffa46dceed134e9731d0b54632002fe2b72d661fcb45a924242da","input":"0x","nonce":"0x9c6d","to":"0xb64b2a886be9164531a186a8031606361380c1a7","transactionIndex":"0x3a","value":"0xbfd66e5a367400","v":"0x26","r":"0x101551c907ae74aa1d49a3392d960b4101ce8a4ef7faf18c73cafee1fd81dbb9","s":"0x51d110c6cfd780fbfa6c02dad32bac18b734d7e7b4101efd3f0611d086fde41a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xec7220d4e4722386270508e0714bfdcffcd66475453ec1ced9c122bfe7fbc24c","input":"0x","nonce":"0x9c6e","to":"0x44b889082ca7cffa9f91107110754fe0abd07205","transactionIndex":"0x3b","value":"0xb5d019cc00e800","v":"0x26","r":"0x2e74c71007b9d74d9fa4de92f2c352275c0f8857883736d496388eb8acb2bc34","s":"0x63324a97cc0a246cc4901f9ada5ebf3c4a3c97b3b0697ae07b1370ca717cbea9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x33ded543bcc21f070d6e24f363bbfffffa8b8c39198493fc11252e5df2911e5c","input":"0x","nonce":"0x9c6f","to":"0x9257d8f0bde62f59f2d982ac4cd534e07d9dd345","transactionIndex":"0x3c","value":"0x17c1adfe0b47000","v":"0x25","r":"0xb1105d9b6f6a5382285f9ee15710d63bd484657b6f4563d1c40d83abdb401e12","s":"0x7ba86b5c18900e078abd585a6e63c55d9cfb51d093c4963fba6b5349f0183abd"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x6db11488011ec8e8820654a89b2f5e0e8b07e32973c5e2089f3d5f7065c7d181","input":"0x","nonce":"0x9c70","to":"0x5815bedf684599205589c23760509fa9c38a4703","transactionIndex":"0x3d","value":"0xbfd66e5a367400","v":"0x25","r":"0xadcde1c993ef446a648fe2eb469423418a993aea2315aef7db0040e703aa0e48","s":"0x695fcb0eed75e2fa344b896b0fd5e1ea7e1d2ddab9907a15c1f0d6cd48f29a49"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x30597ea097b887c60351a77a1efc12cd4a4fd2ffb7aa49564644cf43b8d0db9b","input":"0x","nonce":"0x9c71","to":"0x890910ab2c8f838de49a882235c1abb73e79a94b","transactionIndex":"0x3e","value":"0xd10ec777941000","v":"0x26","r":"0xb7669d6396e8abcbced7c20f898446ea3ce66ab6eef939f96dc104881d2ba4a9","s":"0x16a4f13c73e5c0f4885951413d683d59b8f209067e16b4c645814dfc60081ed0"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x3668733911bc9d75cd2ae0f7ec09c7f4f8a5cf979b57d44e718e92a20182358d","input":"0x","nonce":"0x9c72","to":"0x1fbb1f26b26379d9cf4a3fd152df619bc61aba0c","transactionIndex":"0x3f","value":"0xbfd66e5a367400","v":"0x26","r":"0xff3292258ac91736001885ceff8c7ed619af300f91e6abfe4e4386baad893fd1","s":"0x66113adf45b41a6f34cd895b3aef90c8d12be07e763abb0bb23d90c3768fa4b4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x5357798120a3efcd659e5c3b6a075bb927aee3cc1d2bede1441bc46717fffeae","input":"0x","nonce":"0x9c73","to":"0x1e3b979311a69a5e4aaf257d2887b2340b23e5ed","transactionIndex":"0x40","value":"0xbca080a4a2e400","v":"0x26","r":"0xdf1b455d46909ed9ad17a630f0bbe1ccbbaf2c6c67639d2235fb4b5f8516f3de","s":"0x5b848302ed3867c09bf756859d72371154295e0ede66432b2e56adbae7e2c824"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x4b02dc4da6b4c08222040ae4f3e1a79c0f8fc12f84134161caf188119c82a775","input":"0x","nonce":"0x9c74","to":"0x52f7aaf6429f28359c594831dd720906e9822aa0","transactionIndex":"0x41","value":"0xed90cd1676b800","v":"0x25","r":"0x3c2ead1b59d5090c0c671de8cfc2e68b1df523666f308eb1bce172b4aaaf8189","s":"0x168dd2296d99af982ee467b214d5fbdfb5d3bda5833e98d4a3c2508938a605bc"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9d2338fb32b44f71d384510790c1523342b00dce554f089cdc1b76c11cbc2ba6","input":"0x","nonce":"0x9c75","to":"0x5ce8433eb2b8411bd505ee4be968751aa8f3748f","transactionIndex":"0x42","value":"0xe7962d1595e000","v":"0x26","r":"0xf71aab079829b5d26ec7e66ac88a068bf212c5f3c21cfb9fc56adb18429787e8","s":"0x28804ef7db35b88adc0b0d5943e7923a92b21e9df575a5214859f94d085dd4b3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xaa8961638349e54a3cfe762e88df9a0c81801083ae67dd8da1594d59c2e7dacc","input":"0x","nonce":"0x9c76","to":"0xbb585a66faf023a157067aa4a5b9d704945686b4","transactionIndex":"0x43","value":"0xbe0d6ff05a3800","v":"0x26","r":"0xc0e6c5572dfab3dabf6ff6773f20dc1d6088390e4a8aabe2673ee582d7aacab1","s":"0x28f11928e0b87f0fbdc189ba1098c0c2a3935c73955658f28c68772534cc1cb6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x4ddba646404a84ce65c8566f72c52019faa62e3daee934bba7ed65dba0344d96","input":"0x","nonce":"0x9c77","to":"0xfcf8483d73472d9fec2c3daf98b05618fc5f659d","transactionIndex":"0x44","value":"0xbfd66e5a367400","v":"0x25","r":"0xaeaa50298fe64ddc28ca9e4e3c292bd7f31acccbbaa8e83a90e26f0d3e5aa826","s":"0x136c478f5a0534dc5aba89bbb597f65a64d54747560bd56e00a7d2ec79b88b1f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe3dc71466400ca4406b73dc9d37360752b5399949e758004c5898c6c8dbd19a9","input":"0x","nonce":"0x9c78","to":"0xecfee0a3eee9ba6daa6ac29e9c0cc18ac4302f5f","transactionIndex":"0x45","value":"0xc3d6fc66994000","v":"0x25","r":"0xecc5896a0b0cd9dd48efe7c4d014be27c6598205e89a10b803a0f744fa9e9618","s":"0x6190c56db4119fc23fa85ab9f2932d0634682dc472715fbd07919c4dda06ecff"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8408dd887fd59a64e665de856b9815f4b020a6721210a13be19eb55c5c21eead","input":"0x","nonce":"0x9c79","to":"0xc52478f306bc7f45ca93f26ec27b03e03eac7c45","transactionIndex":"0x46","value":"0x2a7700844a13400","v":"0x26","r":"0xcf05b89ee3b870440ee0dcc5810ba8818e43e5eaf300f0d078af2579871177cd","s":"0x6c2ff2f96d8239a18b581efbb38da45fa648c27a0f8a709f20ca017a0121c43e"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x0c45616865e3111fce61c7f9100d8f8a76ed13ca137b9a3c5b44402c8e82ac50","input":"0x","nonce":"0x9c7a","to":"0x9b49fb099165fb5eb966d2999e04bd3f6f175bb0","transactionIndex":"0x47","value":"0x6b7f99b36c8e400","v":"0x25","r":"0x8c9021e0e864d0e874386aa25fa7dfa2316077327f3672dab7e7b5c343af47a1","s":"0x46f028b207e2dc03a5f0116b07e4e721abad7379e8775c861fa1ef5d25d84b1"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x0a39cb1bbdd38b2a94379ee9b22fc14c8f4d3374c49077bab4cc48ba9779a02e","input":"0x","nonce":"0x9c7b","to":"0x25b672142b7e4f0d28cdacaf94caf4f4ea34c09d","transactionIndex":"0x48","value":"0x3b6432fb1c31800","v":"0x26","r":"0xb9be3c1bb492cdb18d6d50899a3adc0ae0f332584eae98e1049cf3b1096fcda9","s":"0x74bf6457ca137554ddfa6fe9a86d0474bfadd0c83890d7feb226cd79c7ae0de3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x95208af935d245e659f146820af71ff0a7fbfb353c4fa32823e8cdf4062e6dd8","input":"0x","nonce":"0x9c7c","to":"0x55aea382d3f06b0591a12a1b0dfcae08d6a5903d","transactionIndex":"0x49","value":"0xb26646c5657000","v":"0x26","r":"0xf622164cc9bd21c57f1417089e45fb64e589f32663db953cd8581f7d51acbe7","s":"0x10633d8c1ed7597f94e3ffef7d2cea86b1961193cc89e00275ed99fa054e15be"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xad3b5298c4aa0a1ac2d3c5d680214626d69887d3127d5883cf306f02604d9127","input":"0x","nonce":"0x9c7d","to":"0x493c979945440205866ed35bd7df2284cc5e8aef","transactionIndex":"0x4a","value":"0xb81dc0e359cc00","v":"0x25","r":"0xa82e22f5756a82153ae1c457cf16f74f49f42d07a585877922462deb4409e394","s":"0x2b7bcc0575ad15ae9c6bd8b61b62548bb9e4a8aab41c67dd95a7fdda4b117934"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x7daecd2bbfc31817012c988b1325deb998bebdf643a3aeeeadf302a534227f24","input":"0x","nonce":"0x9c7e","to":"0xfd47827a6bff38abdc3fcacb145ccf60326ffd1b","transactionIndex":"0x4b","value":"0x17c1adfe0b47000","v":"0x25","r":"0xeb65fe7953e57784d2607de0add1aad78fe5365ba4eb6ba323f0d28550095440","s":"0x5c04a96968949b3dbdd1ec1e7bd83b1f186cc96b5ae3a394cea9adf6cd53d507"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xdf5b469afc9a6ca28bc7be614fe46726bdd93b069cdebc856f52deff0e32f8f4","input":"0x","nonce":"0x9c7f","to":"0x416e269cc2bf8f9cf56cd70038c0714bb2fb2223","transactionIndex":"0x4c","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x51efedde07c47ae99371c25ae1474c669cc52b100f0ffda4be4936e2892b9331","s":"0x53f6f325d1da57dad6ad2cdd961fc67dfce395372dd18a7774337138b1e2dd9f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x7c9ef0fb0cb6c77a338310f8fa497f2af24dc03bc9e05fd5946c2096603127d9","input":"0x","nonce":"0x9c80","to":"0x6fda165e0d011eaa77f70e24bf515abf4338ea21","transactionIndex":"0x4d","value":"0xb2664919715400","v":"0x26","r":"0x8393b13618da6fa0a79851675d230d53f5e32db404f80ecbd319049cac7ebb7d","s":"0x5ffe6c3a035ac49c22e89b547030c2384896b6cf09a90a7de67114b15ec81f6d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8a6d742d1266639c3ff41ad8424d8e5632ed7cfda5795933f05b9c117868a9d9","input":"0x","nonce":"0x9c81","to":"0x2e4689b51bf43fdaf874f3baaec1b750ad15f45d","transactionIndex":"0x4e","value":"0x27ac67bbdac0400","v":"0x25","r":"0xd22d20eded3b91d1842bed217d4e6dcec8c1b560114963d8b2eee281b4686bb8","s":"0x15e26c42245398df1b6f64927c88081a9e692e18358e9d73b6f3c28da44dca63"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbae0db1e3b4f15e0dbeadeff006bc099f72c33cb642077d1825ec9e3966ec572","input":"0x","nonce":"0x9c82","to":"0xbd822e7b7db725c3bbfe7576e24d3c0354497981","transactionIndex":"0x4f","value":"0x17c1adfe0b47000","v":"0x26","r":"0xc0c0f50432bc3e6d02e68909742a0a344cc4f593b548915d5382f4a0899bd868","s":"0x76a0db87a98089f7d29830934bf1a42f6ba3e4ba558c86768f2e08ef8ba808f0"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x83b64144c19654f052676ba7c78771f7121d933fad2ae0be8e950d5b99e16f73","input":"0x","nonce":"0x9c83","to":"0x2d322adbb9984eb45d07e5c219e325099420183a","transactionIndex":"0x50","value":"0xb20840bd382800","v":"0x26","r":"0x3df40d99f3f47dd3b6d1be21e466f765d7b3f17cc8782b07542c7ceed3408057","s":"0xc0db1dee0f544135878b3fc6767b6034d3f6dccdb113a1195a781f234f91e6d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x2e630e16782c85a6046333c8d046004c60905a1509e56a9a3ef8d2a87ff39340","input":"0x","nonce":"0x9c84","to":"0xdba59dd839fb2d3535802e6d187b72c6476be686","transactionIndex":"0x51","value":"0x1203212e37ba400","v":"0x26","r":"0xd15f940513577217deb4921cd4875b55e5c236135c1dee2a161bd13bf489d4cc","s":"0x53ace39ee25fdf63c746c6084ef0b2e53b8f9a10b364704169453760a0e28124"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x95268414532c05cfed0aef91909f68b4416251cd21999e47857561557a33eb08","input":"0x","nonce":"0x9c85","to":"0x686dfcf430777442606254a0e36f4dad68ac9292","transactionIndex":"0x52","value":"0x360f3a05f77a400","v":"0x25","r":"0xcfdcb39b9d026e5265bf2373fbefc27633c97dd65865b0131ea353d971f78c7d","s":"0x5ee707a379ae0b4e7c2566a7034de41cc9e7fa6879db31498df02763a1217204"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb49e13713a8ccee95c78b26bdbc900872de90608b44789ef721910ec74b31f12","input":"0x","nonce":"0x9c86","to":"0x6c429bc1c51930f2c4b5e02dcf7c01e5fbab1df7","transactionIndex":"0x53","value":"0xb35229ba10b000","v":"0x25","r":"0x8afe1f6dd3247bbd388f02038524ae92c93f8a418e5e02ca6d4a0d1ef29fde49","s":"0x257449addbe86c06d81f31057f2a4c39a954110d90873ca184d4eccbbcd7776b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb109ba1e2415021fe64320fdb1ac4a130cdf38f1f59921f68aade8f47f23db3a","input":"0x","nonce":"0x9c87","to":"0x9b128e46a15545ef9656806155f940e3466308c5","transactionIndex":"0x54","value":"0xbe31ef6ebf4c00","v":"0x25","r":"0x5079c8212f9291b36a1d9052e6c04412925770ec63828dfdc07c7c17a3a90cef","s":"0x38ead0e006a6e4a7a9e4fe58710cb5b08d388d8fb3fda9195ac799c0e2ebdcb3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xcbb6fab536358150be07d80ebb21d2ae0cce0c8315276b837667ff8ba1c42d54","input":"0x","nonce":"0x9c88","to":"0x58cded315eb642a8806a0327a505dd04ab3e5774","transactionIndex":"0x55","value":"0xc4a234146d6000","v":"0x26","r":"0xde626c5dae253d07b126b37b53e43a2280c1de5fe5bab9dcd335f232dd1035be","s":"0x3beae86e6665767e70196ca3442a8119194150d855b7a5d710c22bbb2f45b8db"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe6e296227aff21dcee63357daaee930a262b8d3de5272889774a3ccc78bb09f5","input":"0x","nonce":"0x9c89","to":"0x55e425eb13f8f9d3ee84da9ef721223ce595f427","transactionIndex":"0x56","value":"0xc1a2d5e17dac00","v":"0x25","r":"0xe6fd8d422bd3fb8ce8c3c2f45f1bcd830ace8c3d7d583eb46ca3e2e319e5fa0d","s":"0x42f037accaf12c030392819efebc9614ea8ff3b950f6b35b85aebc1ab8b5dfa8"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbf934a74e1a949bf6630dbae24c0a5e1ac655f798914bbba2b276d756a8703ef","input":"0x","nonce":"0x9c8a","to":"0xa31fb325f638ce6f900d07159d036079ae7a1888","transactionIndex":"0x57","value":"0x17c1adfe0b47000","v":"0x26","r":"0x3afdbe081ebc912730ed377fed0917bf3a7512c6d12591262e02aaef583b15ce","s":"0x2d7f01ccc1a049ec0fc197980acc3dc80accd133edf4b1c2125c9a506a78c412"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x4f895c2f7db9d7977aa003a04448ef070b07e558366c9ef7fc4101f4c5d00f63","input":"0x","nonce":"0x9c8b","to":"0xb7cc039691cb2c51b3202dcec8833f7294adfe54","transactionIndex":"0x58","value":"0x15f98da41d1c800","v":"0x26","r":"0x1520c62dbc3689f64d70fee49ab384a7c98663396618135783dceced04949218","s":"0x5b833f924dd7a046400b82ea2954bec85b63ba7574e46c5301024331d5417150"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x89ef049ce110fd411ae6c8c54e2533d319187e595f5f3945122eaba4e9b427a0","input":"0x","nonce":"0x9c8c","to":"0x2687cd65def8af50e18390199f6e97b0ba72dc2d","transactionIndex":"0x59","value":"0xe4101efecde800","v":"0x26","r":"0xd3961e8f1a2e38c8d75418233e314019eebea31fd7a8cec038a9ab5b7255f857","s":"0x3b5747f6c422427c2353309982c9a625d5217d3d76e0990afc4cabf871cf39f9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x1f07df926060bc3230dff2458fc219b979f6477f3776d427da441d46bce8f95e","input":"0x","nonce":"0x9c8d","to":"0xf164395df8e000dd4a491be5111952280b2b223c","transactionIndex":"0x5a","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x38f3e7926c67197215a0cfead5022d8868c8b63d8845ac01970037b28f875f12","s":"0x429a6f8ee5d836ceee89dca0f7b0f320c46f565564ca751e14016ff25808fcda"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe335af1cfe6732b34515d2cabf4a00495620726620352378864ad80734e0570d","input":"0x","nonce":"0x9c8e","to":"0x7610640b90b17452501bf94fd8e8f37bc0adfe62","transactionIndex":"0x5b","value":"0x15e55d178169000","v":"0x25","r":"0x13d75120136fa3d8e604aad3b9de1ce1817508db8018677a982dc4e141e18f6f","s":"0x688869e08f498ba4aa3a701c6c15136e96f09aa2ce93e0b8e932074044ac95c8"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x541eb3a6b744879dc009ecc18f38854f587a48fc6c9d27bd71ecc05808a373a8","input":"0x","nonce":"0x9c8f","to":"0xb1a599d720d092dd00b53994ecbb30cf765dec36","transactionIndex":"0x5c","value":"0xc2542436fd6800","v":"0x25","r":"0x9df012b2523eb9f05084b0b215d65e4491afc3f1e526d77e08b35944b85d2cf","s":"0x644b5c2b1171871ad1f7b9a9a4d4273a08b26897f3cc45b9e325e2be48e73044"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xcb64bf354dc6953f8fefd125c52c6a28df664607d8705b51e412de57d61fc782","input":"0x","nonce":"0x9c90","to":"0x1559563f25677581d36d4e624473cbbf73e15180","transactionIndex":"0x5d","value":"0xc3d6fc66994000","v":"0x26","r":"0xad7031b60b01849774d08381af4a65a3dffde85eac5df96040f008bbc950cb6b","s":"0x44fb8a0a9b3d3f26d548ccaa209ddd3b24d1ba549bf60719e451ba780e0bfb29"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb5f62b55faaea308eb18733a19556e2730ec3e9f18f8ac6be15af6e46899837e","input":"0x","nonce":"0x9c91","to":"0x4d314bab18394b57c359639c876ec5ec6a377fb3","transactionIndex":"0x5e","value":"0x5b414595a77c000","v":"0x25","r":"0xf80db29fc81d5d80c120b363f2321b092de2e48bd2dd254a2de0c6e6b33bfea4","s":"0xf7fdabddeb455a59822caa8242f006b1f39235c8bea947fa1a98f04d15ab37e"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb7e77c3bc9ffce6c6657282147030007578f15fb0c2b68bf46946e04f381a22b","input":"0x","nonce":"0x9c92","to":"0xbe007fabe0abc3da8b05e1d6ea261056678b8a2b","transactionIndex":"0x5f","value":"0xd10ec777941000","v":"0x26","r":"0xedd33b9aafdbf64b01298fcb08376dec064cfe65d31ae2707d8ba14774b85bca","s":"0x57caf3b2edff6170a338583b5667f1bc83109bf89b774eb10c5ee19a35fcc81d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9de4222cf2a3f10d6fca1729ac7d1669ca981fa4a3a2da22cbfbd98b394d6707","input":"0x","nonce":"0x9c93","to":"0xc3f8a457c2653306e03141fe75a9877493dd7343","transactionIndex":"0x60","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x918dbce8ebfafe208ff78df2710e99f3c0f2112a60027787a0af8fb495d8454d","s":"0x52fa55ca6bbc1cd081edc5b99f4ff131c6166ef9c1752154b59683ba3235f4de"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xad0546ceafd2779a6749d6e2501eb69e291bafb0830dce469eec76cfea70a773","input":"0x","nonce":"0x9c94","to":"0xb769832eb660e512e07258bcc36a0dcb76efac35","transactionIndex":"0x61","value":"0xbfd66e5a367400","v":"0x26","r":"0xa453717ea557e0951f5ed4d1b1afbb9887cf4a5249782ab9cdca467d88e3b0ec","s":"0x5cb9307f135e689c1c5d6573d7f1eaa7517ebbf398673c5fd853716c7dc0092a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc9bbcc2bbf50c6222cf213528617fb13a490ee05581aa68313d206ea1519b2df","input":"0x","nonce":"0x9c95","to":"0x571eec232518d5bb640abaabb4a0dc90a9923fb6","transactionIndex":"0x62","value":"0x2992f07c93bc400","v":"0x25","r":"0xa04da77da585efc49ff19dfbb002379f48bbdc76fa7b7ca92b49c80eb89b951","s":"0xb1dcad3506d3095da8256d6516aeb0f08d28342e5721f85634ef796627b2a7c"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x39ab5625f2e3063484f3b8576f4f3e14c5002341f9c287df9b438e5d8fbd0060","input":"0x","nonce":"0x9c96","to":"0x9d34d6f0b5632fe1a5103eff1b051bcedb4ff55f","transactionIndex":"0x63","value":"0x14c9782ba97f000","v":"0x26","r":"0xe8e7a27dcb4295c3177c50a8516e72285bb27f4700508638060009e22efcafb0","s":"0x39733b86274675763eb8f8ea5015d6f37f220fe3bb86ba088428e9c639c4861c"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x160c2bd753685879936c491123d8ed1b6ddfb6c24fac1957a7d2ffc83228ff90","input":"0x","nonce":"0x9c97","to":"0xfe1d3a10df8ec413d60ddbc5f864372785b15a0a","transactionIndex":"0x64","value":"0xc3d6fc66994000","v":"0x25","r":"0xf4d4a11d1ac2380662544373f650b4501357b6938f46a8cc511498e6f9af2fc6","s":"0x5d79de1db6e91984fb9fd0afd231d9c218fca8565746b8bf562c5275c82633e2"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbc7636268fa7d2e2dbb0a55f27891941b8175ea87c0ddbe81e6c2af867279ec3","input":"0x","nonce":"0x9c98","to":"0xcd865711992c4ec65c6a160b53c89a7d6ac6ae7f","transactionIndex":"0x65","value":"0x31a272005eb3c00","v":"0x26","r":"0xecd2574b39a2a580e8d3d1471d76001cb926af5e644b6ce99625d5509b534471","s":"0x4e5ecf8ebdc96a1aacefee24f842f45d3a0e26104c75848c3a1a4eba1b1b97e2"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x937bbde3396f50bd58b228acdc6075099afe6abf9e4f1cf6ca6bcd70f5768f80","input":"0x","nonce":"0x9c99","to":"0x1a31a3cfd3572351a03e7b28a2c31560a918952a","transactionIndex":"0x66","value":"0xbfd66e5a367400","v":"0x26","r":"0xe26c33c48e8d86df5f1f518bf3d1b68b56c589afc6874836b2968881708b980e","s":"0x1979c6cf8c46b224b55e0018d1fafdf7fe8d8623cdd50b648a83b019ed0806e3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb03550a7b57e201b1a2fd1afb376c66e6bfe3425dd948b89d439849939899e57","input":"0x","nonce":"0x9c9a","to":"0xcc2171d4de600277075fe130e0d36ffefa99b5e7","transactionIndex":"0x67","value":"0xcda1be8c933400","v":"0x26","r":"0x1bfd0376436155b78ebaf2124d9d0acaab4dc2067814529978235d03f8bb5ab2","s":"0x54204e780711ae4c4ae1b7456280fb14973308bbb75e830986430f1f291bc53d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x99e6d8bc383e246a6a7a294135344f16346b53eb9fc228da27aff8118e99d4f6","input":"0x","nonce":"0x9c9b","to":"0x92b264dfe333e5f73122225c41cd73db8cff9337","transactionIndex":"0x68","value":"0x1cbed51d319ac00","v":"0x25","r":"0xbca9dda64074c1b01225e1a1bf5d2f6e54ac94ac9c014fa17987815f9dabf8a5","s":"0x7065c3e426f83910d6e4401c877c071ea94cc3e4393b2fa822d637ac83474348"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x1fe4bee972c52aaec26617e86fcf8758eebbbc98b952a8158247af139ed2b54a","input":"0x","nonce":"0x9c9c","to":"0x4ca85ac8e93bc77355db733f4111bb09c345091a","transactionIndex":"0x69","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x42eda4e90e20cba06037bc795dba4c76da79eb3e2bfdcb1bbc08287925816974","s":"0x5b10aa514cc2c1e3c517804ac123e38662ff1a1a67e47b840df5304c2a2af2f7"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x4597183867eeb0b2195d6d367dffa37c25aa46aff4436b7ba225bccbb3579c7c","input":"0x","nonce":"0x9c9d","to":"0x2b1f68abe6a29b3edd64ceb21ef29158e52590c0","transactionIndex":"0x6a","value":"0xc1da8171cc3000","v":"0x25","r":"0xb7b87b68455e7cb5eb9db18806aba977f6f939ac144bd569da37395d806900e9","s":"0x502a37059a0e7b96840e290676ce5942ecdb1a1aa25757fdd56d7f66976ebdc3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x0bed04a6609b66a5d8b6bd6ce40ef5325bc4c696aeb37776d4d83ec8e7ecd961","input":"0x","nonce":"0x9c9e","to":"0x7924e5578215cdff5f181b64da2927923af16260","transactionIndex":"0x6b","value":"0x14c9782ba97f000","v":"0x26","r":"0x572a3bc3e383ef8bff21c48de4073a88500771cb36b898fcb89dd84522def105","s":"0x7ad3f5a4329166326649743f6ed25a3b2f2556464e767dcb4c36dd837b059ce7"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x73c10857457e3f5c45895d9a77fb438b3421eb7c28c26789e2c9cf8151fb9cac","input":"0x","nonce":"0x9c9f","to":"0x0253cd09335b8df37e1c5473ec99a6d70eec1766","transactionIndex":"0x6c","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x3275a10bbe9666457ea5afc4d59e675b0144f76b98663145addd4bc799105e6e","s":"0x5568e0f28186411f3d70bbc4270ab0ab61c08019948350a918390c0e281e241a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb9eddc2db16ff61f58001642ca2a51c8ec95ebfe9e5b036421370077137e193c","input":"0x","nonce":"0x9ca0","to":"0x7651952fcb8ffdf86aa45ba15cc5b17900e2a43b","transactionIndex":"0x6d","value":"0x126409b8e091000","v":"0x25","r":"0xa5e27911e785f9a70a759a769c71e0dca6cf6bbeae4f57c3bdffedfa1bf07fe9","s":"0x301d8a3cc91d42a32377755b8f59a3cb98f6cac73bf437a125a9532aa8d48769"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xd31e51cf1dd441bb59f560208a1f623c8c46be73b64e05d4a502c24966ae2ecb","input":"0x","nonce":"0x9ca1","to":"0xd4f6efba0e8afac5070e2f212ea2399890c661af","transactionIndex":"0x6e","value":"0xbfd66e5a367400","v":"0x25","r":"0x25a991a9e975affade3700b25c8f643e0f5b2da33c080884489c0e9d08de74c4","s":"0x3059552205c70ae443d68470007e1df0ab8590f3bf8c3176a81ca0450a3d4779"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8dffae13ab7104649563acd462619eff57ed1c6aceff9b89aae020d377502113","input":"0x","nonce":"0x9ca2","to":"0xd0d6468dce409bab6c90ac104e43cbde0683ec0b","transactionIndex":"0x6f","value":"0xc3d6fc66994000","v":"0x26","r":"0x5f96592f3e82ca7b68650642d9db0f1ad1224a26341408e757c298b0360e83fd","s":"0x312df679b162ea5c7eeed6295bdb93362a03ffb3dcfb74c5012f9acfffc2b071"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x909401b08022a35b0e6bd1efd6ef2b9c3e29e29884f4358ec1047998e06462eb","input":"0x","nonce":"0x9ca3","to":"0xba8a931df397f5821766d764dfc1123a12725866","transactionIndex":"0x70","value":"0xb2664919715400","v":"0x25","r":"0x8703033f77bec9be225e4edaf8fd4c0067d1e94b4842f039bd872dda4b4f44a8","s":"0x2895e3d128915a86b138eadb90a669facd73fc1c0050ac7ee7091d212de08ed4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x58c48a7b652c7382cf7193760b16fed729c000668c5692e0d1185b7486c221ad","input":"0x","nonce":"0x9ca4","to":"0x4ee1bcaef4fbefa28184325e6a9c4a57d6c5bc83","transactionIndex":"0x71","value":"0xbca080a4a2e400","v":"0x26","r":"0x1d306f27cd242ed559942c8dc28da48f0d3aaa37e99c3ff64ddb3f58a7107779","s":"0x106bd74d4b7249b7c410e289892066d91e0da4b63581e2e9f93f40471bf8ed2b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8360665b9a5b6abeed5d63621ce4a22578aa3eb27090429b676db106de0297c1","input":"0x","nonce":"0x9ca5","to":"0x5d6290be073fcf27fd1affd5f7703feef07f3d5d","transactionIndex":"0x72","value":"0xbfd66e5a367400","v":"0x25","r":"0x665380256bac009ca3bd65e34d8829b417e9ad73e5b9994c875472b374becc07","s":"0x707772a8bae78c26f22f8375f34d277b43db9a1be118c3772e9cddbe76c2e31"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xba38bc44a84a1be2d3ef1b104d7d24b9531951587d8801f55b7e71f442ab303e","input":"0x","nonce":"0x9ca6","to":"0xae0a808e2a772a4302cd78aea2ddc3ba526c6ad5","transactionIndex":"0x73","value":"0xc3d6fc66994000","v":"0x25","r":"0xba3fd5e06b4460de11a18ed944efe58d89175295594d7130a2dda4c73b5f9f39","s":"0x20531064f3c4b9dfb9d7c2e08dedfd4ec187b0525a1ed5e965d748cdc29eb5cc"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9333f58acf1bc7e92224104f057671998592a1909cd5b3acb9c12ee92b325f0d","input":"0x","nonce":"0x9ca7","to":"0xd482e0fc8213cb979aee9f86dd488da365019e5a","transactionIndex":"0x74","value":"0xbb0aad48175000","v":"0x26","r":"0xeeb8f6c5dee495a379c25a2e6f7be0f4779f48df8a112dda804af184f128260f","s":"0x52f8b6b9a51711a16437ccb853c95dff6099b00c7b30a04661b6ccd24e8f1146"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x34f3c1e3163f4b91dbb9a07eb139a6128e11638c944c688064601c1acd5b0500","input":"0x","nonce":"0x9ca8","to":"0x6254be074cd9a548455bf7b852b4c37b1bfe3833","transactionIndex":"0x75","value":"0xb3d90a82e2a800","v":"0x25","r":"0x3722cdea2984b42025e756114fa881d09cc234b1832bbfe5736f1a7c560b408b","s":"0x282ee2ac69f52de76906ce7586d6d1ae74173dbcd0a24a99f80315d414bfa74f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe50993d20c4c2173666f7407fe8a2d51dd4568f55f938427c7383cb528d7d9e6","input":"0x","nonce":"0x9ca9","to":"0xb6e4350b195042a6e2d614aaf2f55c2a250b5d4a","transactionIndex":"0x76","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x57542388d21ed1659704be1021983b6dd7e8c9969f8a3ae1bfb672088fd26955","s":"0x23163ad0713433796a3590e73d4f1c2975b55684e725506f806a25ee715e1f2d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x6bbf3a2ff8d375155554f2393fa9146a543d0a2d989ee879840c5210d6d8af9e","input":"0x","nonce":"0x9caa","to":"0xcf56e5ed5ae72a3073947495960fa7132e54b3df","transactionIndex":"0x77","value":"0xd3057bf2e29400","v":"0x25","r":"0x6b183cf8cd9beedbeb0a9c6d665f422c3e02fcad2e6034a0e5dcf4efb35110a7","s":"0x135376a5a6bc6d5f902c0111f612546166674dc9ca7872b971f7243d046b5415"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x3d3397dc7750bef59af42dbe05cc0012b6155779f36d18e07bdebbe9503d4886","input":"0x","nonce":"0x9cab","to":"0x8de0498a27ba339552efdd739e9feb820059dce6","transactionIndex":"0x78","value":"0xb63eec35f82c00","v":"0x26","r":"0x58ba1a512c9aba3d9f34b170c2e4e111432c6008a553422484a762d4cf0ebecd","s":"0x12544bf2a888c125beb2a9301163294e3a7c041d3d2b109fcb9e4dc809d68614"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9ab6b22db7be7a6995a8c62b3b00a59ea441f62c56b9b3520a431f3c4555643d","input":"0x","nonce":"0x9cac","to":"0xe0344823f21a2e00f17a0afc808fd4c6e002750d","transactionIndex":"0x79","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x86cee2916626102013acf7ca7de60bac8d37b534664066a4a077454608527efe","s":"0x4012fa62f4bb99242ebca7a0bd15cbd8fcb3eaa3b23f7dc5a79900bb8cef9049"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x527d15925e495fe515e1e3367616577d7ec0744094d35bd9546827c33c0b5530","input":"0x","nonce":"0x9cad","to":"0xd4bba6144da7295055fb1b1d1dbec86da8b4d21c","transactionIndex":"0x7a","value":"0xea7b427a49ac00","v":"0x25","r":"0x67b6019a6422ed9ff8560ba76a46df47a0838139ad2db752682738753b6e84a0","s":"0x2711600ac97e3f070f9de07544b188b5875d14467025e981c02cff15bce86fd4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x4d3d5cbc698fce23a2ffa4eda0e151bc0e6ae5d98629c9b4b77234fa22a30a5e","input":"0x","nonce":"0x9cae","to":"0x54801393c02e07ed8c5aad855dfb1cbfc8c9a9ef","transactionIndex":"0x7b","value":"0xc3d6fc66994000","v":"0x26","r":"0x35daeb020d4dfd39721785c2d28591e902e53ae245eed0ecdbc25ac7472528e1","s":"0x28d959e8608cceaf0342bf71bf0332bab49c67ba9b76597a136f79caf1a05492"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xd0851fd1a3aafcd50ead7aa1e6dff1c9d2cd09ff4392264718d6d1b8ec027a26","input":"0x","nonce":"0x9caf","to":"0x2fb6665a77c8c6935aae38cc8cd63c79f4978f23","transactionIndex":"0x7c","value":"0x17c1adfe0b47000","v":"0x25","r":"0x9309016ed84c7aae11d7460539ef350906f7b3fe48a92be2571c9773873c86f2","s":"0x1b6dd64e9dc8701c39a17f705b04c81ff8ab46607bdc84c77c212cb293b74617"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x122580b9bf98702f5d63e9541a54dddfc3baca0e9856e2bdf8dcb0cef8209992","input":"0x","nonce":"0x9cb0","to":"0xe7b54f8793c8bb9b29e492ad6e4f8d6d5f5be164","transactionIndex":"0x7d","value":"0xc3d6fc66994000","v":"0x25","r":"0x2c2e7929bdecadb75e1bf53add116c441a11cdf535566f37a6adbdde5dfce143","s":"0x1c684ac9766eac8558f7064e346433bb80baacecf336938c4136e0558efaef64"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xae661bbfc2e410190d8a8adf3af712457502e0700dda717a2a22e7adf94317ed","input":"0x","nonce":"0x9cb1","to":"0xe05ccc1b7a0313fdcb79ff3eb0305e91d5c487a0","transactionIndex":"0x7e","value":"0x2b480f427177c00","v":"0x25","r":"0x6ebe9fd04f7d8a7ed086be355c8385ce99094cd822a42f4b710926c4a04c84e9","s":"0x38cd85fb70f0a9367ced78bf6eed59128ca755f8ab7d3c9a2766b85c6e81cd8a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x399efc768c069ba010a4dd3d6a522e4e215b4e6b183b82adb73bdda2b6ec52ce","input":"0x","nonce":"0x9cb2","to":"0x349510b999a5fda5db4780e2aaead90d1e5ccc50","transactionIndex":"0x7f","value":"0x2f835bfc168e000","v":"0x25","r":"0xd40338eba03278577e0952a6c4323cc678b0953e6a4a6915263562238279fddf","s":"0x180f76e6f04cf4ef6fd8d5cd76aeb38b190641ad858c28e3431b9844623a4c3a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x03c315f23d10b806d1ee3903c4c0ab5bc2648f81489f37e657134a0ebda47a36","input":"0x","nonce":"0x9cb3","to":"0x47871f0665a2e91aba71c73e13de5b11155c8cbe","transactionIndex":"0x80","value":"0x20aa4f2aaf22800","v":"0x25","r":"0x52d4ed029392502b17d06324a92946efc40933fcbf1a36e72ec7671daf11f35","s":"0x4b3b4a12743f4ada37757d363da59bf27c4eb9d923b36b379dd1dd47c3f13e05"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xaf5ba7e04bb64cb7b2f61d81261c6172507d26b18b42b30f49d43affbd8d23d8","input":"0x","nonce":"0x9cb4","to":"0xce260bc65ff5f6ea95efb3dcd5620f4591f5dec1","transactionIndex":"0x81","value":"0xc1da8171cc3000","v":"0x25","r":"0x8f60322824210fdc76f2c9f2d83b64a650ba21788f256da54dffb1278c1ab1c1","s":"0x298ab7cf17efc560d209a520a600f554d5971fa77238fe255b421ff187948e86"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x660d9a64e3c96e78622f870ec011091c3c7fd9fef664ec5573d65d2c0f89f3ef","input":"0x","nonce":"0x9cb5","to":"0x1749deae94e5fa3c9504ab2849168f335c4fffa7","transactionIndex":"0x82","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xa83f70d6054ac06aadb460225c6465d612bbcbc956d022e17b50bcc730f6012d","s":"0x1a66523c602ebe0a5f5bd0ef9c918155dfc17e32bab33f1182f19194f84de284"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc2cf524f088f4496a5731d36a0b6929759153ca770ebb77ec291d9ff27441d3c","input":"0x","nonce":"0x9cb6","to":"0x3bfe9da8c04e53b387196d30ef1b635ff6264bd0","transactionIndex":"0x83","value":"0xcc4e706bbfa800","v":"0x25","r":"0xf0cc09d24d5fdb64e9cb286e1c3ccbf3f110b3d4e110b192d9de42407d692600","s":"0x240ddd910ab5cc583ee199e92c4713db2f7dc9490b8d6d1b9333085b539d7526"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x744b645bf4ab7711762b1ec7a7eff192203f6944efb392038b4dc9c3a27c14f0","input":"0x","nonce":"0x9cb7","to":"0xf2ede79c5a212432ee3e966386e5a01611c79363","transactionIndex":"0x84","value":"0x2a606995ecbc400","v":"0x25","r":"0xf9e9b8cc015f0a903af9981191feb4b5ffccee7356367c20f4bb0d460cb6ece6","s":"0x1d08280e485e095bcc78f50986630abda306524446b1f43c9b3b4a4e5b4703a7"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xd068bf23a5d7c792e8b4ce6eeb5b19a6a12dfe5fa3e47bb264d8ea4c6149afc8","input":"0x","nonce":"0x9cb8","to":"0x84d12193cd5f827ac842f98c9a3ea8b5f01e6542","transactionIndex":"0x85","value":"0xc649ac5b14c400","v":"0x25","r":"0x67f9035e3dc6399c195e29e1cca206d6271e8817b78bc7ce8045e67fc21ba952","s":"0x74e7a387695d3a38eb1b213d5a4cad1e656af4a1a2e08d0cabc246b633f630d6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x7f61182b71012789a75dcc019c21907390108a669ce7ba70f95c7174970a1f5a","input":"0x","nonce":"0x9cb9","to":"0xda62fa9c85567310844408d4ed1af18b971b3d61","transactionIndex":"0x86","value":"0x14c9782ba97f000","v":"0x26","r":"0x82524dfc74b9f7ba43e164dee5ef1513e2ca9173e6813c7c26b08f0bb4137f7","s":"0x12ca085a43e5508497f9e8bd8c35307ebbffb3ca267a9cef2edb1c514419993e"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x61fed8d0284933c47e3d83dbf9809e94917087ef5db0343773a53d5dcc494b57","input":"0x","nonce":"0x9cba","to":"0xed63003b5b433e274b225e2669815941ec23a320","transactionIndex":"0x87","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x988fbda5dd633ce6c9848077b0defc7da98497328dadde7e836cab18d272fdd4","s":"0xa3d1c80b43be4d933156820e7e0eee5e720ddfbd96bd59f2f54a6fd7f2d2072"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc1ea753339019b98d452c9492e3df47ab9363513095d5f929daad42417b6f825","input":"0x","nonce":"0x9cbb","to":"0xda46a91896cd97e7c94924b8ddc2715554d1ea7c","transactionIndex":"0x88","value":"0xbe199b367fe000","v":"0x25","r":"0x7c5c5f220ebea15518f78e36be2d2a170d5a4a356a42cc562772e601deb14b6","s":"0x59217c69942162de414af122a0de01a1ec00bc9c03246c0530de3e15db91a73"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x999eb2b04f57d490da06645c9acb2f0cbea22ce3ab327f4a9636c61ecda5d598","input":"0x","nonce":"0x9cbc","to":"0x4df8fec170166dafb5600350c9947aa999647934","transactionIndex":"0x89","value":"0xc069c2969eb000","v":"0x25","r":"0xa8a89f485bc8d8f53856cc044d795424e4bfe33d5a5f840b1c3f37ec7ebef4b","s":"0x39e73c09306b3f47a8166abe6164f305ca88999df5b02b7cd0527849beacf002"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc711ac0e81667190af33ef264b76d3c7770699347543ff69cae7d9c6175d74da","input":"0x","nonce":"0x9cbd","to":"0xbd4f0ba5c8584b9ec978745f9a03db5784a08527","transactionIndex":"0x8a","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x6ecd6d48196853285f57103c76cc997c26b3ddfe19e26f3880565459d16ac5ed","s":"0x663e7698cf7d5bafb65cd1f2f8626758fccc1a30c47c9a80ff5cc37b5ae905b1"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xa04a3aaf82b481df7a09c053a6b8de58997f9f273b4990939ba0735c62c773d5","input":"0x","nonce":"0x9cbe","to":"0xead137868089c6354d4bd1339e8320729d68b57b","transactionIndex":"0x8b","value":"0xc3d6fc66994000","v":"0x26","r":"0xc6208f84be9cdff67d2556cc6b410165fbb6882994d7d617dda95254ed020260","s":"0x30da6485220fb714888736a77bacb0ac87137748bfee53a901dd49f88e40dad"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x95608d38b8b00bc8b9426727f856eadcc7e705f784f4d3f48ae29dab2e888527","input":"0x","nonce":"0x9cbf","to":"0x39647d3170161f7d338914206f6d58d13798b505","transactionIndex":"0x8c","value":"0xbfd66e5a367400","v":"0x26","r":"0x1a46be403068d8143d02a852fabdfa3770f18c800a929fa4a01d565b34d28657","s":"0x1b136a2d0eea449ad8c746343c5d1d847d093665064f6613825df371dd4773f5"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x00e2d1d6e88dace86c8437fd412997d09a16ed8e782dd86e857c9fea42e22ab4","input":"0x","nonce":"0x9cc0","to":"0xac48389a295b51028822a6962ac5b426bc452a34","transactionIndex":"0x8d","value":"0xc3d6fc66994000","v":"0x25","r":"0x738ef925228e34f3c3d84f1bf731f406fdf88281f2ee392ab86373327ea3ed1b","s":"0x5600337bf5efaf09ff42730158087f1180c40c36fd2961ed2c94ff45e38725b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x2ffbee15977867989ab6023d600214a10810269c270c1a26c758aa3a152af8b4","input":"0x","nonce":"0x9cc1","to":"0x257a3600c0e58fc720cd34bdf13ea61ad38a743d","transactionIndex":"0x8e","value":"0x3b6432fb1c31800","v":"0x26","r":"0x5f57524a2a89ec1652fca3a9f72bce25904d2acaabf1e660c0da25592cdfe43a","s":"0x12707d6a77a4e179f99904fa282bd5e4a0d535bf98a097c4a2d72b455bbb5de0"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x970db809f14039e6b35adf1519596cfa20f60fcca7637b822b04c8c7d5f8ab94","input":"0x","nonce":"0x9cc2","to":"0xf3dcd496198ebab1411ca134792304f895a19eaa","transactionIndex":"0x8f","value":"0xb5d019cc00e800","v":"0x25","r":"0xb5d199c236bc60b3535928ff849cb95087b56e075e2ee663f4800f01235d542e","s":"0x4460e24e3729d10d797f4be88ebbef94890b386c550f96e043b28653d1d1ec6d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x5e5903f0fc43e2be2bc343d9e89d8f0ba621922dc4b6a4ac82e0704ee11f4905","input":"0x","nonce":"0x9cc3","to":"0xa6572c15100a418abd29ea3217b051954e5b48ce","transactionIndex":"0x90","value":"0xfbd1cd91dc2800","v":"0x25","r":"0x288fbc105e6886f096d102d1dc96f90c32016109007fb7680bff77ffc0400019","s":"0x306024b2a455c39222088d37b3569044b39cc2d600c2738e57eda44851b2a00c"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xfc0a931a740e71774ecc63e0b764e4c9d0b4f836d7f00ae4d0ae28017099a55b","input":"0x","nonce":"0x9cc4","to":"0xfbe3eaa8fbe8dbd66fcd449c99511c0a57c591fe","transactionIndex":"0x91","value":"0xb482a4c50b0800","v":"0x26","r":"0xef378b58c91bed44c7ced17f4c36ff225e78105169cf2a82bcfcd16a142a71df","s":"0x26881c33faec172f7fe83fd7cdd026fd12573f88c16a17aa5e78f5e3f6ac0506"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x4231bb2bec57016216b4e6025dbf126565119c2d168ede494d90a7f1d382e873","input":"0x","nonce":"0x9cc5","to":"0x9b7990106b63911055a652a2026cce6d972db134","transactionIndex":"0x92","value":"0xc3d6fc66994000","v":"0x26","r":"0x1c5f1ac94cc55c5e563100eac213a43ea80c87d6184da054c3521f6fe923b14c","s":"0x54f018e4f182cacd9ecacbe446b23b928beb6171deb28e0b2c8b8ed1e1a710a3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x726daaafbf1ba791f50cce8752e9bf1a6929fe47e54ac1b93aa79222ac7b1680","input":"0x","nonce":"0x9cc6","to":"0x7bddda613c69dc409d67a5e7f922850b95e027ee","transactionIndex":"0x93","value":"0xfcc510c832b400","v":"0x25","r":"0x8ea0986a9fc06f2855011e7fdbd2d5aed22ed88ce7e7b77a034e7c877cb897f7","s":"0x624cd5c8a3140f96dc40a83f56dddbdf9fe84b9b1d557263ac5f6b251d30ed82"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xd1cc0903afdd4a618d7df56324428a98a9b9582bfb254173ed064e6f649020c3","input":"0x","nonce":"0x9cc7","to":"0xa1fa1c9cc2681f806fe184e4f7283fb3080bee60","transactionIndex":"0x94","value":"0x2e6ad7727d09000","v":"0x25","r":"0x510a0c635065b30bbec14934a7ed8d799a6eff849d9fed17688be1bd78fd4e2c","s":"0x648bbea70e0e648a4179e0d3e889f7a26baae54e85403b60b07a2af6edfab618"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x323d707d53a05ec3db824e36ec43814b3bd35e49a084dbd6a3ce4f777f0a1a56","input":"0x","nonce":"0x9cc8","to":"0x39728384467996ec57dcdef0cf4982c82e751885","transactionIndex":"0x95","value":"0xb48cc1d8b16800","v":"0x26","r":"0x621c9fdfbd1496173119f38f3030d3b5eefda05c302a34ef76e08704ce3416c","s":"0x2c5f7eadf8a68d1d4be38db5ff9ef93cddb81722196a472f1348f28d852424d7"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x77e76f2309ef91cd2366417b36a430b6a3c485ce48dc3814fc94bdcd34b029c8","input":"0x","nonce":"0x9cc9","to":"0xd4da32ade44649a93b7b08ef193d981dac0f5750","transactionIndex":"0x96","value":"0xeacc67a0b1d400","v":"0x26","r":"0xc536f136181fed929f24ace9936b185b08a412bfa944d7d86b0810f748baf04c","s":"0x6b06d0a6444b72eeaec10b551d126594ce20c0fd9e7bc9ee13c2385673d9bbaa"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc88bfdf60759e31503e65a53cd66efb3f0fc37720aded93ee2c5c1c45a1119d7","input":"0x","nonce":"0x9cca","to":"0x635611df213c557d53afa326effaa65d4ea0ef04","transactionIndex":"0x97","value":"0xbe0d6ff05a3800","v":"0x26","r":"0xcec675c38b42f9557c97581c8c4488619243e3f8a4f1f644b3dd08b900a9e440","s":"0x1821058a9a2ec71f10ff33189005f8545ed003a1d8b2e0f06cb74afba8ca3b61"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xec991c9d8160e0a0a8c8427559f6dbcf6714b472e7ce296be5d21f9c0f904336","input":"0x","nonce":"0x9ccb","to":"0x11e55784679b3c232c089277bcf10e80f1cbadf0","transactionIndex":"0x98","value":"0xbe0d6ff05a3800","v":"0x26","r":"0xbba064582085abd6bb0c35fd2e1c3160ac095d0ddaa0c44f415049d218f63d8","s":"0x5ede010809dd5e0efe1455814e1bf20b108a445afd3d8d7e8ccdb77af513e8e"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x621a8230b5080228901854d87058a2d00475d0d4c40787249c51f325a099ca2a","input":"0x","nonce":"0x9ccc","to":"0x24ad36f1264980e4c0cf4f8f3cae33c22681f5fc","transactionIndex":"0x99","value":"0xe13ab79a2d8c00","v":"0x26","r":"0xa74a4e20cdaa096a62e344062d9178ff63ce2f7788eba0dad142905545f49209","s":"0xe42d9884686d6b933753ca48c3f41f0afd1fa0d46058bed61a80b89f0e38033"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xd7bb8fcb3c156badf23c8cd7e51fc3eecad18e01c9116a3a908b4c3619c8de11","input":"0x","nonce":"0x9ccd","to":"0x3bd4147e2843e22a404b3a7ec4e623dcc1d03e2c","transactionIndex":"0x9a","value":"0xc3d6fc66994000","v":"0x26","r":"0xe39c6c476a58562df02ef7a65c0fe91fa1b160461d58fad3dc3e78773ecb209e","s":"0x3918944fcbb70032d45ce38ae1b8433f21acdfd2d8e8cf254860d82bda5cac6f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8cc27b7bab23324ddcc94badd25686dc5b4fc6a6d5dc5e8621a53928f7694154","input":"0x","nonce":"0x9cce","to":"0x539be33e02a71c2794b473ffd7d93457133bd53c","transactionIndex":"0x9b","value":"0x2b97e1c95848000","v":"0x26","r":"0x4e3192b3f87e0ca5c4a0e88d7586d1f82e14aea5afd34216edf5d237a5e1ddeb","s":"0x44be3d194141d488ac5be4e6ee28f8220b745828a8c295419592e7f4ac9108e3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8b8d69a1253996f85ffc76260e1e24440c0aeb426f8a84261c33a5bd325922df","input":"0x","nonce":"0x9ccf","to":"0x895aec706916932f6ff92f396b822a7b742f8894","transactionIndex":"0x9c","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x73220c3777d9143003dea0505379d52edd2b0def10229d662daed56b524187ae","s":"0x1b4962a36536e15098f5cf2a0de19b6235b0417306a0fb0eedbe449a5d35b776"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbfc34a1bbf3f08c83dbfe4f831ef8748d517a4bf8fd329e726cf42fa579cb4cb","input":"0x","nonce":"0x9cd0","to":"0x08fa1cf2fd7584a60e036d28aa1f15e428ead213","transactionIndex":"0x9d","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x8d382c30c2a6b5d163ccf772aa01c5783ab82f9136130446649eafb4e96ddfc0","s":"0x4ce80fdc02b364a26b565a8dfecb12a7245898a21d66591b77a52d4a688583f6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x0fbc84a0583a6bffd51e6eedf56ca022923632aef0e82b9dd542d7adc5d61791","input":"0x","nonce":"0x9cd1","to":"0x906df0ac2b8e313a423698601881cd7019daf577","transactionIndex":"0x9e","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x31f4781e47379574227e2a230ae927e83a55d773ab4cffcc91c0e5608b2c6bfe","s":"0x174d3e978fba0bd7bb4ebd1f7fad798c402b684995f8ec44b46af843ffa5b5b4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe3314f9fdda1e58fb733b7931387e789b56d36c11855a815286417dab541e1be","input":"0x","nonce":"0x9cd2","to":"0x8e88bb62681f28a830d237fd023f2f2d20e7c04d","transactionIndex":"0x9f","value":"0xd28720c9962000","v":"0x25","r":"0xafe02a7c2b2699acfd9c933be9253453c7abca1dfc380dae2969e7ae45c1f8df","s":"0xa0e16b9d8eb149deaa599d6eeb952fb2a7494ddb7047c93babd582eb23e14ea"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x755a581c3a6846514c20e1ae3edd96a0867a2861256197a37ee5bdeddb5d2e69","input":"0x","nonce":"0x9cd3","to":"0x33269065d17f426432be4bfbb773debb4c96f1c8","transactionIndex":"0xa0","value":"0xc3d6fc66994000","v":"0x26","r":"0x196ab468529ac624cdcdee3722add7003460ff30d8fe7acf46e33d20bceecc06","s":"0x71a4036e59d768bd4d343f9477d3190cbc83b402a5ecd8d416a3b616fedbbea"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9df7142ec0c5ee2ab46290936e726a940e445106d6f05be08a3765178cc93b86","input":"0x","nonce":"0x9cd4","to":"0xf957e85e2418b0cb016f61b94e77ce0acc269c50","transactionIndex":"0xa1","value":"0xbca080a4a2e400","v":"0x25","r":"0xfa8205bf60de23ff80b8633931644e68b824a0785f393d565a5da518a1c2630","s":"0x538220e9adeb78c3fe3c4c96936e660a9fd1d1452e87729809cf254a339526d1"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x1730ed3d9f3a10b52de777e0e122a302399da8c1bd6d5da9d9bfa86ee2f89ca9","input":"0x","nonce":"0x9cd5","to":"0x3cd376f5b979e46f0cb5b68c3902860ae43ce85f","transactionIndex":"0xa2","value":"0xe4101efecde800","v":"0x25","r":"0xea5079eb2952368693662d052a2f8f0ef43a9febcd18a85b33491d3b82c93090","s":"0x7698917e0c0c3e64b15da00503d507a6f8b9dd86806e16e38bb16f6aed4f02ca"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x288d87d47b19ba2e65a60fe5e5c90da5d363209d7969057c198583a15bb305af","input":"0x","nonce":"0x9cd6","to":"0x1b2fd12e8b9abf91d99991dad4d9a306765c0367","transactionIndex":"0xa3","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x82bc034aa4e4ee35e3218f0dae7cc8373ffa45acc115d677ca788b716fe6426f","s":"0x3c8be8b725ea4f35d0afc236baa4b2aad175c41ce7b0093a15fdfd77d379d18c"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc7dd7fcb098b82b800dc16b3532196c89c3b0faddabdfdae739da5c7c72f3409","input":"0x","nonce":"0x9cd7","to":"0x94e0323df94c4065979c1a421479d08d8df1fa1e","transactionIndex":"0xa4","value":"0xb5bd33937c3000","v":"0x26","r":"0xcf456d759f0cad5e1fc14c1ee8c3d01a6d406684d59752a549717eaa2e9207b1","s":"0x14efaef72e72e1c8198efd2bb11087af1d3b0f4100cea3fca248dad012a405c2"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x2145c573f84f33f6c003ccf1eaf9f84c9c0601b5fd5a5e8382e8c1757828b14d","input":"0x","nonce":"0x9cd8","to":"0x7bf32bd578ba355bf700811e599247e810618ee6","transactionIndex":"0xa5","value":"0xc65e071b07fc00","v":"0x25","r":"0xe1b492da8fad24cfd7d349294477e0fad66921bc91623152fc06409de2fb3cca","s":"0x6b16cd9a28dac6af29e3c143ec361d576cddcc8c71eac0c4481618614c62ad57"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x58611b2610635a8b76df6f7e605ff0702df017348abd2238782a3359cb71dcfc","input":"0x","nonce":"0x9cd9","to":"0x2bd7aea169058a604d456297373eb84f5a34cf04","transactionIndex":"0xa6","value":"0x1db2197d8e18c00","v":"0x26","r":"0x891409b0f022fd802e451215ae2ee96c81dc06229cdbd05ddcb9939da5ecd579","s":"0x68f48717051b13bfb8578afe51c449f31a3bdde25ab3ad83b28d8cfdb4611f6d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x87c02b06f25d71f35374a271bb60fe2f99a79af6508d9e33aeec498ae434f73f","input":"0x","nonce":"0x9cda","to":"0x1655649294a57e5c11172c8ab523eda86e4fd1af","transactionIndex":"0xa7","value":"0xc3d6fc66994000","v":"0x25","r":"0xd80e0eaba17f95a944c5b658477975f19c28ac94fb8b9fa2566f3b38f603474c","s":"0x1580339fe9298d464f58e8c4fea9389f7006ca82b20c930b8909b75279c25e9d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x2b3c06aa279ab80455f276671a61a838fdf05b76a54a8818fa64cf95c4490b36","input":"0x","nonce":"0x9cdb","to":"0xcd3a553544775d8611e698467795f358bd7fe55f","transactionIndex":"0xa8","value":"0x11ba73f98f3ac00","v":"0x25","r":"0x1dbfd861141e35072522bda3c1219194eb01c0e330c89b6022ec730ac93dcc31","s":"0x5af83895a635f553e3b9c82a798a7d53a5a3a86488a26fb27737a33264ac9f24"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x56004a943b7e36b67e741870b1890849c34990d048a0a455e808cb132540d496","input":"0x","nonce":"0x9cdc","to":"0x56fc63ad1fdff5630f17543342af12d0aa15d247","transactionIndex":"0xa9","value":"0x154e819e545b400","v":"0x25","r":"0x377d06a741b2450b091d5128e18b1ae4c760ba5207e8d9efbfc6e774b1cf60b8","s":"0x4f0083b5968aefbb5acefd1b338180f8b1004ff1d6c913d029c66432ec007659"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xa29176cca49a109d53efa403efc3c7b35ba2a1b195484f8c05e69b849b894a8a","input":"0x","nonce":"0x9cdd","to":"0x297c6ab093a5e9c17a19bd83005e309aa6bf90fd","transactionIndex":"0xaa","value":"0xbec3e418240c00","v":"0x25","r":"0x511df109f77d1b9d2c7011b0cc8a8bba940abbdc53890544d45beff6c3a61d06","s":"0x11d11e39276e64593c4275673271f41c650c423cdec21468f6309c7c82fdf886"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x1cd5a9fd79b22626d1df97c78709f4db9abe62157196a34ac537c59280490fe9","input":"0x","nonce":"0x9cde","to":"0x287ff03eb0ab5dab611ee1e8e7808289cf122197","transactionIndex":"0xab","value":"0x17186bc5e484400","v":"0x26","r":"0xfb6464f449ed3133bfab98300f69a9af9c2fcfcf70348f4a3cb804e9ea668abe","s":"0x697002a0151af289d5bc4a5b42dd810d34e456ca4ced24b882ad7ab084785f6b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x00c308e3e62fc3b58f7d7702e3882d6d2aeb809859e4487e8fa997943e7a0bb2","input":"0x","nonce":"0x9cdf","to":"0xa85a7429620085477373ccc651ce6aa411c610e7","transactionIndex":"0xac","value":"0xc3d6fc66994000","v":"0x25","r":"0xbbf0e35e491aee18fbb86d3710083e914cc858268a6af2d16426bf7ccb2fd973","s":"0x38a6b8278e842d9223bb24cbe7d32ac4cef3b83cbe567c9c8ba257bf2a38ddd3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xaa0bc5f611f5828d51be4888401de4557a173262078eb6f11315a917fb6c2ebd","input":"0x","nonce":"0x9ce0","to":"0x3f18f9a66a30cbe9d6c9b02ec54254057eacc43b","transactionIndex":"0xad","value":"0x185af0237b74c00","v":"0x26","r":"0x22f3ba4c1b250346e58fce9f135541005c440aef5636ad99bb831fdc64c59be4","s":"0x60978c1e9808dad73a541cf557de560135634d090ba229bebf0524b28b3ffc7d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xd2a4d7e6549ce0578679a0d11d2d2b5f2c4f64172951362739f9b16903e82621","input":"0x","nonce":"0x9ce1","to":"0xa0fd5398b2102ea03918a547cfc58a1fbf4c2403","transactionIndex":"0xae","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x6055a4f416f5e818f9918bea1eaef0a9fe14a3661149a12daae0f48ee88d0998","s":"0x4b03acb5deb9c71ca143971abd748e935db2b76ad8430c8a3cbb2c757ff8fadc"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb42f3a400da89e618a4c4d35f0ed6153bfad69d3346909bd88ee8171d5be5d4a","input":"0x","nonce":"0x9ce2","to":"0xcefce92fb15f3164268589b706191c8362601e97","transactionIndex":"0xaf","value":"0x1db2197d8e18c00","v":"0x25","r":"0xd22d3e17926de80a691c83667373b97e88753d8507b3f61764b494b624ff0e92","s":"0x2c2406f7bcc907e877d2145b1b29ce4b818d14e97d37d2c6dcf0271b22d26af7"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x1e8bcea74e6ce6b5ed1c81c6fc9882e0488b4e82614cddb5fad905544d434fca","input":"0x","nonce":"0x9ce3","to":"0x724ac56002fa96bb4476838cee9c22621d392e11","transactionIndex":"0xb0","value":"0xe10d49b62be000","v":"0x26","r":"0x3dd9c54a927146032bb7d6104b7790467ce1c6441524020ed704acf458d58887","s":"0x4ddf7517d33b421d07605d2939c1e3a0a80a10b46ae21ea0e717f23700376112"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x217fe1e5d79996d4d3c2f384a516f58fbc4aa5618ed37be8d8176e1318e4bd2b","input":"0x","nonce":"0x9ce4","to":"0x211544a96613f246545b0b8308ad688697e02b4b","transactionIndex":"0xb1","value":"0xbe0d6ff05a3800","v":"0x26","r":"0xe7e43e38fd4c5ac224564611b60dc13ff3b6834ca9210954033a778a744e8a35","s":"0x2e29744b11609e3758cf7f0486448b82f89296114af13a39e14a573ea491f769"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x1ee443f2fe6e52c762b7e3d305d77c427ebd30cee71c465da6f199f53e37b5a1","input":"0x","nonce":"0x9ce5","to":"0x3a10cba0ec57be6d905e3ae2a3d446b1e2b6f8c3","transactionIndex":"0xb2","value":"0xc2cdc6fc2ea000","v":"0x25","r":"0x17a76b0755c0b70ed372cf66f081d4ca093069d3f6b0b6b01d8b0e30a2b4e80e","s":"0x3f46b120b112c7a3688d51e4cb8712ed64776d7ffbc2d0ec63fc9d3cd07065e2"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x4dbf985934569c076b2f6190838817453a990ae27aba71e59a4cef7f7d8de7c9","input":"0x","nonce":"0x9ce6","to":"0x13eedb523e8e5c84afade1a43b8a4e447d417c06","transactionIndex":"0xb3","value":"0xbfd66e5a367400","v":"0x25","r":"0x213e26c9232cf2b74adeafb0e055aa261c66cc014d34d0fce46a581c60788eee","s":"0x21a635177917aeee4653bfb94d44db6b218b75009c62f1ea882fea1fc35af5a4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xec9bb7e6c141a37985ab43588ed88f7969395614615636d03c1b79ed7ebe5e59","input":"0x","nonce":"0x9ce7","to":"0xff509eaf1c3cf5ebfdd485fd46ef3122ab080768","transactionIndex":"0xb4","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xba1b67a6465f30389cfa278c492d906b1a122fc7ac4a861719402a6d32b21ed0","s":"0x3116dae25a6df9bb99297ecb492c10dcf5bc87ebf09cd43892f9974eb645fe59"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x1408a4b31b8be29ad4955109cab7bb2caeed3d07abb7477cc5c2e102aa16dc00","input":"0x","nonce":"0x9ce8","to":"0x9ceb693dbc8d0e83b281dc9f2f0c9fbc80cd2179","transactionIndex":"0xb5","value":"0x10488f2b8489c00","v":"0x26","r":"0x94a445991efb25f3f0f172c75af1ab84cd698302b658c7ac1ad1d92e165072e5","s":"0x5a2ba979d90c2f4d78d39b903c88be1859fb22d2edb1275683dcbb500ff0b9d5"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x860d308e608ed19833ff274428e2a9718afcbb9e599bcf7d5b29846b77f938c3","input":"0x","nonce":"0x9ce9","to":"0x18cd86558de106863e994c35a5c63bad30e23838","transactionIndex":"0xb6","value":"0xb2664919715400","v":"0x25","r":"0x769a58a1d432a1caf7b847257659d5f9e90af72db57035a42c64d268ea98a3c9","s":"0xa88b914c5243ceecae1d96273f5c04b5add4e0688b1f7b355a28e270e0747ab"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe9d76862e1bc46fa061bb8d1598c659038ca0c1c621c17ccad338c989dab12d0","input":"0x","nonce":"0x9cea","to":"0xc13c2d8ba7889fab62d820722b2123a13b26e4c2","transactionIndex":"0xb7","value":"0x17c1adfe0b47000","v":"0x25","r":"0x1d31fcf986b4464ea69ebf1ef99c90aa34f8bdd254cfeb1b6e3f62a55a026ecb","s":"0x19461dc3be2733c3ea1319232d8d2247aafbe43dd8f7e898f235f1c065e6b56e"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x7f816b4793eccbba701e79f0e1aff842515eac816e9984609bb6beb37a42040c","input":"0x","nonce":"0x9ceb","to":"0x845878661700257c0b2b51028272edcbfdd4d0a2","transactionIndex":"0xb8","value":"0x1524b1cfcc2e400","v":"0x25","r":"0x2ed8c352f733813b45fec2a7f4454294cff0e937e0e79a3cc69c1381bcbda3cc","s":"0x44a26812b96e80f40823db93ab2e595f4e317c324b08c92e8b66f9a9cfccab4d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xaf7d3927d7434976786fcef6700fd0ffab006d66508f52d48e0d771453c6d662","input":"0x","nonce":"0x9cec","to":"0xbace08e3c0c1c2f232d83ac08eb506d4528d879d","transactionIndex":"0xb9","value":"0xc223c19fe34800","v":"0x25","r":"0xa9d9eb89ed7f59e74199d6d2520911a726222e6f9874d52be5bd189d9a199df6","s":"0x3b17a05d1304b7219c3a5c09de56979b03fab9f77e7bab3cfb6c9d6bd770abf1"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x06e15c18ef71316b4fcd19ae69a0bc4a78de770e27b18059901136122a9c4e03","input":"0x","nonce":"0x9ced","to":"0x33bfeb8ae567ce99992a353463819f7fc6735d8b","transactionIndex":"0xba","value":"0xbfd66e5a367400","v":"0x26","r":"0x641c4ce339ba76bf21a3d1a629de3a1162b9ca5ca8564eb1bc38608c2eadc0f8","s":"0x637b595c9180335cd72ceab2a6ee5fd489b6ef201f65906cbfcbd755fa3794d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x1ba46c696e1030964f9824bb8ee284d1ff6254ee5404170b9421195ab141c7b2","input":"0x","nonce":"0x9cee","to":"0x34debcfd3992a938f17b58585ad9f5d73a673fd9","transactionIndex":"0xbb","value":"0xc3d6fc66994000","v":"0x25","r":"0xeadc532404bd692779019e4e2cb6dca4c38ca2075661984595b91b18fdd196c4","s":"0x5689b7383296d9233b98af8f422a67c4ca1a7c2e6d286575e6b889f38829b9a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb9487d0a7f752637586666f40fa99896ccccc2803c47cf003333c09275046113","input":"0x","nonce":"0x9cef","to":"0x4e205689f178a5903422ab4fd6410b435a82b165","transactionIndex":"0xbc","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xcc38dca840bd2912df3667aeccfe3711a98420eecf41ca3c14e61f525f191ce3","s":"0x2d469cbb6a1fc81854cf1d976c1653fdbf3ca79bdcb28b8cdb84611f3874728a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xce0293178b71291de5d02b8124f1c252f4018c1d55768dcbbf193f7d361c53a2","input":"0x","nonce":"0x9cf0","to":"0x03f4c3ac41b38e8d9f349e675d0fb4c509b522db","transactionIndex":"0xbd","value":"0x2992f07c93bc400","v":"0x25","r":"0x9eeec756163c4b7c1e73fdb0b4edb4808d325045f47eec192d5097034ebef0d8","s":"0x73102b81a6f71f09fdb6c1931ff817f2ed984c3a9b1d22f84913606f80bc2ed5"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x2cd24cbb022a9bc0352e4c532d939c48ed3f71d644ee841f816fce064f5c2b70","input":"0x","nonce":"0x9cf1","to":"0x0a57963ddfa8cc90383cef7f06fc6e7ab0b35d22","transactionIndex":"0xbe","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x10f8c7721ca343a0cc32e711538ad4eb3d37ba56fab12be5c1f8894aef67a406","s":"0x28f65ad322f0d0a1d381da1053bac2032a392118ff7f5eb9608eb8c6abbfadda"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc3cc47c5c88b194f48aa0d8bec7d2c9ab31dc4e81e7380fc99942b9af503e6f2","input":"0x","nonce":"0x9cf2","to":"0xc6bd787851fc8eb27e9b0328b570549663877735","transactionIndex":"0xbf","value":"0xbfd66e5a367400","v":"0x26","r":"0x3e9d7f4fe67506178fff36ddc6423fb32c489b874210ec4e28882aabc3f3cc75","s":"0x7b0bb7cea70dcae0f136e052d6608062ba7bf41d83e245f2ef6e722e52b469bf"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x7cea8c95bee7eb2189dbb6d4444bbab4784c1494336ded6c8d1e761f9b94d618","input":"0x","nonce":"0x9cf3","to":"0x13726a3c3fde08d00532e221957004ff6d1342d3","transactionIndex":"0xc0","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x8a9f17141816d27034ad606ef936ca7c566bba5301cef78511cee9ef5e428d1b","s":"0x21a40f36f9bdf2c4a57f0dfe12ac4d5fbbf114e0188067e84d905f313a847253"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x089ba7df9163e818675a85e53e4236e543c16994423ad1b64a81f43c37b9005b","input":"0x","nonce":"0x9cf4","to":"0x8773379bb3de3de7fe976122cdbdd801f55e4820","transactionIndex":"0xc1","value":"0x187adf8cd328000","v":"0x26","r":"0xa488b0f12d31783b85845bcfc5b1b4ba5ffcfe736acb1f9d35444d1b3905b1b6","s":"0x6a8086dd57efbdc84bf54322738de8faa9ba607f4042ff7dab2c0e267bfb08dc"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb66b54b00b9fcf3c61267c7d0b1762e403bf6f409a8e7275d84a0994946752da","input":"0x","nonce":"0x9cf5","to":"0x78d53308e6ad14799789d7558ce78c73827fb780","transactionIndex":"0xc2","value":"0xbca080a4a2e400","v":"0x25","r":"0xd59825ea762c091be2f0717d1e049bf4a0b818c657d358ac04991c1680d720d2","s":"0x639e1beef12560bc313b2454615a38d84aca04671f5d41979b363cb18852f0f6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x71641cb80e0f1f39ad689acf6e56a429f1c82d7ce64694f30636cc61c98ec174","input":"0x","nonce":"0x9cf6","to":"0x4d73cb2b71fa1f7e5e63a7ab58967cb92bf4b921","transactionIndex":"0xc3","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xbb686da884114b60ecc2ebb307391098cbb273ee4b92d13c1ef7696a8bce3fea","s":"0x19d16886c84b1fcfc7b81ba07c05a57efb42438c410217268d3f4f12deb1a65e"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x78d7967c296e433208d48b24a9f9332a38fd0b18781881b893c6eb2c5dd4a570","input":"0x","nonce":"0x9cf7","to":"0xfc9481332ace0c3a7ec57bf0cd4bd39fa115eceb","transactionIndex":"0xc4","value":"0xb731e73ede1c00","v":"0x25","r":"0xfcaad74772d1a076f8188b4a6157a898e0d85670c71cdd842d151aa281b0a3ee","s":"0x32ff5cd65b7379190f099ae6cf86ec0ee383d3ecef36f661d013928676a7d216"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x29f864a1bedabb6457faa0a7fbfb103dd6dc01b7a0ca0be7b1bbec5f93044f4e","input":"0x","nonce":"0x9cf8","to":"0x654240e37aa1beb5b40a18bb9cc69334b3a56175","transactionIndex":"0xc5","value":"0x15064943c09e800","v":"0x25","r":"0xe3ebe65dc975500e1f4743ceb3ae145b8326e72d5668ac8f0db9b65e0c8e9977","s":"0x6b7f1ecf321444dc3100aa1e3af67f4620853b6d3555cca6d44e5b51a9a3fd6d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb1293a984151655a0dcc5ab9059b8276e3f83eed10c0ccbfe4884c318935f106","input":"0x","nonce":"0x9cf9","to":"0xbe5cd7c23c060cd74f64b91424481bc40bb4db83","transactionIndex":"0xc6","value":"0xd76c7c0a756000","v":"0x26","r":"0x2a1c53b2a71916243828174412e55ba03951286cc82947d8490c6fb2e61babc0","s":"0x39a2e24783ae14e66facf41c5b8e44e529e352712bc9962d1ef71bfbe5475b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc793ec632f476aa4edaebee4f358485d245b0026804811b7f6528b49175691ae","input":"0x","nonce":"0x9cfa","to":"0xb82e0f3c72820861037bd7c3d911a96e6cb25497","transactionIndex":"0xc7","value":"0x17c1adfe0b47000","v":"0x26","r":"0x14aabd73b35d878b51c152c0ce5dd892cb5da4796b63f3ae1d3a9c467142d2b8","s":"0x320772c6ba1256843ede366dc1ce288d20af17f36ad9d908bf8b3ab35a6b1aee"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x12169fb22d1405f853c977bbd994f3baf65aeb9ea4482ac9060161c6a4f0cce7","input":"0x","nonce":"0x9cfb","to":"0x32e700e832d99ae47a00227cb068fb5cf3da5edc","transactionIndex":"0xc8","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xbc7b96700d6e7f4ba17e1528574d87ec8ecb2bde20bcf3714e36ba51fbc1351","s":"0x12ccc6c7288102727ff6a4a054afafc3e77237fc35f8b0598aa05588c9eafe6d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x89ba13a7b91f35ef7b98fa20a5f60fec657ded837b72cd7a69c5ee2cf5250edf","input":"0x","nonce":"0x9cfc","to":"0x776438b8e2e99ae520c68424362fec87cccf0eb4","transactionIndex":"0xc9","value":"0x3573c77b995fc00","v":"0x25","r":"0x1687de92e6a9e03f5a26d7e9adf01d703687ae98723f7616059a2eba1042bf4e","s":"0x4cc82767b8bb816344996892375244c67114845fae15c5a4d314f81278bca8c2"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x6471d332d78de2d77d20c68621f01bfbfd402f1f5174d5d23f1f65fe6b8835e9","input":"0x","nonce":"0x9cfd","to":"0x9d11002318a9dc9d1933c86f01bc629d51e6a3ec","transactionIndex":"0xca","value":"0x1db2197d8e18c00","v":"0x26","r":"0xf3665db4603eeec0d6b9c126da18d1d0c4e723635416d496d122b51bea8e5c38","s":"0x665537b02e8c6b542695af06167d86232ac78f5f37e9f303aed334bb81715443"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x27aa3212eb0a239a711f186d8a63a42512a18bd9332d7838f523b95118f99749","input":"0x","nonce":"0x9cfe","to":"0x9246543d9461a606b2840433f7c392b5aef8b285","transactionIndex":"0xcb","value":"0xd6c261b9bf0400","v":"0x26","r":"0x4d1af5be4a0c757b54eb66058c3feed92c2a1a85b1baa62dd4e9ce9dfbaf04b0","s":"0x7e284bad216625aa8ce5ae05b475cfbd3c5863ea51885de4b5c90f290cbbde8a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x787da5b7891661565543d353b5dfa70e5873ff85c7e566192963aa3885084aa8","input":"0x","nonce":"0x9cff","to":"0x808c940bf3acbd75bb3499318b352db2432d614f","transactionIndex":"0xcc","value":"0xbfd66e5a367400","v":"0x25","r":"0x5a2bc1e4a21cd2ad8c7819b3bb1da0b14baf103a217a076d719ed41132f57adf","s":"0x19b6341660bc14bccc747f7737be6ab023bf8a9041402a5051013faf812947ec"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xa887294974aa257f4f9a16b7c13d266d55ae0913c59b40da033c3d853b4ec752","input":"0x","nonce":"0x9d00","to":"0xaf758aaae27a66b03dc018e30b8effba820187f8","transactionIndex":"0xcd","value":"0xd10ec777941000","v":"0x26","r":"0x3efc22d04b40946916b5dc10ff039c45a26eecc4c024a11b2480777cae4af45b","s":"0x5364886cfddbbf40cf8fe12aa986ec4579478dc56f4fe0ca12892fe6f3efc591"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xaa9a352aff5cc1bed522ccdd197a644257d9ee7cdc6e8f61b68126e0819e8ab7","input":"0x","nonce":"0x9d01","to":"0xfbf330ad8f876cdd7b89232cfe4b593722882852","transactionIndex":"0xce","value":"0x2e86359cc169800","v":"0x25","r":"0x835f89cae0dded62ea8c6350d3d3bcf652047b57f13bac1ee26d112b7aa59214","s":"0xc6e496eeb284948bed201735ff3bf63c6499910f3d4ce5b7d6b172dde27af23"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x425b4f3ceab69dcc0d05ddd2604dfa40e78160d8cf839630c3e7919cf954ca1e","input":"0x","nonce":"0x9d02","to":"0xeb7d710b47c38c4992da2c3289ba57a85920ebe3","transactionIndex":"0xcf","value":"0xb35229ba10b000","v":"0x25","r":"0x35b710be13362ded9c96271d2d401cfa8ff606f3553827e8327477fd612e3c7c","s":"0x7b4290776818db42b4411a812ab0eb57aaa0884051369a30357e86112446f267"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xa4e40b677c8f444c3a7b97d23533e43d4a3ae21dde8fad55771d4c7ef5937c5c","input":"0x","nonce":"0x9d03","to":"0x28e8318732b762515981ef37804cd4eb6a5758e0","transactionIndex":"0xd0","value":"0xc3d6fc66994000","v":"0x25","r":"0xc783a1e9e5c08743c5427c6847ed19864e9c5adaf95a3e46912380fc377a8f4b","s":"0x4b83d0068197957b2479c6778f88df8bc6728aaf8175bb5b7221de1d689a9360"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xfbacc6bfb7f44322b7709bf52429cd5dd9d9d69d5c247338b1bbe84f015494cc","input":"0x","nonce":"0x9d04","to":"0xf00d3f4ae5b4214a302e464b3d12f031b127d483","transactionIndex":"0xd1","value":"0xb3d90a82e2a800","v":"0x25","r":"0x3f511bbba6e703af96fdf15b9adec24067f8390faa99917226e705617b0093f7","s":"0x154bb661e8272e7134fbd138b127b1b84cb5db49f1ae2a3f778c307d72bed1e4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8b84a4966d38d776c6b8962a1917bbb4f059729e34b99610e2c7ddf79ca49228","input":"0x","nonce":"0x9d05","to":"0xff8d7b0bff0fb85b52d10e5d7945b73161cce477","transactionIndex":"0xd2","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x3f5a312c1d08ec8dec4f42a512d85edebf264f008965941bbc5353e597feb38e","s":"0x715c0b3fe338250faa707432a7cfbd4e52c9bb2308d8a02bcf74b3041e1b57e6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x3e0fc3160fa5c53b4c1e2e3e46b4290771144d0e990ae89804f60c99f32b3cfa","input":"0x","nonce":"0x9d06","to":"0x255157a27d51fabc579ece5361622eaf8c1813c1","transactionIndex":"0xd3","value":"0xc3d6fc66994000","v":"0x26","r":"0xc713976a750fe379a85211f4f02479a7dd0b225ef43576d566f7533acbdda3ba","s":"0x1cc622ba98693076e2d9a21e141f524eac7fb9a888c7bfa889f058c63fa67c88"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8d53b68772193d037d5975e35fab74223b481d40feeea6861fde738bf4ef2671","input":"0x","nonce":"0x9d07","to":"0xd3e8de3b5a63b284bbed2d5cfe9794e3d5aaf221","transactionIndex":"0xd4","value":"0x2bf31b6d7af7400","v":"0x25","r":"0x6c3f46638dce4a49f9d5c743960bc20d6c3db6209ab199eb63ffac809aa8d860","s":"0x777cb49838ed0c4d553aa1ab1614d56b863422ff77b580c8fdc42612fac7daa9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x92d4a4e90c1ce7e3862c41aa95aea5c3354c7bb10b6a4516ccec5504b05cd033","input":"0x","nonce":"0x9d08","to":"0x9f52e533d0d336b0205cd27513d0368ecd27723a","transactionIndex":"0xd5","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x3bd544c739b57fc40be9937ec9af4a6d89e6e48d357a8280b27bd39a320064d1","s":"0x5624ef908fd74fe087ff1e81ce64d11030dc92644f9cf3f51a791fb13482e5f6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xdac1ca5e90336bd34ac6395fdb8d2838abd22a6d22298adc66d402d54bd81587","input":"0x","nonce":"0x9d09","to":"0xb18ed27b948855cb6b70355d15022c5ae1bedf2a","transactionIndex":"0xd6","value":"0x10488f2b8489c00","v":"0x25","r":"0x1499d499a1d314ad6f96ce73f641db22d1bcc69b992a4fe2db823f58182ff833","s":"0x6eb9b31a603012a831b78f14d5b902d2b9d5bc78f365ad8274415eae0b33955a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xab0c181188235dd287a7039351e65ed31a1c3b6ca3e25265672d1ffce9e26d74","input":"0x","nonce":"0x9d0a","to":"0x6f607c25b954d8ecbcdbbd9963339670f266e394","transactionIndex":"0xd7","value":"0x2c8b2629b4c6000","v":"0x25","r":"0x525127a98bbd7ac6bd66e2ed099fcdbaa6bc31fc232916099823fcaa7867132d","s":"0x2477abe88708caf7091f55ede6b4bb822d77a1e025d051f602157b851d092daf"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x83b03938fa0948f26c1b00a62f399c46155988aee9d6d2f01c10b2c4fd185e5b","input":"0x","nonce":"0x9d0b","to":"0x5a5dcb51cd6ce7b05303ab28429edf8d9d3b062e","transactionIndex":"0xd8","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x60a9c574271e060b3fe30f2c91e16824c27ab6487103aa4844d4b21a9161a6ef","s":"0x2af5c7fada52e0fd32d0c79e0decdd6942deecda5433a12695c99a19957fcf5f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9fc136a17fffb9382333c373b4179a3eb7c331885b86a422c31f5257da22a55a","input":"0x","nonce":"0x9d0c","to":"0x6f153c34ccb387a3c65c456f2bc73d02dcd74aa5","transactionIndex":"0xd9","value":"0xbca080a4a2e400","v":"0x26","r":"0x3dd0047baec92ffff8217aead0db0dedb1eee7269bc576612c753832f9d9f226","s":"0x7face9f9fa7c5cafb479f8779f083a74376a15f23b1d45678c5f96fc242e1765"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbf29e878bf6ac8691125f38d804c2c7ff3f73627a554a83609e3c11423da6903","input":"0x","nonce":"0x9d0d","to":"0x3cc6361ffa45d348a6baf3bba05c4fe0eaf15b07","transactionIndex":"0xda","value":"0x1708302ebdfb000","v":"0x26","r":"0x5df3e470d3dc803d9c85224ce70047fc39a523a9d8e0aa269e9e9849696aa7e4","s":"0x50ac36fc9444ccd19262ada9e5c9f5d41eb67a1962dec1b4a76ecde83f7da264"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x351f9816a5f1a92031a5cdd7ced1a49b4626d215df0306ba9d49d99b9a8dcd9a","input":"0x","nonce":"0x9d0e","to":"0x9de1d52959d35e32a2698975a137f183f9511e3f","transactionIndex":"0xdb","value":"0x14c9782ba97f000","v":"0x26","r":"0x548a968998e3260944e30d7a1176218e72fe8add244019aba026ed26dcccfeb1","s":"0x49697d323bb12ebe772e5f62768b98ced32b127d1270ad5be5da2fb57041d8b6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x5d2499b5492e6de32086142ddcb47f24d1e1e7e46c7088af168eb9f74a9332b4","input":"0x","nonce":"0x9d0f","to":"0xd695c7dbd84e5d58c7ba1f26d20b2593e15a1fec","transactionIndex":"0xdc","value":"0x2f55bf3ca595800","v":"0x26","r":"0x191363910d31ca0643f9d1aae7a3f8c8eb81158022f1e7c73dbb2115c8e00917","s":"0x5991eb14537e7801cfa75e0750fab12c6dacac01540783bd9873116ca9adf9f2"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x45483edcdeda70664203bfb599bbd94e27673d6f4c43f4566ce9957c468768bf","input":"0x","nonce":"0x9d10","to":"0x745d85da1aa5d82f151fb90a76723e94e7c4cb48","transactionIndex":"0xdd","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xd66e41d88dec87395300a329068cfc53854af5f9c74295a79604b769f6bf9d00","s":"0x389c13b049434448195df4d4198dab5adce0eb7c54f89b234e21c4002277c05b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x180450baae621a037e6325cda67da0d5299f3bc53ab5fb53cd2063db30ad857d","input":"0x","nonce":"0x9d11","to":"0x1f078100f770dca9bc0de8a2e56281e68d10efc6","transactionIndex":"0xde","value":"0xbfd66e5a367400","v":"0x25","r":"0xc5282a113557bc82f1891870d82e0fdfa866631c59fe0ef8fcf492a81b240a84","s":"0x76499a4831ca6ffa0a522d16f08095a03475ec091361196a0cab29e9a64ddd08"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xddd7bb565dc8195e56ec8678041e817be52defefbf1c61ff8e50aa5d2f4995fb","input":"0x","nonce":"0x9d12","to":"0xb88585c62dea87d736c29f0fd4217f70c07c057f","transactionIndex":"0xdf","value":"0x10a4fa1c3e61800","v":"0x25","r":"0xbe3003f71dc134804a94488bab38476c3c783ef50dfa6825669757e3901656f2","s":"0x186151902e221bba4f3c0e6d83da1bff751dec4520bb4d4e411d3fa71429c984"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xf4a3fefea93abbb34748b07264fd97a86239666f0e42b83327e4bb154af88554","input":"0x","nonce":"0x9d13","to":"0xbe2c3874af4ab4ddb7bf24586fdb6cf13780e453","transactionIndex":"0xe0","value":"0xbe0d6ff05a3800","v":"0x26","r":"0xa6b34a07eb15597019cfd7af199a232a6103ff79ff851cd67ce8379817d56ee8","s":"0x578fe3780418a7c7b5c0abe6ba2916eee7654b11ed204d0df84d5893bd31e417"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xd44ef22db1fb7e12e2da4978630583d0371faf280491ba4ea14aa67c05f2f2d3","input":"0x","nonce":"0x9d14","to":"0xa15c242c4311f878eca821af6ca6b2fe2392991a","transactionIndex":"0xe1","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x62ad380c829c8957a7d67a33afd0cbdcf52236b61e0b319f8c44ed8208901179","s":"0x7e7bcb8ce95f10253eabca57b68bfc94094c23da7a15c16a9c3142a8a571ccbc"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xa5fb48b4ecc1e86facb80d4846465650fe8c27953674f66efeb29edc343a2e96","input":"0x","nonce":"0x9d15","to":"0x1c94dd84c1d0ec757ed568c1676541f039c06a6f","transactionIndex":"0xe2","value":"0xc3d6fc66994000","v":"0x26","r":"0x5ce4bf66e7027de1c39cf920e19fee8f5da51ba6231fa06853a08d8826e2ebf0","s":"0x4d536ff7d2dc81be76ce0b9a2fcbe6e7f0e7e0e92517b94d8edff2c7103a934a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x6949634372f1fe260cbacd3db19bb9f5c61b44bd858a50c3af3dce9fe0ccad46","input":"0x","nonce":"0x9d16","to":"0xb3328cb02b0759d71b1837ede36e5674a77c6da2","transactionIndex":"0xe3","value":"0xd248715f3438c00","v":"0x26","r":"0x6961ab1637e1e2b367c49e9ab0e59f1bb4475acc61feab020b3cc65d470f2b01","s":"0x22531490dd06c32be73504df385bf0b39f17c6b710f04930ce2955b9053aff3e"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x5d581a05dc437f6a0d451a6d4f068257abbb2ce0fe1bc98aceb6fcd8e03268ba","input":"0x","nonce":"0x9d17","to":"0x4ad9178b47868752beb5aac9685388cac1f1cb7a","transactionIndex":"0xe4","value":"0xb51ebb2a2df000","v":"0x26","r":"0x360b546750e04cacf502754024ac71be0377edc32c1349b7e7eed2937bb7caaa","s":"0x2fafc99957e967677cc43fc67f8a5fd304a7261a08e67e91f9cec5de4fe28500"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9714470a91c3dc2e7dae6ac9d4152d70272ea323ccde232ea35f9057790c21e4","input":"0x","nonce":"0x9d18","to":"0x8fae8ae3f4431c4d4faba4b4756b45de98759e48","transactionIndex":"0xe5","value":"0x41549e7a9f03400","v":"0x26","r":"0x27208885dbd18638b93026f4c30acf509dd027a5c52d8db1228ac2edd4ab87be","s":"0x4b49789d178fa09a9371e15c18d0aaf1dd172a4af9dcb3364613dd58a863a1cc"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xa2b3186efa03b1b54d00998aa0d8897cf278678f404a8060816b6cd806629e04","input":"0x","nonce":"0x9d19","to":"0xfc6418f560acae4419be48f7f299f0aa2185f525","transactionIndex":"0xe6","value":"0xdc51de47784c00","v":"0x26","r":"0x12cb0e577acb62d2dc1ec52f0ddf0e113a4b6ac6f9fb5f9b410dd6852ff137e4","s":"0x10787f0526a00e60d31de51b6066e5bfdf9aadf8b0575c7f9485c49477fca7f9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x73200aa7eb57161747d1bd9a2d11917b45bd6d79caa5d26b7344f7a7502952ef","input":"0x","nonce":"0x9d1a","to":"0xc4a11e92427a5554364ac7e314670adce6c9422c","transactionIndex":"0xe7","value":"0x17c1adfe0b47000","v":"0x26","r":"0xe1faccd7a599b682df63b68836e6a4f4d45223b8ebf2446e7deeed2d01a6201","s":"0x487e703d6e11239513aba25bbfd20b31cf76871b9437a7c16e2faf35f32f939"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x954b6bfcc16c66d3d3cc657348b4bbcc6d4a06f6f9ba779ce4eb96e483634352","input":"0x","nonce":"0x9d1b","to":"0xc11990d182af08898b244393d729d082c04d1e16","transactionIndex":"0xe8","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x701fc2458fc289813b711df4cf032cc35b121fa830dd09e0d6475ee6ba8123f8","s":"0x1abc1a548024efc3d7827607408b1a001856f5490e7a22039e6903341aec37cc"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x91df18865f6a5df609741a128228d2aebdf09aa37b15f97f641e8d9dd88ba034","input":"0x","nonce":"0x9d1c","to":"0xcc5ffda4eb02a170d7182d0dd4f75f25c564ba11","transactionIndex":"0xe9","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x34c6e45d650823ff297591136710152176d81c093e1990da19a1bc4725b18cb1","s":"0x206c8b68f07b35099132551e9b10509585ff4f702f4d05951e71f709ed2b761"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x163d3003030a7a4d384acfc07e3d32ce388749efb2f6ecae44af7de5e3730894","input":"0x","nonce":"0x9d1d","to":"0xf2355719899495d08429900681a14bca060d9879","transactionIndex":"0xea","value":"0xb78eb0a0ba4400","v":"0x26","r":"0xfae4248749423ab2587efc0bb3091a8507e6910ea118f35a0ff44967f2a4d732","s":"0x4f15fc50959fa68880e1c38bc0d75ac501a1cfab2f8dd3b8856ba71f50efbc3c"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8c59316f9c6cdc642313e218d1966894991c706395d7b70e4c8c6f73eb3c06eb","input":"0x","nonce":"0x9d1e","to":"0x0ae5b31bb58974b41961d06a865e8ffc1751a3bf","transactionIndex":"0xeb","value":"0x17c1adfe0b47000","v":"0x25","r":"0xcff9d3c7dbfe980e210d13ce817a6852e844b1a281b1df27a89608e655272724","s":"0x4af41ea19ac9119abf9befae40e384be08144a5dea0bab0a6d7ef94371790bf4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x34d76ba55e293dc71439735338540abc154a6b934fdbc1d9a887aeb8e6b00055","input":"0x","nonce":"0x9d1f","to":"0x9be6e5003ebd8c12fc8453adc0bea7c040907145","transactionIndex":"0xec","value":"0xc3d6fc66994000","v":"0x26","r":"0xc9362d7253138a9f4851835862970bc14af545d5414033b0be3d8df042b2263e","s":"0x3f8a0678a5a528458c63e08a0a9412d656bdb972bba090416fa895aefdde73a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x754bbd76215fcf913198131686c42b14790cf6d231b3299dd7d173bcc2989d49","input":"0x","nonce":"0x9d20","to":"0x493ed6708e1709d51aae0f4635dccfe695e17a42","transactionIndex":"0xed","value":"0x1ee22ef601b6400","v":"0x25","r":"0xec291fdd9183fb067ba1297fab3ee2f44eefddab9a84be982145e01c3b1ac225","s":"0x7dbd0d4dbc7a551ab7daaef7b3dff1b4af48d0f666741740222c2af2d7bd233a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xeabc4b6188418f2dad5b245a39c6ffd8771ed87f9d453d254dff1af9371b4a0b","input":"0x","nonce":"0x9d21","to":"0xe0dd007e4c1858198d5333188d1e51a50fe7fa24","transactionIndex":"0xee","value":"0xbf373008f58000","v":"0x26","r":"0x53d0edbefcbf73c8e024d30293fd1ebbbde41f2e0559fb6505256c89b2d404a0","s":"0x4b70ff90da557741e490c44b5d6187541378d038383b0cadf07ae7b122d538c9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8f07bc246af8f3ddaed18a610cf6c270ef1c2dfe109e822e544946c9135b4b67","input":"0x","nonce":"0x9d22","to":"0x840a86928ecc07417570a52a2fadfa07b92fa249","transactionIndex":"0xef","value":"0xc3d6fc66994000","v":"0x25","r":"0x4898903d6c230f74ba3e9ef279ac0ebf89ec7fee7cee57f484449d0c00934f43","s":"0x5bb1e090a72b44aca5108e59616396d53fafa5a099276340c8714ad151f05095"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x69c58c9688d17f6e3a41bb507d45a8a3e466f8288e3b946ad4efca1d45ebb973","input":"0x","nonce":"0x9d23","to":"0xbdaaec2bd3aaa7d7dc7bbb1632ea8407a0400ac8","transactionIndex":"0xf0","value":"0x2f91cda05a5a800","v":"0x25","r":"0x13b6bc5a8cc3e3f573082bf9c5a116676005af6cfa83b09637fa6d5d49ff69eb","s":"0x30d62a01c5facfafe6aa9ec72420df4ab58960c035efc82cb0d74b4dbe47ffe3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x55c64f655d8dea53f2ce64166fd895407dd9137d1c6ab71b5557521b013762cb","input":"0x","nonce":"0x9d24","to":"0xab7cd1de895d8f6acf3a33dc0cff1dbc5d3cf8f8","transactionIndex":"0xf1","value":"0x243a8fb94ab9400","v":"0x26","r":"0xe571d5ec1a3ad2f7ee2e4921ec990fee738f790b8b9cbaa41ce6199dc271557e","s":"0x4281a9021c3baee73922944a32640e83b563d12f1ad7d7080d0f56226957d613"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x7e9e4fc7893cf0a9622eb220c1fda03f6de22989ed09c07b5d4e962280a26fa5","input":"0x","nonce":"0x9d25","to":"0x0ed7fd37ac6d0cd11556a390ef5755cfe7e11ee4","transactionIndex":"0xf2","value":"0xb5ab95a5840c00","v":"0x25","r":"0x8c5ecc5b3eee2219e9abace46b7512f1cfd545342db9bb86055a00ad4d01a513","s":"0x29a5fbe512591d06682e59ef9c6189d3bf8452363d2e4b9bf306dc0d0ef8532e"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x01da483cc7dd23a9eb7789d099a98dd7defc20ce93445cc3f9b27a3c45b88567","input":"0x","nonce":"0x9d26","to":"0xf90454bbf19f7a77f6b0af28be2c5f488f494246","transactionIndex":"0xf3","value":"0xb236dafb37b800","v":"0x25","r":"0x296b8e9e002db193de14cbac2dba792ac3e10aac099e516efcb426ce0fffa1a8","s":"0x5cb237747f3d97eb69fd34c77464b048ab8a130d35eff139a69f99ebb3a67bfb"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x11415c478db04180237ee25f0d9f25051d28b253fb036a67191d14c794f0aa7c","input":"0x","nonce":"0x9d27","to":"0x13e36fd42db0af1af5daf99cccdbd5d3abd84c75","transactionIndex":"0xf4","value":"0x3c4843281346c00","v":"0x26","r":"0x4a9805021177372d9e45eb50f1c7215124f767adbe27f6d50239745afbaaf2e0","s":"0xc32497ec2419af80fd422f8b513bcf2aaf694b19e82f5be710015ed47be6cc2"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9d0098cc74b6c0fd63e186cd7082f1230532cd8c7139c059b3be9418744e7e24","input":"0x","nonce":"0x9d28","to":"0x1aa676e5951dc81d5d423448eab4be659bff8af9","transactionIndex":"0xf5","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xb66285b17cbf0145ec370a5e9f38c931b77d0c2b9dbc1cb105eae92df68cb3d1","s":"0x516b4cf19aa021d5d4547d8b107eab6a71be2141d0e09735835537e32179fb64"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x38022390b5784a49bb4f7b77abeae78d2a4929be84390600a273b3c60e71427f","input":"0x","nonce":"0x9d29","to":"0x137ae004483aa3930b86d70c61e2704a8ed15f92","transactionIndex":"0xf6","value":"0xc78e1bb3f72400","v":"0x26","r":"0x619b7886c3459782bb7a12d9819792a9830ef4006aff306494f513d25adb63ca","s":"0x20e165e8f873c59618ec2f45177391a3d329987f2f269ae849f6449affd432f2"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbdd61eb9abee735e5f27d7183ce30a25996e14eaed40604b316b0612795a6c64","input":"0x","nonce":"0x9d2a","to":"0x91a5d62b126dfaad6c9f84208fa7265e35f654e5","transactionIndex":"0xf7","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x1659de2ebd90e88a745c6b6fed1781f709d14740b44cd08cf2a4b89b38120842","s":"0x4ba65b21017b960635bb239784b26ca9cf9cf619b3ebaea46f549a39f813073e"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x4054d4a66cc62b44cbd482e7a7c9a3d47961ee4c92f01383dd4bd217af49f029","input":"0x","nonce":"0x9d2b","to":"0x653df565ec7fd75e6d11c93d2e418df3059c42a2","transactionIndex":"0xf8","value":"0xbfd66e5a367400","v":"0x25","r":"0xb996499cc7de072f5aa5e00195b371b10600226e422fbcce26a66b19e895b460","s":"0x6774c8b83b1c4e02bdc628ac26536e44551b4c0d16f2c69adcba53094af21361"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x14feb3ec93a5784e8e8ea8086c8b0b14bc8a1ba18c2c020b0faca2a3282f233f","input":"0x","nonce":"0x9d2c","to":"0x48ce0a4b875f12a67491cfff924d6ffa26a15095","transactionIndex":"0xf9","value":"0x10488f2b8489c00","v":"0x26","r":"0x5f1487c5db3f0f6810fd94a2358417e199f37fd8b83b12dc730ec254ad66ecc1","s":"0x6d0b167e2cdc8a783b0c4d344ae2f53c8506918c7507d4b786a1829e1b930b1d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbe8033c700e32c4cc9357f236c22e38b46248bc969c1877b1edd5667caa0275e","input":"0x","nonce":"0x9d2d","to":"0xd4f2d58076871ab57b6bfacefc77d89e25520c7b","transactionIndex":"0xfa","value":"0xbfd66e5a367400","v":"0x25","r":"0xaae12497417754109c27af289a5c076bb921bc128502b05afd3707bcde72315c","s":"0x1bf7d8b4fd7ac51a136b09bfaa77baf90adf1a54c06e74e5958c4afe12f7583a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xa1f25d0f7e6bf6871bd49184e89c6281f69df9533d22f1fd85aa6a91aa86bcc6","input":"0x","nonce":"0x9d2e","to":"0xc09c32d40513584b21c1cf9c281ef0606512c2cc","transactionIndex":"0xfb","value":"0xd10ec777941000","v":"0x25","r":"0x8d560c372f294da15f779d0dac2e381cd73571c65f311d7fb681fd73a1424981","s":"0xcfefef34555e00a3be0a99ae73b599ea5af3af892b68305e3eabb1a5c4cd8cb"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9b8740e51e99cfd9aeac76684a2aadaf8a4becb51680e8acf6e67d7885f6ced2","input":"0x","nonce":"0x9d2f","to":"0x466521aebc4b3d385fe15ad735aaea12112b127a","transactionIndex":"0xfc","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xe773f734e166160eab39e86abe317b09fa87dda79dfbf5d6b1549c50e2efbd80","s":"0x20fa53a197715b410e631c5ea0ce32734e4611733104d5d44bfa42eeb50ad84"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x61aa8b97e2c95243396ad3d8987a9514f3cc34cd35a7f2e5ec60625c446c713c","input":"0x","nonce":"0x9d30","to":"0xdb909d1093c83d34ada5d9627560f467344872d2","transactionIndex":"0xfd","value":"0xb63eec35f82c00","v":"0x26","r":"0x2675c0ab6ab44114434e174fd737ad8ebdca6a6a75bd1e6042af22abc7b77095","s":"0x562f6f3642db195e37855c3d8451c82d2e64b1df0de6bb041faa4563ab3d1711"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xaaf865c9b11a37d154dc3a0d82a8b5751ae480cea7dc78144815014a1d47a131","input":"0x","nonce":"0x9d31","to":"0x890b451b2ff30f1da26e5ff815b8e2903609e78f","transactionIndex":"0xfe","value":"0xbca080a4a2e400","v":"0x26","r":"0x927281130e5da54aeafbaefdefba33888fa696a6ae4011397db46e32556bcffe","s":"0x63537c39427a59de124acce253ec54eb36f7f1350e6a31f4da019391d11b52f4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x04b414f36ce448d4382e29c61acc81cd1ff5397fab63fa3e520d367d0b12c907","input":"0x","nonce":"0x9d32","to":"0xf060b2a6f01a05eee307ae90201afa5b13f6670e","transactionIndex":"0xff","value":"0x1c8203dfd9bd000","v":"0x26","r":"0x4c1b44608814b2c80472721e83e9ca5471b48226e8a697ac530c91f90a64a0c7","s":"0x2efd8eb43d46ad4a08c341d855b2feac58d7571ad609155d79ff8f81f1c5b46d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x84835297b78c0fd5b83761e87046aa80c5c4b25028172a6af2e3c3845fe3a973","input":"0x","nonce":"0x9d33","to":"0xe0e6c781b8cba08bc8407eac0101b668d1fa6f49","transactionIndex":"0x100","value":"0xc495a958603400","v":"0x26","r":"0x981b6223c9d3c319716da3cf057da84acf0fef897f4003d8a362d7bda42247db","s":"0x66be134c4bc432125209b5056ef274b7423bcac7cc398cf60b83aaff7b95469f"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xdac06da3dfb3f3f6a0f9c79038e3d08ee33f525ae9868ca0af5d5a9dbbf39a08","input":"0x","nonce":"0x9d34","to":"0xc70f9ad86ccf27090c331a20c11e09e161badb35","transactionIndex":"0x101","value":"0xb555380c72ac00","v":"0x26","r":"0xdfac45d18340cdbe65b97e769ae1845841e580698feaa730b7357211d222a305","s":"0x2a60cb17e470d16b323026e3f048f0a6de30b2629bbfcbdbae5d264f8e51e019"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x27356a5d6167fbf721b223e0be046c9214449802e55498426acdcd2dc96b69bb","input":"0x","nonce":"0x9d35","to":"0x58d0bf6c45fd77edba9e0ad3e46e69dbe1ab2d15","transactionIndex":"0x102","value":"0xbff52062f95000","v":"0x26","r":"0xed00d8e5d37a76921bc78481e6b0f4a137b4a03b151b3a6bac8962484f077778","s":"0x5c9229481247f3af1cf80f7cf0a8292594e35093e038b5c3afeca3a167d2ec77"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xba4819c207044620e3989e499e61e7c03197864bb8b6e815e3691079763695ac","input":"0x","nonce":"0x9d36","to":"0xeb53460104b5b5ce5add099abb75932da9904af5","transactionIndex":"0x103","value":"0xe07fdf4fb6c6c00","v":"0x26","r":"0x86f96350bea35565fb74884e356f9810c9ce1b75502292ecd311a286a4b7fe2d","s":"0x5d234756ad837a45d9c67b9d85f25eadb0fa0e839746a3abf12660b923e07fc2"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xf366be96a8c24c2c5939135c036e1dabc81b8b22118b68ce18600795069685df","input":"0x","nonce":"0x9d37","to":"0x6a16c0c1fef68d68711cc9b35fd5491e89bb2506","transactionIndex":"0x104","value":"0xc3d6fc66994000","v":"0x26","r":"0xeb1e4254f3d1f1c8acaa79c750c3928f2327fd88cf2c02eeae75b6ca74986cea","s":"0x2e700cf3266f445e9d68b9bae03798d5e052c514c1d4bd08703fabae97ca69d9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x77f3beb8f13797edf0979091a9894abc3a2d37ad00ea6c2283d364b2bbc53749","input":"0x","nonce":"0x9d38","to":"0x3b88c148c85f265d0cc2e1bbd22706440266fcc0","transactionIndex":"0x105","value":"0xc3d6fc66994000","v":"0x26","r":"0xa850344302e0bf95410b8307c6bf967b0abdff41f46d03d78332f56c98e4b61c","s":"0x975632db6f8f95168bfdf0f14b46b02d9841235cbb0bc8c2be6833b6e48700b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe8e77fc19f52a337633d20318dac2583b10094a5d886aa12ba86b40d8c445b99","input":"0x","nonce":"0x9d39","to":"0xb89ed0d7c1bab4562d6c9f62ae46e1ca978ac3d7","transactionIndex":"0x106","value":"0xc160e100a6dc00","v":"0x26","r":"0xe857a3fa7b82349a1e49abb8cbca936d234737a4fd9db5fe43af59054e8cf806","s":"0x4530fc86a8dfefe73a8edd8ade26867b0cf704c56a63902bbdd87f8cf2f633c5"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x39b8dcaf327d4494a5d7e334924f063f5115b8f88d5d3e0fb11120857154cf7b","input":"0x","nonce":"0x9d3a","to":"0xbd630d86d647dd1cf11693c8cf1712431596e757","transactionIndex":"0x107","value":"0x3b6432fb1c31800","v":"0x26","r":"0xc962522d9db8c32ec37d6e1d2542f92999d7c92748a1f79d5d535b1f0ab64e7","s":"0x2d9784082a45fa85b38dbb5bc86b1e695bf3461c3319526f7b00524e77b47180"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8687c226e36b53a0e243b950f842f8063252a8131b8dcf5bced13a3d374460b7","input":"0x","nonce":"0x9d3b","to":"0xe8beb6602e9fa7261fb7217772e74a0e0eff5b32","transactionIndex":"0x108","value":"0x274d60dc4dc9000","v":"0x26","r":"0xcc877996f15ea692f268ec668049d9f1e9e5d4e06d294bdedc0e5dd849c044f6","s":"0x7894390aad202383f3513e0280e368b8806b3c84457fcda33865124905fcd2ce"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xd3c6851ad1b73607f350e94caac79d6bf8164db95e2550a176c17c82d686a436","input":"0x","nonce":"0x9d3c","to":"0x7259671a99d6727afc719b6be335b3d12f23315a","transactionIndex":"0x109","value":"0xb3d90a82e2a800","v":"0x26","r":"0xe80d30a2e0221d11e8c8aeeed9415b61a46b8f75717f520757f0a04a30dcb2a7","s":"0x6e8e19c90a794ddcadfe87c155fa907dd120e78230442a8fdd84a3eaad6b8fb9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe3c463f1d97b6783e4d3bab38371467db884276dc506b28d3f499b7dc8633d0f","input":"0x","nonce":"0x9d3d","to":"0x3fa58fe438957db67fec7d98830733cc20ef78e1","transactionIndex":"0x10a","value":"0xbef19c7da23800","v":"0x25","r":"0x12b6c4b531ea1ed93893813ca4ba83711ef77f0aeb5d50496338d61ed4a8073f","s":"0x615ef3572bccaa7a2b67e2016fe27cd5e92476be30dbdd896421a0e885462987"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xdf8d0be70c7f0c1b363ce33d040f854db2dd283018bca934592bf5a0bcd7d9c7","input":"0x","nonce":"0x9d3e","to":"0xc6484480165ad0be7837d9699879f471598f47fb","transactionIndex":"0x10b","value":"0xb213bd63e20400","v":"0x25","r":"0x88d47a6ff2e2adff1b749dc2d98ecfcccc34a431a12f6e6c8f609afaca81e292","s":"0x2b7b96247e151a7d80e1cb2007328c35640b5e88d248861d0c04aa6d5a77dffa"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x31b9b1f7476fec5dfd5fd18d4215a91c59e8f6347890945f4c8cd0efb7bd68b5","input":"0x","nonce":"0x9d3f","to":"0xdf918af8a6fcea8aca4e41033a83f376822c5af3","transactionIndex":"0x10c","value":"0xc2fe6d18a19400","v":"0x25","r":"0xd4604addbb94448503460ff0817f0f282ca9d6593502a55f4a9b614cb0da1862","s":"0x72822737b98c32e340abc5e1d6ee981b5744bfc10a561b9042c9cd4256ff9923"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xeb29d192acdb57fc681038476f689fab44f12b7c75016085f6c3841bdd5081c8","input":"0x","nonce":"0x9d40","to":"0xb8f4c6ebc5adee28bfddfcfb4b99969a3d4d3f00","transactionIndex":"0x10d","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x6a7142f6a976e021731d4565247432a41c9480eea32b2a92b8379242a5582d47","s":"0x1c919c1ed41b784fd02b03f5c34db4e11d073c741683b25e80271cdd277612e7"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x68418311e4bd7dd19b15b5c38344aace68b5eedec39aa24835e76e17ab44e3f9","input":"0x","nonce":"0x9d41","to":"0x171125195a8be9c1bfa055ea4cfd111e5ddcbf24","transactionIndex":"0x10e","value":"0x20278dafea97800","v":"0x25","r":"0xdd1b1aef77828c1775ea8fe40e284d38e61215af17a7f71f275853b212091fa5","s":"0x16cf60f614ffa64806b57a6395392fdcc682ee642b5628fbc5efdf09b9a63af1"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xff5a78bf3cdf7ceefb03d933c01ef9d7422bc3560ac872bc2f7e31ae06d610ef","input":"0x","nonce":"0x9d42","to":"0x778ad400d43bd2f7f41e3ff77093bad2cd91be12","transactionIndex":"0x10f","value":"0xc78e1bb3f72400","v":"0x25","r":"0x6928d8a9aa1c15cc31debd4c39279dbdddc877124acf5e9002e75ea90c581a74","s":"0x6cf6d08af094cae7180a0cde1a328c4b224eb6a8d794380ae01e52823cc548ca"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc5caf93d7b27eb0a5d0a0d48df676b8c8788867566e4e23924746ecfefe05e31","input":"0x","nonce":"0x9d43","to":"0x986c672311415938d7586e79a5f638f2b29a3927","transactionIndex":"0x110","value":"0xba0c3c94ab3000","v":"0x26","r":"0x5732311fa0e31c3b8d3d2247ec44072c3ac4b3058b8f8393d3b397c0a8945742","s":"0x492aba48035675bb962b3b9af6d9e7f41251e68982e7f109a065452d3df106b9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x88bdc57f8dd898de0d50a5c5e15648570f2059b4154123923bf0d1676f4ac029","input":"0x","nonce":"0x9d44","to":"0x4c647225087bfff6da1536b4d3542ebf13cc46ba","transactionIndex":"0x111","value":"0x7cb8d1507a76800","v":"0x26","r":"0x746f8df66a4584f2defc5b791ef251bc4a67472c01d173aed64fe7b4a92517af","s":"0x4a20a791bbd9eaa7ce682068fc770ef5139feaafa37d8a00c4a8a694a87c0953"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe79ceed82b17fc949cfbc6136dc826ce72d5b67e9ce4a922a586697ae4e6873e","input":"0x","nonce":"0x9d45","to":"0x4798994ff85419670aa86bcf026e7c5976833249","transactionIndex":"0x112","value":"0x4fe1a5db4928400","v":"0x26","r":"0x2fdf8b414249d409056a19be0b0b55df2d00a18ce9cfe9a63841bceb9ae0eda2","s":"0x7437f0548a236bb86ee90e3789c7167bd60197065a93da26a006efad3600a0f3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc2af406032f7e8684cf7de96048c604d2fff9e3e326c66be0a8ba7b901510b87","input":"0x","nonce":"0x9d46","to":"0x4bddbd1cbe7aaa14d1461178e2cf4943c12fa20b","transactionIndex":"0x113","value":"0x1db2197d8e18c00","v":"0x25","r":"0x88e7c916c1699248231e7b0b01d6045d64efdf5c3e910337a3f1a395b87d1dc6","s":"0x755e8ca9e5bc9abf2a5b086fbdb37c05e505a118c28e58efdbfd4d1da854da2a"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x19ed7609e5fc47fa26b198bd9b58365c4b6067ad02fcc6547b768fa5080be8ba","input":"0x","nonce":"0x9d47","to":"0x60c977bcf64316c88fdba52391d0dda45b129352","transactionIndex":"0x114","value":"0x22726f849d4d000","v":"0x26","r":"0x81b8c25c00abc5654b307058428192835818c810de464c3bb0ad6db58756951","s":"0x4deb54a63c82641983d8497dd69544755933718cc892165a5bddfd5cfc069dfe"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9c432dca59d47809df0c50b93fafe25c5edac9497617b55629d714dca7373596","input":"0x","nonce":"0x9d48","to":"0x374547eed2c3738f09f591fff7bfa417b9a75901","transactionIndex":"0x115","value":"0xc0aa6cd8dd0800","v":"0x26","r":"0xa987421bfb2d3b853b84891b6f85216d66c22c2b2fca15f39150f912ccecf727","s":"0x7f10ab7897ab16da3797ea41272558d65d7def38be91e4c1003348051f412185"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9c5cd08d5ceb6f4d4c3863046b643f3fafa9bbb351533abc71debf1687c18c0e","input":"0x","nonce":"0x9d49","to":"0x3c068db8f6ef4182e75565f5d37eaa8543177c25","transactionIndex":"0x116","value":"0x11de480c08dc400","v":"0x26","r":"0x3525843199367aaa9044153ae0d85e54e3707cb7698cca38097876b02dcd068a","s":"0x77ddfed3ea1e5f7943b2d89610d2371e2c83dc62c00267f2f94b6c0cbb21d962"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x3d22ae6592e88c4ed761f2b9ff688f1aa41982a1bb370ecedf49019843c94630","input":"0x","nonce":"0x9d4a","to":"0xfb3de54d4a6130598e8ff6a039ef30f0b59082aa","transactionIndex":"0x117","value":"0xf711768607c000","v":"0x26","r":"0x2acfc1043321833c91b0b59efc785cd3f6cbdf19dd3419bc2789cec5212e5ebe","s":"0x62460ef4770c05061fa67960019f181056798b8db278626e22851a7856dc0132"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x689d96eb460e8e30e8ea87d0b98a647c0edfcacd594cc5e6eaa1e062cc77b313","input":"0x","nonce":"0x9d4b","to":"0x5d795994944b3aee38fe866c8fe77b68d4b55f22","transactionIndex":"0x118","value":"0xbfd66e5a367400","v":"0x26","r":"0xb1742bec9a7df83d804cec1d6655ff3a3e921806e0b6e9a97b84138ef0b1d075","s":"0x59c1eda35bccbceb17161743d4f44788f7654f1f92afe15cf03ac4cd66d57ba6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x0ecdf674c318bd00f62fbe5413466ec13175c523cb0cb16c4122df6d4d2c24f7","input":"0x","nonce":"0x9d4c","to":"0xe417e7027b38ba90f4250deb71ee602aea6de5c8","transactionIndex":"0x119","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xaca1fc6427a7e3c699b3669cc6ff3ba6c8f2cfa573f97091424997be5d752cc","s":"0x475a62702cd690b0ef846b65868bbb2d726938ff7c2e6b1aa394c49298535c15"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x3dff56ba42771c98a208c77ddf52d77ca3cb19a47392795f5a109b4ed50aaa20","input":"0x","nonce":"0x9d4d","to":"0xf3bc692f1b8a25495c63a5e21906ed7c16cc976a","transactionIndex":"0x11a","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xef42a333834e0ff5c47ac0a96651e3701d2c5f59e424d7f22f0512ed2ba55127","s":"0x535fa706628decb9b4bf85420b8d25eaf94a67eb0d0749b8746762f61c84ca10"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xcdf47726cea581aa0378b01dc18fecc863fbdcf375ca39c5e2bbffe1bfecadd1","input":"0x","nonce":"0x9d4e","to":"0x88483fbc3eac6a4c27e180394cdfe01780b971d9","transactionIndex":"0x11b","value":"0x3b6432fb1c31800","v":"0x26","r":"0x399b92ff667f02a249af27e3fb783eedf9a8fd48745b6609bd0e81641b88c176","s":"0x7a15dda763017a4d4962e716d4e153fa04d9021955250863828c80a5b4a1f35c"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x7cd35a6c78cdcb0d0cdf2976c4ccc8bc22675d40f87b5be6e309f05f138deebe","input":"0x","nonce":"0x9d4f","to":"0xf31b2602804d986d6298f06f7850fbb1dee44c07","transactionIndex":"0x11c","value":"0x11d1427e8875400","v":"0x26","r":"0x6182f241240e0a693ae127473d0632b75192ec86f25abcd3093d510de46eb7ac","s":"0x71da8f4e8c4df4c4f2cc6489c3799199e7a4dae6be816b0a99cc9338c1ead5c4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xb0628801347233aad9abf0bd2d4cd745cd636e180c573d99f902d467585cb655","input":"0x","nonce":"0x9d50","to":"0x3007abf58617a21fa38383a8d978cf12824e5083","transactionIndex":"0x11d","value":"0xc3d6fc66994000","v":"0x26","r":"0x968d3a6101bf5c9b4d2696815b70d9c2058f9bc771cdb070a191e067e32388ed","s":"0x1e5188201fde674eda698ac00137288ea1c128b00f55ba120d0a1acb47663a3b"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x9cd75bbf02e58624edc86f7fb73648c527dffd236c6b8fdd6809c60f39c69290","input":"0x","nonce":"0x9d51","to":"0xed2fee621473e633b7ae70b35d5a371745b5d7c0","transactionIndex":"0x11e","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x57381d57fbfd2bd4de4581dbef6e526025be89d3b909397b94ab9101c67b240e","s":"0x72cdb9ee50a130bab459b7b5d3571fbaf65143bb4cb92b13d7523e12828233e3"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8295129f3e7f07933f31954ac3119b79d397f4a1442ba43dd8aece46eafad0bb","input":"0x","nonce":"0x9d52","to":"0x996af40e6f835cfe4f6ef7901e841c638183255c","transactionIndex":"0x11f","value":"0x17c1adfe0b47000","v":"0x25","r":"0x3acf5d97079faa59d7f10eb15cac69d606055e9490be84cce0d3f9e9da21b783","s":"0x1ded8203056f75ce13ab52d94a1d7d199b603ad8560a59841e175e6c47766dd7"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x8c4793c0372011a897f8c4114ce8fcdfd02cb568815fba4245a8612c840d22f3","input":"0x","nonce":"0x9d53","to":"0x6b6a72cc53bf65645cd90378ab7235344f57f3d1","transactionIndex":"0x120","value":"0x14316d94b06e800","v":"0x25","r":"0xe1a5e98c7f70e0d6537fe3ddee2c41a5620dc9f485ba57b1b0da9bc19f257fb0","s":"0x14437aff3705bbd139d76c9ac83a00d02ca5dcc5c1deda0855ce506ccb78cbf4"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x527a3a6945c5800af57396b53c89f99d9bca46d64f6b266aa76e3abb7825bb51","input":"0x","nonce":"0x9d54","to":"0x05b03715ab29e54485ee847b926921905779cd4e","transactionIndex":"0x121","value":"0xe8d3be8f66d400","v":"0x26","r":"0x204f995758024eff4af8904d07489f365563e631b88192ab3b19ed98c9729a3","s":"0x77d1b4ee8746bdbb5a3450e3cb5b559095bb67fab461d3d17334ca2749dd70e6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x20185783ecb691a6e0d0e315fa4af57310596745b2f1dd34f8c05418f8e49e67","input":"0x","nonce":"0x9d55","to":"0x84f26e299f3ffcc72e30bcc17057379b9b059450","transactionIndex":"0x122","value":"0xbe0d6ff05a3800","v":"0x25","r":"0x7aea1f615f63ca364d9add4f75f3260367fcb01d072bbf512895ffcfb4d461dc","s":"0x20107d0a72dda0f2e1e76ea3e2bcc6c9afca31c0c54243b6376e1028279c7a32"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xf67b6ef1fd47f4d11e54fa7e9455da9bceb2546bfd7dc8746d0fc90463e29ba2","input":"0x","nonce":"0x9d56","to":"0x989e5a5f88b26d0d8cdb5d575ae4582010cbd9ff","transactionIndex":"0x123","value":"0xbe0d6ff05a3800","v":"0x26","r":"0x1be2409382789e78f0c8415b49b98c9842b7ffe8984594b821c38eae4d1b404e","s":"0xab5b5427ddf4e70ef1bbc627ed1789209c307f86e6805f53fadb0bc6c617317"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x125fb4f1f64f0e3a26fed148a7ddefa52ef94e328bc85d203e4d9f93835d6334","input":"0x","nonce":"0x9d57","to":"0x1bfbeb992ded2e68e6783110048053279c27aaee","transactionIndex":"0x124","value":"0xcda1be8c933400","v":"0x25","r":"0x6eee9dae37a2eb68c5ad7413f36caf03eee0916190894f399dcb101a608be46a","s":"0x6ed3cb6e041a39b01d5a617f74f83f95f092e4504ba8935f3686ca6f75b97f65"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x206ddd0eb0467b94918220c9194ea76c4fd38cd7f1270ba4055bc062947a09e2","input":"0x","nonce":"0x9d58","to":"0x3094c5a507916ad1d30b32704fcba3c781b3b038","transactionIndex":"0x125","value":"0xbca080a4a2e400","v":"0x25","r":"0x12c952bcaa4a479491966d189ab00e94787004433d1cf3f27e44db1533b4fb89","s":"0x1ec37deb9c3c19ab870e9d8d0a28664ba5cdb24827cb415387024752d32ece86"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc8fcbe49bd48d18f1e643d9c30f7eff5b91580ecf18e3cf51a64dc33efef8945","input":"0x","nonce":"0x9d59","to":"0xc1e6d014845c3e9be49b7c7ff404d57eb70bde55","transactionIndex":"0x126","value":"0xb26646c5657000","v":"0x26","r":"0xfc6a142536a53f2c193415f71b30e70873616851a326ff8603d0e2f94bba5e55","s":"0xb6bb5f256d1ac716eeec46450d0be5bc097c1cea3893942edf19c236eda5404"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x808632c02997d355498cfd0958bc6d6234ed895c5714f8038b8156e77092a1dd","input":"0x","nonce":"0x9d5a","to":"0x6eec88f110b7634b7c454ecf6db811bb4e20d1a6","transactionIndex":"0x127","value":"0x30546aba3df2800","v":"0x25","r":"0x5efc9d9e4413f191250d1fa3649568081b18438d460469f38cdf4c4c64e21395","s":"0x548dcec1f369ed12e15e7853b651a9bf123255d7dff536e9651a0732319dba65"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xe501873db84664299077c024d19d5469c9e133f5e9bd473c9f83e1fcc55be399","input":"0x","nonce":"0x9d5b","to":"0x5e27e82fde06a884b709d688a3b054cfbc5d92f3","transactionIndex":"0x128","value":"0xb497a2803e9800","v":"0x26","r":"0x9df43eb8a4464fbf55658e8a1b11acaba33cbb90b8a000a14bd448f1d004799c","s":"0x52e6890fb71ee8e65f2d5127eac2fe795a204455b29909472343477a216c06d"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x3c4957db98859d5b73191adf0adc2721f7fbb1cdb2b89313b7497f2534539622","input":"0x","nonce":"0x9d5c","to":"0x4b916d1e67a42e29365ca2310da3c5c2b4956bb4","transactionIndex":"0x129","value":"0x1762a743bf0e000","v":"0x25","r":"0x2272d8f5f8367dc892ad8fc4d7faac48ae1803eb1cd36f6eed5fdc6c4a40ac9c","s":"0x7e6d5fae5c321780cfd6ea79dc1a2b84ae259128ae1b2b68df70e567d6acc327"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xbca55fac4feaf192382e16e23b7c208e30c86a232a3e217ce03105ce776d4023","input":"0x","nonce":"0x9d5d","to":"0x007ce001301ee96abaa5dbd73e26c1e7b9a16ef5","transactionIndex":"0x12a","value":"0x1e4a2439c7e7800","v":"0x26","r":"0x8fbd9c517cfc6fa4b4d7ea0557f4f60801fb0ae1d955758d03dfce8a7ea068c4","s":"0x6e69a2ed3fa784cea7f7f82e14ed3bd722061607129432d4bb06334b7b80c4ec"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x00a04953f6f4ff9b130e2092117664aa9b8eaedaa7040b0bad7592bb72baafc3","input":"0x","nonce":"0x9d5e","to":"0x0f845cd3da369321429220e6d6e7c3788414e574","transactionIndex":"0x12b","value":"0xb900a526153800","v":"0x25","r":"0x3c743941f289cff5c55e8c83c42dbca60b45919cbede34f337b671bab93de60e","s":"0x12b65e6314dba335249edba1d6bc88caaeec3cddb739203a9b6c40472f0dbfc9"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x7f0d62ed1e4e25dabb2f70af5054792df085ca81c0f6ac64121fa97bbb9e39ee","input":"0x","nonce":"0x9d5f","to":"0x3c5b89b3d97e9e56880e4141e24ead232340e4a3","transactionIndex":"0x12c","value":"0xb5d019cc00e800","v":"0x26","r":"0x63972ff9a057b81f446fb119776e16d055399858b236a6d329e45b3452dca643","s":"0x2626b9cc6f3f156b96f5109544afbd5ec4b8ebb125e2b451c3ffdcded38564c6"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xc1c8699fcd8fd3ba414d9d593a3c1de30ed1c03f18a614c5b1f1e2f63de11b8c","input":"0x","nonce":"0x9d60","to":"0xb6bfb46ed86dc95b9a4ac4f9dc54e5eda66f555c","transactionIndex":"0x12d","value":"0x1db2197d8e18c00","v":"0x25","r":"0xa5c8b14f86f3e193d494437b97cfcc44619ccc2fc5ca6930a83efd20f2497443","s":"0x683705920b7dfae3751b43f068e26aba4332a744f7732f362cfcd25334575540"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0xfc57b690a9eae5e5315cefe3dfd24285dce4a4ed089ab9245acf44d3ddabd446","input":"0x","nonce":"0x9d61","to":"0x5304725b936791740704de8795eec60c8bccc3c6","transactionIndex":"0x12e","value":"0xd1cc30c6e63800","v":"0x26","r":"0xa12ad1d0fc0419d5741a47c63b52e007043e5b18d7fc50212138c50fee9adfc7","s":"0x30685b751f0469cc649b7c3cb8c1a7d9fd92c1bdd0448d16063973a43362245c"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x7dcc1722e10be952d4d7c473965d4c82669a7242ea500b4e55ccbbb23777e19e","input":"0x","nonce":"0x9d62","to":"0x5e708092318a8604d4d353d0f1820e256dfbc618","transactionIndex":"0x12f","value":"0xbe0d6ff05a3800","v":"0x26","r":"0xea10d857e88859602a70352d68ee1222554c472fb6be25ffc21afaac7d645bb","s":"0x1f2ce0b79d3297c8d96089d968f0ae94a7d5485ca9e21270f5316dc6fe5dc081"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x89e7853a2fe1e32daeb2c2b06d4cdb1148587c93c049f63bf45c6e302f498c32","input":"0x","nonce":"0x9d63","to":"0x3992c699ddba35a6c706973c6dedbc92eb99462a","transactionIndex":"0x130","value":"0xbe0d6ff05a3800","v":"0x25","r":"0xeec1bdc4d6689af10104b650081fbc49d70b22502afa77b329f7f2d3f617e148","s":"0x1425e1c182fb4496f44e15ef096f634fbdc003003298c3c5220bffc77a7cc804"},{"blockHash":"0x16f37b728aacdb8491eaf8caa84c090285f204d9f6332931144e2fb7fa9c622b","blockNumber":"0x3f29e9","from":"0xfe92a3cf1843b5ec7ccf27b2ae753fac1289fa9d","gas":"0x15f90","gasPrice":"0xee6b2800","hash":"0x983b78add24766c3f9a35cf0c1a471489e92a897d042d0fb8cb4bea11d760015","input":"0x","nonce":"0x9d64","to":"0x2f19943cc9b0352f0cf60924997a49847eef3699","transactionIndex":"0x131","value":"0x12152a80d452c00","v":"0x26","r":"0x13afc637ad749e2aa15f4756ec96dc14504ba5bbadd3dd1f1163aae862e43d1c","s":"0x56876b68b6f58e4c4347e0125aade9cb493bc845eff0037365e3aef08f90452b"}],"transactionsRoot":"0x83975aaf055a868c2d091539397998b8b2a0eb1b25aec5b7aec46515145cafe8","uncles":[]}} diff --git a/statediff/indexer/ipld/test_data/eth-block-body-json-997522 b/statediff/indexer/ipld/test_data/eth-block-body-json-997522 new file mode 100644 index 000000000..9c385bef3 --- /dev/null +++ b/statediff/indexer/ipld/test_data/eth-block-body-json-997522 @@ -0,0 +1 @@ +{"jsonrpc":"2.0","result":{"author":"0x4bb96091ee9d802ed039c4d1a5f6216f90f81b01","difficulty":"0xae22b2113ed","extraData":"0xd783010400844765746887676f312e352e31856c696e7578","gasLimit":"0x2fefd8","gasUsed":"0x5208","hash":"0x79851e1adb52a8c5490da2df5d8c060b1cc44a3b6eeaada2e20edba5a8e84523","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x4bb96091ee9d802ed039c4d1a5f6216f90f81b01","mixHash":"0x2565992ba4dbd7ab3bb08d1da34051ae1d90c79bc637a21aa2f51f6380bf5f6a","nonce":"0xf7a14147c2320b2d","number":"0xf3892","parentHash":"0x8ad6d5cbe7ec75ed71d5153dd58f2fd413b17c398ad2a7d9309459ce884e6c9b","receiptsRoot":"0xa73a95d90de29c66220c8b8da825cf34ae969efc7f9a878d8ed893565e4b4676","sealFields":["0xa02565992ba4dbd7ab3bb08d1da34051ae1d90c79bc637a21aa2f51f6380bf5f6a","0x88f7a14147c2320b2d"],"sha3Uncles":"0x08793b633d0b21b980107f3e3277c6693f2f3739e0c676a238cbe24d9ae6e252","size":"0x6c0","stateRoot":"0x11e5ea49ecbee25a9b8f267492a5d296ac09cf6179b43bc334242d052bac5963","timestamp":"0x56bf10c5","totalDifficulty":"0x629a0a89232bcd5b","transactions":[{"blockHash":"0x79851e1adb52a8c5490da2df5d8c060b1cc44a3b6eeaada2e20edba5a8e84523","blockNumber":"0xf3892","condition":null,"creates":null,"from":"0x4bb96091ee9d802ed039c4d1a5f6216f90f81b01","gas":"0x15f90","gasPrice":"0xa","hash":"0xd0fc6b051f16468862c462c672532427efef537ea3737b25b10716949d0e2228","input":"0x","networkId":null,"nonce":"0x7c37","publicKey":"0xa9177f27b99a4ad938359d77e0dca4b64e7ce3722c835d8087d4eecb27c8a54d59e2917e6b31ec12e44b1064d102d35815f9707af9571f15e92d1b6fbcd207e9","r":"0x76933e91718154f18db2e993bc96e82abd9a0fac2bae284875341cbecafa837b","raw":"0xf86a827c370a83015f909404a6c6a293340fc3f2244d097b0cfd84d5317ba58844b1eec616322c1c801ba076933e91718154f18db2e993bc96e82abd9a0fac2bae284875341cbecafa837ba02f165c2c4b5f4b786a95e106c48bccc7e065647af5a1942025b6fbfafeabbbf6","s":"0x2f165c2c4b5f4b786a95e106c48bccc7e065647af5a1942025b6fbfafeabbbf6","standardV":"0x0","to":"0x04a6c6a293340fc3f2244d097b0cfd84d5317ba5","transactionIndex":"0x0","v":"0x1b","value":"0x44b1eec616322c1c"}],"transactionsRoot":"0x7ab22cfcf6db5d1628ac888c25e6bc49aba2faaa200fc880f800f1db1e8bd3cc","uncles":["0x319e0dc9a53711579c4ba88062c927a0045443cca57625903ef471d760506a94","0x0324272e484e509c3c9e9e75ad8b48c7d34556e6b269dd72331033fd5cdc1b2a"]},"id":1} diff --git a/statediff/indexer/ipld/test_data/eth-block-body-json-999998 b/statediff/indexer/ipld/test_data/eth-block-body-json-999998 new file mode 100644 index 000000000..5e9d4d77b --- /dev/null +++ b/statediff/indexer/ipld/test_data/eth-block-body-json-999998 @@ -0,0 +1 @@ +{"jsonrpc":"2.0","id":1,"result":{"author":"0xf8b483dba2c3b7176a3da549ad41a48bb3121069","difficulty":"0xb6cb9824e57","extraData":"0xd983010302844765746887676f312e342e328777696e646f7773","gasLimit":"0x2fefd8","gasUsed":"0x3d860","hash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0xf8b483dba2c3b7176a3da549ad41a48bb3121069","mixHash":"0xcaf27314d80cb3e888d32646402d617d8f8379ca23a6b0255e974e407ffdd846","nonce":"0xbc7609306a77d0a2","number":"0xf423e","parentHash":"0xc6fd988b2d086a7b6eee3d25bad453830391014ba268cf6cc5d139741cb51273","receiptsRoot":"0xb0310e47b0cc7d3bb24c65ec21ec0ddf8dcf1672bc9866d6ba67e83d33215568","sealFields":["0xcaf27314d80cb3e888d32646402d617d8f8379ca23a6b0255e974e407ffdd846","0xbc7609306a77d0a2"],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x764","stateRoot":"0xee8306f6cebba17153516cb6586de61d6294b49bc5534eb9378acb848907b277","timestamp":"0x56bfb3ed","totalDifficulty":"0x63053e0134c03db1","transactions":[{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0x6b5da959786d801c1bedda58f8a071a40f992f03","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x679c178c832194d3f40afbda60421e8cb12f2c6b879a925d2e60b15a2b4d212e","input":"0x","networkId":null,"nonce":"0x111","publicKey":"0x1acb54447b8e66222a23fe267f75e9c7ff46538e5c7b286ee14bcf7ec587f9656c5eb2163e6e3d7dbffd677de22e50d7e067dff34de403d14f5ead2eaf8368a5","r":"0xd5ad60765e2006490e73bf06f4bc9b382b2ea434eb066b60bc4f577cb056603a","raw":"0xf86e820111850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880f64f66ddf683000801ca0d5ad60765e2006490e73bf06f4bc9b382b2ea434eb066b60bc4f577cb056603aa00e8d699411b71b08f550a278b05fb1d36174509758ad7370528ae06cb1965a8f","s":"0xe8d699411b71b08f550a278b05fb1d36174509758ad7370528ae06cb1965a8f","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x0","v":"0x1c","value":"0xf64f66ddf683000"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0x9da7521d2b2281b3cd477b553a5dc18b58674f07","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0xfe3189ab9a3c3aaa97a08e9410b6569f7528e38a4c86077ea20ddf33bd2c7ea5","input":"0x","networkId":null,"nonce":"0x79","publicKey":"0xa150bdb9419cf198e7430552880e8b050a09952ae53d1fd82d70941c6be318f21b98dcf93a974b763948c1621e460ec8cead12080fc2759c2e3e4dc884d2308b","r":"0xb31d8d88bfcf7a3dd705bc78a078c75542ca1a993860a3c95b2af317ee3a4b0d","raw":"0xf86c79850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880ef726f7729a1000801ca0b31d8d88bfcf7a3dd705bc78a078c75542ca1a993860a3c95b2af317ee3a4b0da076d529630cef5d1acf0d649faf281ebcb13768effce3eb02a96f5228ad2f5333","s":"0x76d529630cef5d1acf0d649faf281ebcb13768effce3eb02a96f5228ad2f5333","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x1","v":"0x1c","value":"0xef726f7729a1000"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0x707868ea3bfb73007106cfd30f678fdb94d12173","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0xcb7508e8703535fbc801146fa3c7d04798d71a9a0e3bb97a0a14beb733559672","input":"0x","networkId":null,"nonce":"0x251","publicKey":"0x030ad57f373be3cd858bb949365b1438b4383b94fa1b95af0ab5337719539fded4494868e0a82e6df40cddeb9415d8e45a6506ea77c1909c71dd2ec37316da0a","r":"0xbfc3a164f96f95f04ec50af58645d5cf51eaa2473872af9bf23ceab22560e8d6","raw":"0xf86e820251850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88881fc1efd41e37c800801ba0bfc3a164f96f95f04ec50af58645d5cf51eaa2473872af9bf23ceab22560e8d6a053f43d489fd83f8e2c9acbf2d14695c63838c18f420021771f111750aac8efba","s":"0x53f43d489fd83f8e2c9acbf2d14695c63838c18f420021771f111750aac8efba","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x2","v":"0x1b","value":"0x1fc1efd41e37c800"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0xd614cc8e7d44e6e5d48b9b3efd5ffec36098f403","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0xf333f42badd731da2869ce92d95a255f75ac2a16ed043e6b343ed91d4fdbb579","input":"0x","networkId":null,"nonce":"0x18c","publicKey":"0x34ff9f742cb0c7feaf8109a722d4518fd504abedc4f66e4e6bf8ece0726841c132e5660bbabe5dbe83414cda8ddb5b0aae4a649661747a817cfb79045c22d419","r":"0x32a184bbbe6168a2ebfba1be61d3535d45ce580b130eed8df8f5024be97f5bf8","raw":"0xf86e82018c850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880eeee41c060f2400801ca032a184bbbe6168a2ebfba1be61d3535d45ce580b130eed8df8f5024be97f5bf8a071c020aef32840e0f4f5ea2b095faa4602586a471d33c62563146314c4970a93","s":"0x71c020aef32840e0f4f5ea2b095faa4602586a471d33c62563146314c4970a93","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x3","v":"0x1c","value":"0xeeee41c060f2400"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0x078838304c9ee678209ea0959587da9b6f31ebff","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0xfa50db902c56466492e9f32fd543edaa1554a47b2e288175c262685df0537106","input":"0x","networkId":null,"nonce":"0xf46","publicKey":"0x866ede0bed987e0e8736cc94244640df1124b5b789b780bc012b936c2559cc630102e32c1c454f92626542eca44802f3ee44437a031fa1eaabcbdf323891eb93","r":"0x9a569d066c62c64ec8b93c6d268499a276fe882289f6090e65748911ec81b256","raw":"0xf86e820f46850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880e62a83e59ffa400801ca09a569d066c62c64ec8b93c6d268499a276fe882289f6090e65748911ec81b256a01e7b9216b86d6a5517b88a2aaef666732c51486214948fdecd89b9043a30750c","s":"0x1e7b9216b86d6a5517b88a2aaef666732c51486214948fdecd89b9043a30750c","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x4","v":"0x1c","value":"0xe62a83e59ffa400"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0x460825a3542f4823818184020ba3861da1e26872","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x0b4a6c8459c02f647d8a5c667e292de3e45c5f03558a0e814377e5356ebc6234","input":"0x","networkId":null,"nonce":"0x113","publicKey":"0xee1a6b3dc03e8b5329d99b77c33f64767196ce47236b4c9ee2baa87827a6348488926ae6da54abbf788f5d2602dff65984a60020407e7e8b2da160f32e80a344","r":"0x87842eacb46cc63064a8a8f0932ce3f18c0d27f81a8124d2c3a9f751293b11d0","raw":"0xf86e820113850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880efd50e050f64400801ca087842eacb46cc63064a8a8f0932ce3f18c0d27f81a8124d2c3a9f751293b11d0a04e7678e22ce8ec60a04c36fa5685421a3bf8b9d0ff68280a8f31d6db49629afe","s":"0x4e7678e22ce8ec60a04c36fa5685421a3bf8b9d0ff68280a8f31d6db49629afe","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x5","v":"0x1c","value":"0xefd50e050f64400"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0xa29862fb7f9b37374d0c9062ab52bdd74d1af867","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0xc4ea04477167cc599788100bef3306eca140549e747ba531db579eb2a72b1b11","input":"0x","networkId":null,"nonce":"0x59a","publicKey":"0xa3e333b30947a5a685b47b387a92f65a7c5d7b61f6f3016777f720e83fea9fbe5faf6fcb3296e0cd9da6ec9acf30920d5d67c2c4636a79f940b6e2fbe46c14a7","r":"0x90ddc9473c323eebd5c4a35251cd437e62563c883e8e87b141389fde111c5b24","raw":"0xf86e82059a850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880f32a22e7fc0f800801ca090ddc9473c323eebd5c4a35251cd437e62563c883e8e87b141389fde111c5b24a039a1dfc3e2b85c74fce62ed7369ac1a62de13b31f4fb47e5fb02232aeefd83f4","s":"0x39a1dfc3e2b85c74fce62ed7369ac1a62de13b31f4fb47e5fb02232aeefd83f4","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x6","v":"0x1c","value":"0xf32a22e7fc0f800"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0x771dd02681c793eb34eff34528309e3657f843fb","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0xf73f661edcb6e8fc0b48a5bb5292e8b5db8ea911e4664ed1f8af1b2e66f6f585","input":"0x","networkId":null,"nonce":"0x211","publicKey":"0xca6db6e9182a094b5cbfa68741ab7c31450582eb65f1c558798a08b230de63a2f25deedc62d276a5f3eef3526282e28c7efdbbcba8e3ed4dad086c2201f10855","r":"0x7ecfd78b2838d73283f6de62bee1a046830fac75fb5b85ede279dbac097feec6","raw":"0xf86e820211850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d888811a2bd08b7075400801ba07ecfd78b2838d73283f6de62bee1a046830fac75fb5b85ede279dbac097feec6a01cfc1ced8140efc2dc71e217d6693665942ef1424affd7d61c134ed462605922","s":"0x1cfc1ced8140efc2dc71e217d6693665942ef1424affd7d61c134ed462605922","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x7","v":"0x1b","value":"0x11a2bd08b7075400"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0xfbe56e8afb28e097a871b2747800079ad5c29c03","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x9b2569e1b26d29730cf262756a6033834e34345f4a18caa241117747ce8cf746","input":"0x","networkId":null,"nonce":"0x6c","publicKey":"0x7c2ee029ec45aa73444091d1a0c3f830bb7f91797b30a1f53c11a2fbec10f7bb7706a9569350da382cc623c2b65d03b480ae96bc168021da4f0df60146f9e16c","r":"0xb1f3b2754a9189b376bc32d03a1097d4fe0cfaae3e55e45a4249127b9b541399","raw":"0xf86c6c850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880f94ad612cf85000801ca0b1f3b2754a9189b376bc32d03a1097d4fe0cfaae3e55e45a4249127b9b541399a025b51f84e621e9193dfb7172dfdea0379bbf8d5d73e25de0e2d0dc50f657e249","s":"0x25b51f84e621e9193dfb7172dfdea0379bbf8d5d73e25de0e2d0dc50f657e249","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x8","v":"0x1c","value":"0xf94ad612cf85000"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0xe6ea7febb65f6fb46dc42dea2f873c67aadb1f72","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x5ac04be22ee89dce8c33f334a41ab05e1cbeca16669003c5ffe2c220f772b097","input":"0x","networkId":null,"nonce":"0x170","publicKey":"0xa6238a7419a3321706c6612d7cc647bce4568ec6ce4a999d081077feac54ec8d1e2627484782a15a4a2c2eca0a71bee25b5a82a7ca74c84b75f89ec2f8bbb5ea","r":"0x3c26e80876f0901d3007a8798f9792d426b6f78079dcd06d91019677850b9356","raw":"0xf86e820170850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d8888115740dac6be2400801ca03c26e80876f0901d3007a8798f9792d426b6f78079dcd06d91019677850b9356a028a644324a777b7beade6b8432d6f95f85112863e08c50bd3e22d1594244014c","s":"0x28a644324a777b7beade6b8432d6f95f85112863e08c50bd3e22d1594244014c","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x9","v":"0x1c","value":"0x115740dac6be2400"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0x2a65aca4d5fc5b5c859090a6c34d164135398226","gas":"0x15f90","gasPrice":"0xba43b7400","hash":"0x46a83d066750df27119aa3e314641fb3b3ec6e1afc1e768d3da4ac941a6a0a8d","input":"0x","networkId":null,"nonce":"0x2a11d","publicKey":"0x4c3eb5e19c71d8245eaaaba21ef8f94a70e9250848d10ade086f893a7a33a06d7063590e9e6ca88f918d7704840d903298fe802b6047fa7f6d09603eba690c39","r":"0x85bada12a37f21016e8801d6136cd7793192346a0f29f4fd37782d774378a7df","raw":"0xf8708302a11d850ba43b740083015f90945d65e227f4e7bc798cf62526f4bdd47c82e6a590880eb35d6f4e620c00801ca085bada12a37f21016e8801d6136cd7793192346a0f29f4fd37782d774378a7dfa07e1c78a62e1c16b955dc1b56f657c51fe2dfb739c2c1d11fe4845583706719a8","s":"0x7e1c78a62e1c16b955dc1b56f657c51fe2dfb739c2c1d11fe4845583706719a8","standardV":"0x1","to":"0x5d65e227f4e7bc798cf62526f4bdd47c82e6a590","transactionIndex":"0xa","v":"0x1c","value":"0xeb35d6f4e620c00"},{"blockHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","blockNumber":"0xf423e","condition":null,"creates":null,"from":"0x2a65aca4d5fc5b5c859090a6c34d164135398226","gas":"0x15f90","gasPrice":"0xba43b7400","hash":"0x15dd5bba84901824fb3aa75618a92b7cbacb454c53eaa962a2ca8667acb06a78","input":"0x","networkId":null,"nonce":"0x2a11e","publicKey":"0x4c3eb5e19c71d8245eaaaba21ef8f94a70e9250848d10ade086f893a7a33a06d7063590e9e6ca88f918d7704840d903298fe802b6047fa7f6d09603eba690c39","r":"0x1611395215c0ede475af6fd3b647c674d18735851060ccad0e0e7a7c150831c9","raw":"0xf8708302a11e850ba43b740083015f909436fab08874deb6cd0e7f916ddee8957630073d47880eb1fbb47be3f800801ca01611395215c0ede475af6fd3b647c674d18735851060ccad0e0e7a7c150831c9a0333716a13f040cbd8ac43462b9cfa8d602d4a3413825d283705bc3d4b22af8de","s":"0x333716a13f040cbd8ac43462b9cfa8d602d4a3413825d283705bc3d4b22af8de","standardV":"0x1","to":"0x36fab08874deb6cd0e7f916ddee8957630073d47","transactionIndex":"0xb","v":"0x1c","value":"0xeb1fbb47be3f800"}],"transactionsRoot":"0x6414d72a4c223bce7d1309869332b148670eb66af4e3b3ba6d1a55aa0bb3fd4f","uncles":[]}} \ No newline at end of file diff --git a/statediff/indexer/ipld/test_data/eth-block-body-json-999999 b/statediff/indexer/ipld/test_data/eth-block-body-json-999999 new file mode 100644 index 000000000..de007b641 --- /dev/null +++ b/statediff/indexer/ipld/test_data/eth-block-body-json-999999 @@ -0,0 +1 @@ +{"jsonrpc":"2.0","result":{"author":"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5","difficulty":"0xb6b4beb1e8e","extraData":"0xd783010303844765746887676f312e342e32856c696e7578","gasLimit":"0x2fefd8","gasUsed":"0x38658","hash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","logsBloom":"0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000","miner":"0x52bc44d5378309ee2abf1539bf71de1b7d7be3b5","mixHash":"0x5b10f4a08a6c209d426f6158bd24b574f4f7b7aa0099c67c14a1f693b4dd04d0","nonce":"0xf491f46b60fe04b3","number":"0xf423f","parentHash":"0xd33c9dde9fff0ebaa6e71e8b26d2bda15ccf111c7af1b633698ac847667f0fb4","receiptsRoot":"0x7fa0f6ca2a01823208d80801edad37e3e3a003b55c89319b45eb1f97862ad229","sealFields":["0xa05b10f4a08a6c209d426f6158bd24b574f4f7b7aa0099c67c14a1f693b4dd04d0","0x88f491f46b60fe04b3"],"sha3Uncles":"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347","size":"0x6e8","stateRoot":"0xed98aa4b5b19c82fb35364f08508ae0a6dec665fa57663dca94c5d70554cde10","timestamp":"0x56bfb405","totalDifficulty":"0x6305496c80ab5c3f","transactions":[{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0xc3665b8a9224ba8da9a20322f31d599cafa52c5c","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x22879e0bc9602fef59dc0602f9bc385f12632da5cb4eee4b813a0c27159c4d24","input":"0x","networkId":null,"nonce":"0x1d3","publicKey":"0xc3dbee74f1b2b8dbedc417244b7f5a134c6f7769faf9ffe784b3f0fdda7ca52cf914d3f2b3164c009bf939796b77f047ccb4cc113d3bde5b06555b781e0c7149","r":"0x43531017f1569ec692c0bf1ad710ddb5158b60505ea33fb7a21245738539e2d5","raw":"0xf86e8201d3850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d8888102363ac310a4000801ca043531017f1569ec692c0bf1ad710ddb5158b60505ea33fb7a21245738539e2d5a03856c6a1117ff71e9b769ccb6960674038a3326c3dd84c152fc83ada28145a07","s":"0x3856c6a1117ff71e9b769ccb6960674038a3326c3dd84c152fc83ada28145a07","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x0","v":"0x1c","value":"0x102363ac310a4000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x4ce758b0c8aa655b77c14f16bd0190b5715be75a","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x3c634bf5f09f6b5b5ea377df7abb483f422ae5d4ba389c395f14f833de25d362","input":"0x","networkId":null,"nonce":"0x9","publicKey":"0x75022ee25c702fc6a53853843e00e87877e737f9c631a9d831c11693d7e31877a1b09755ab3a5c112decf57339839364b8b9a3c23ada01761b1e3a044e297316","r":"0x8219a4f30cb8dd7d5e1163ac433f207b599d804b0d74ee54c8694014db647700","raw":"0xf86c09850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880ed350879ce50000801ba08219a4f30cb8dd7d5e1163ac433f207b599d804b0d74ee54c8694014db647700a03db2e806986a746d44d675fdbbd7594bb2856946ba257209abfffdd1628141af","s":"0x3db2e806986a746d44d675fdbbd7594bb2856946ba257209abfffdd1628141af","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x1","v":"0x1b","value":"0xed350879ce50000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x30906581413d556de1a018adbe6cc63c88d58512","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x59feccaad599e776cd6635e68b5e19254cca3b38e49437044f1e1d15d00b0576","input":"0x","networkId":null,"nonce":"0x59","publicKey":"0xccf6be26c1eb1c89d5fe958db0112a46e3ac23a95ac0f709ce84a49ae3f20bcf143909bfe67f685caaf362066e1c7e224899f57678bbcecb7a720175bcbb387d","r":"0x1ca26859a6eed116312010359c2e8351d126f31b078a0e2e19aae0acc98d9488","raw":"0xf86c59850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88882b0ca8b9f5f02000801ba01ca26859a6eed116312010359c2e8351d126f31b078a0e2e19aae0acc98d9488a0172c1a299737440a9063af6547d567ca7d269bfc2a9e81ec1de21aa8bd8e17b1","s":"0x172c1a299737440a9063af6547d567ca7d269bfc2a9e81ec1de21aa8bd8e17b1","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x2","v":"0x1b","value":"0x2b0ca8b9f5f02000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x8bec4e6fb1a28820eb1e8ec2d4eae4842ed2f923","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x98a03afa804e248ada5f26e9118ae927d4d3cb60e78c54938dced1cf25ee3567","input":"0x","networkId":null,"nonce":"0x2","publicKey":"0xbc8c89a85804c7859069c13561dbbd8d1d4739ec7d18514c42b3ffea64529cee522a5e20d93373d0074e94c4c7b6eba51c7d2f18ef7c64c37520342acb233795","r":"0xa5aca100a264a8da4a58bef77c5116a6dde42186ac249623c0edcb30189640a","raw":"0xf86c02850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880fd037ba87693800801ba00a5aca100a264a8da4a58bef77c5116a6dde42186ac249623c0edcb30189640aa0783e9439755023b919897574f94337aaac4a1ddc20217e3ac264a7edf813ffdd","s":"0x783e9439755023b919897574f94337aaac4a1ddc20217e3ac264a7edf813ffdd","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x3","v":"0x1b","value":"0xfd037ba87693800"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x4835a9626b02369546502d2949e16b0fda110b0c","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x18f1e6430334ad548bc36fc317016bc9f7a076d1fa50a89fe4e1d095ed3f9562","input":"0x","networkId":null,"nonce":"0xd9","publicKey":"0x91b3b4fe89d112cfc7308619e8aa7de86f14af3f6b6e4e92becb6e29e98207835bbe1a69109c16b14b0eb7285d2b952a9cde6007932afe95e81eefc183f75314","r":"0xb93c6f8dce800a1ec57d70813c4d35e3ffe25a6f1ae9057cf706636cf34d662","raw":"0xf86d81d9850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d888814bac05c835a5400801ba00b93c6f8dce800a1ec57d70813c4d35e3ffe25a6f1ae9057cf706636cf34d662a06d254a5557b7716ef01dd28aa84cc919f397c0a778f3a109a1ee9df2fc530ec0","s":"0x6d254a5557b7716ef01dd28aa84cc919f397c0a778f3a109a1ee9df2fc530ec0","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x4","v":"0x1b","value":"0x14bac05c835a5400"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x9cc72ebf3daaf12c72e48605e1e67b47c95a1911","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0xb1cada8daf63c45750df1ee79eed5a3cf6240e3cebdb6de3f26bc7cf03217bf4","input":"0x","networkId":null,"nonce":"0x34","publicKey":"0x90dff18c1c01d566e6d8bf0190e3e965f98e7f51ccbbe6040f9a9972e88f4ad19f1547406454fbc9e1ebcf4c5f2f1e2df9b9371028fe0a552ecca5f5f0aa4129","r":"0xe9a25c929c26d1a95232ba75aef419a91b470651eb77614695e16c5ba023e383","raw":"0xf86c34850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880f258512af0d4000801ba0e9a25c929c26d1a95232ba75aef419a91b470651eb77614695e16c5ba023e383a0679fb2fc0d0b0f3549967c0894ee7d947f07d238a83ef745bc3ced5143a4af36","s":"0x679fb2fc0d0b0f3549967c0894ee7d947f07d238a83ef745bc3ced5143a4af36","standardV":"0x0","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x5","v":"0x1b","value":"0xf258512af0d4000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x5c51467399bc655f0cc6db88df15946717534633","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x4fa879b491e0779fc035758ec77b93c4e51d528d65b64eb055c015a58deff103","input":"0x","networkId":null,"nonce":"0x6f","publicKey":"0x0b7e2532afc2daa33763002525aa6c7edc25ea97d63baeeb2c6f5094f18dca4a0212b52061f9a9091aad5c4380a6506f9a51ddd2d014e78742bf144a58d6ffa0","r":"0x9e0b8360a36d6d0320aef19bd811431b1a692504549da9f05f9b4d9e329993b9","raw":"0xf86c6f850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88881c54e302456eb400801ca09e0b8360a36d6d0320aef19bd811431b1a692504549da9f05f9b4d9e329993b9a05acff70bd8cf82d9d70b11d4e59dc5d54937475ec394ec846263495f61e5e6ee","s":"0x5acff70bd8cf82d9d70b11d4e59dc5d54937475ec394ec846263495f61e5e6ee","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x6","v":"0x1c","value":"0x1c54e302456eb400"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x055d9d7ec193d1e062c6ec4fa80ef89b5c1258f4","gas":"0x5208","gasPrice":"0xdf8475800","hash":"0x1bea59827ab153b20cee79890d221a80fa6a04e552d667504c592ed314fb6d76","input":"0x","networkId":null,"nonce":"0x46","publicKey":"0xfae19a0ac08d36f0229663d45d0c41ca52c4e295c7af82a1b39515a79025175293400d026e0d41767aac42f8b7e4a6687c5762161457d753f1fc0766614868f9","r":"0xb2803f1bfa237bda762d214f71a4c71a7306f55df2880c77d746024e81ccbaa2","raw":"0xf86c46850df84758008252089432be343b94f860124dc4fee278fdcbd38c102d88880f0447b1edca4000801ca0b2803f1bfa237bda762d214f71a4c71a7306f55df2880c77d746024e81ccbaa2a07aeed35c0cbfbe0ed6552fd55b3f57fdc054eeabd02fc61bf66d9a8843aa593a","s":"0x7aeed35c0cbfbe0ed6552fd55b3f57fdc054eeabd02fc61bf66d9a8843aa593a","standardV":"0x1","to":"0x32be343b94f860124dc4fee278fdcbd38c102d88","transactionIndex":"0x7","v":"0x1c","value":"0xf0447b1edca4000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x8e68c0c9b5275fa684291304af9cafe6ceaf2772","gas":"0x15f90","gasPrice":"0xba43b7400","hash":"0x73e87db1108a2aa852f48e088ca1a2771f9b7c18af8d1bd77a3cdcc72a750c56","input":"0x","networkId":null,"nonce":"0x3","publicKey":"0xa5e423dfcbdbba1fdbb785367a88235fa2569061d72b6c715111ac21cbef8fc1db860acdef85f1408c760f34b28a4f07d950ac15c4b85d5e528e50f546a89b6d","r":"0x6dccb1349919662c40455aee04472ae307195580837510ecf2e6fc428876eb03","raw":"0xf86d03850ba43b740083015f909426016a2b5d872adc1b131a4cd9d4b18789d0d9eb88016345785d8a0000801ba06dccb1349919662c40455aee04472ae307195580837510ecf2e6fc428876eb03a03b84ea9c3c6462ac086a1d789a167c2735896a6b5a40e85a6e45da8884fe27de","s":"0x3b84ea9c3c6462ac086a1d789a167c2735896a6b5a40e85a6e45da8884fe27de","standardV":"0x0","to":"0x26016a2b5d872adc1b131a4cd9d4b18789d0d9eb","transactionIndex":"0x8","v":"0x1b","value":"0x16345785d8a0000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x2a65aca4d5fc5b5c859090a6c34d164135398226","gas":"0x15f90","gasPrice":"0xba43b7400","hash":"0x337a5e90b73f44ffebea73cb3d97738c524f63e1032b30735e43212cff731aee","input":"0x","networkId":null,"nonce":"0x2a11f","publicKey":"0x4c3eb5e19c71d8245eaaaba21ef8f94a70e9250848d10ade086f893a7a33a06d7063590e9e6ca88f918d7704840d903298fe802b6047fa7f6d09603eba690c39","r":"0xaa8909295ff178639df961126970f44b5d894326eb47cead161f6910799a98b8","raw":"0xf8708302a11f850ba43b740083015f90945275c3371ece4d4a5b1e14cf6dbfc2277d58ef92880e93ea6a35f2e000801ba0aa8909295ff178639df961126970f44b5d894326eb47cead161f6910799a98b8a0254d7742eccaf2f4c44bfe638378dcf42bdde9465f231b89003cc7927de5d46e","s":"0x254d7742eccaf2f4c44bfe638378dcf42bdde9465f231b89003cc7927de5d46e","standardV":"0x0","to":"0x5275c3371ece4d4a5b1e14cf6dbfc2277d58ef92","transactionIndex":"0x9","v":"0x1b","value":"0xe93ea6a35f2e000"},{"blockHash":"0xb4fbadf8ea452b139718e2700dc1135cfc81145031c84b7ab27cd710394f7b38","blockNumber":"0xf423f","condition":null,"creates":null,"from":"0x2a65aca4d5fc5b5c859090a6c34d164135398226","gas":"0x15f90","gasPrice":"0xba43b7400","hash":"0xc280ab030e20bc9ef72c87b420d58f598bda753ef80a53136a923848b0c89a5c","input":"0x","networkId":null,"nonce":"0x2a120","publicKey":"0x4c3eb5e19c71d8245eaaaba21ef8f94a70e9250848d10ade086f893a7a33a06d7063590e9e6ca88f918d7704840d903298fe802b6047fa7f6d09603eba690c39","r":"0xcfe3ad31d6612f8d787c45f115cc5b43fb22bcc210b62ae71dc7cbf0a6bea8df","raw":"0xf8708302a120850ba43b740083015f90941c51bf013add0857c5d9cf2f71a7f15ca93d4816880e917c4b10c87400801ca0cfe3ad31d6612f8d787c45f115cc5b43fb22bcc210b62ae71dc7cbf0a6bea8dfa057db8998114fae3c337e99dbd8573d4085691880f4576c6c1f6c5bbfe67d6cf0","s":"0x57db8998114fae3c337e99dbd8573d4085691880f4576c6c1f6c5bbfe67d6cf0","standardV":"0x1","to":"0x1c51bf013add0857c5d9cf2f71a7f15ca93d4816","transactionIndex":"0xa","v":"0x1c","value":"0xe917c4b10c87400"}],"transactionsRoot":"0x447cbd8c48f498a6912b10831cdff59c7fbfcbbe735ca92883d4fa06dcd7ae54","uncles":[]},"id":1} diff --git a/statediff/indexer/ipld/test_data/eth-block-body-rlp-997522 b/statediff/indexer/ipld/test_data/eth-block-body-rlp-997522 new file mode 100644 index 0000000000000000000000000000000000000000..ca176613e46a0b03ceaf15c4c5012d079726c562 GIT binary patch literal 1728 zcmey#w)ZEK_=2u$S5H5GQ~I{>s;KSNe*G)L8*41PE-k-lFeUO_hhNU@1ss*u$+p~z zI~xS*?TpHgW!meTTRu2ew#ef2Bi~ui9tBPD-kC7*-P{Jf3zkPNF8!vMKjDWo;{w5_ zuRP!EdlWUhU#(=)(o56UaGp=B++uy$L`9cXdrf5Wf~rkAf4<$071LPL(WClokLT(| zzg8*mpJ@2O@bR`>_vJGS!d}RWOP>i{_P^Qn*`xzM@}fN+NYBh!dw?-Xf9vDqEs8rC z8Adv2<9ej6DEzjW-(pg;{`(tEK^!e%`vs29xZcdj!qDQLT9VP8o^PmUs%O}mlbKgq zu|PF-ruLHC*H>F_=#^dU5V%fu!tvS1%oj;5`YNB?us=SlUV`4@+G7ZuT$|l=QENl$<*t_ZF z~O?}9Ar2EYA2dODlUl&eMP~Gf)_TCMz-=qnxjaM^}+R7KvwfcEfgZCk}{^l8c?~g5zJ>&c0 z-tpL~)va68x1G5nby>(&dP-M`@P~y?e;uw&cAt__8RNBJZoc2;r}ysuIJDNla~b2U z1wRd@Ofu41?V@7eW1+%Pvbpxc(d1nx;-wlh9oL+6-6Tser4dvxniLt@xE{Cfopc76 z6#GF*u>q72r{hkDy8f5`VoIEF4)?7Zq~lLnap%Ct*^J2b869= z3VT<|9D{Gp^F?=4@5rqNv)3Cl+~%ZRPabQ`zz+rbOB5kkF1_^t0P73as{LZ@{2 MWXe8D+O+v50A5(%GXMYp literal 0 HcmV?d00001 diff --git a/statediff/indexer/ipld/test_data/eth-block-body-rlp-999999 b/statediff/indexer/ipld/test_data/eth-block-body-rlp-999999 new file mode 100644 index 0000000000000000000000000000000000000000..3719c36d3ca61c6709df9dc288efe2268d9f37ad GIT binary patch literal 1768 zcmd_p`#aMM00!{Q9OgEgTWxb$$Dx|ChiDRU%q+$!qPgEDnl^FT*eT29YuR*pik%a= z^qnLm9-`vJJSv2zxnBx(+M^Vf%gS`nIr{1R<_|dUKk)hCecx5J=~b2O;Gk3S)Xi^* z=JNNZ7cB=`#Gz7@@!7=(`xrT0l-M-g2GFF}XJ)E1?Cf2BW88z@Ao17i z)?J74C?dbd?!!btLyngi9*`tWVR`3djo^HK6*UCiMYw+~W`Pf{(PYiVM%+%OPgHt` zB?fp;Awl=lmP>~f`Q_KFkbv>)&qZmHp4Ky=mAinUuWA#cHU3~4_@x^U&9sG&!J+f_ zh%y-nYYY|I6q0Anu3x|p>~4ZW{_nYmd|7)aJXOyQUT^Lam8+@qXJugYGf-`9#%mLI#Lb9U-B9zRr>^r zYl>5m8>;tLRXdaknb1MLj*=1x$@GJZY+LOPijzvc3*YG77b0%*w6)jh`)hU@OTWGp{#O7>O+<^txPj`{JjRXQ+7Al-u_B zcF$-h#Ke85Fh&#P9ughk95ru33pwmn60xe<%VYw#g%$<3q{XwuK#o}+-1X}e6i*#O_~_HUuriJ4YDk}0%#AD5*ADbaw@!^ zqnEF@-Qg~aHN^7brL|*-HYL+;3r*L8uUD({?@X}Zhtkm8BFp|tKig(bjRIYXrKtJN zrbK!C{ueU@G?xKj+|Bwm9W7mZ&p%S(A~{c#ras_MacG77*lFIER93rR$vnMZ5jFizu4H;_q3Nnp>gKz@U!XqS1^dJB}okbz;t_eGXd^ zXs3*NsQi-A+gu8sl@Eq$OIi^l0fgZY7utH8zx-|=p#%Gcbwfa^3UXAkV0^8zgKP)@ zjkqeZgvMKiW#cEX`WWx=p}K5g-}tNmN+)x}a=w3n)mvv*fR5ecN)DE*Qt&c$bU-@5 zLC!6`TXPd6&%(fiSs#m>Vxp_z@h03GMyWgPh4H6?U1x$5$S(z18#||ziGYgO>_4I( z=LymDg^yQ=sezOwY2V2U{FEy|Uc4Hm$4FFA!-OQuS;~uh zMrI7;Z#VKEffha~ZgbsBil@{KI>4P!SWSNLh%mBY?;`F$qOq?8>Np9f zJsX!2lI|>qRyrRx5+JUnQjuNk%>t#edp09cgv;Di@}gmH2(=ybXRb(H7IKxI(p4h-VWHDshbxoar~KH`e0$O1?c!OsOFh>*F6rJZB#^nF`G6Q> zHiuV2$t$C}dH2jy8K*^cNr=cxZ(jF(`EjHDZx$>%nb4an(7dgjQQc_2$XsQ8rpvl+ zA<7%iY%|ET*mWgv!SQnv^Y>)*Ux{vU>R57(F=rWrZu!Pv^Gd|UlGHeUPZrwA$S~4D z8+ZOx%exiL{7yE_`tNTvEfHu5+rRn1teee@%uFrrsU;ch>G_6wCVEEg<(YXY`Q^n6 wHh0`J{Iqo5iBspzEYbv|GFd`meg7}LHr3pzj`!Q=Rr(!auD`wn=%m~P0D29FEC2ui literal 0 HcmV?d00001 diff --git a/statediff/indexer/ipld/test_data/eth-block-header-rlp-999997 b/statediff/indexer/ipld/test_data/eth-block-header-rlp-999997 new file mode 100644 index 0000000000000000000000000000000000000000..3d3cf65afe5412dd633622fc2ff1424362faad06 GIT binary patch literal 539 zcmey#B(b17)pWt*$8PW1A4s}{-Ha@p(QDb5Jo`Iae1fjv_O-8eE|5Lr`{Lg5*s9g7 zThq6lxgvF0$W?kuSBdb4g-(ARu1t2H612zVs(CZ#JFWeqmir6uN!M0C-nt;=rqBb6 z&R6ascLgl>S}dGaZXC7dvgIrrE2|Pi*N&?#3v_hU9wyCpmb&_j*>=L0H!<3gSIo~# znQ$mh{rbIdb8+l~)`M}2(%&vfdg9L29-seMIJP(WYvL2muLp{CLM;!+O7CQ380nym zJ5Sx+Y;QBalWnv9`y0(nk33q!_HVv6<9ahAGjof3YDq?WdcL8aiJnnwPG(+d#e%n& u8+L4CaGTS4J^A-`8@Ve&jVXtAoH-(Q-PTU*$E6kbI;v+e+Sx7(It2i#k%%h* literal 0 HcmV?d00001 diff --git a/statediff/indexer/ipld/test_data/eth-block-header-rlp-999999 b/statediff/indexer/ipld/test_data/eth-block-header-rlp-999999 new file mode 100644 index 0000000000000000000000000000000000000000..6b79b705624905bda92b127e7afe6b319c841be8 GIT binary patch literal 539 zcmey#B(dPK&D?wQ|MTry_FS%8?b6tGlWr6G&-xv3e$5yRw z-I~7b%oVB2Lax$Nx=MsUEOh$oaAmUll%PE>SIwI_-)Zd^wcKBLPrA1H@zw=zXRPv$ zmOP=qIXLA*E5|yn+&5|QOUsh)tn`U32=%!qu)w8eZ;!{98OtVW3pC5z|2n6B|LJ|j zF)KBiul!=WbA4UNg8BvDPH8bV8FAd;V0^pQ{PE)j%v)nR4QIQ)mY?3HbxCt4Bg04s zZQR-3ujTrh`JL>W_21uUW^RjU3ERJgb;k8(MrP&~_tcV%_Vj#1Jrg~n)||||(uxJq v0$&z%LY=pPpw%vGlUgGJ_&!1!)kNZ=cpY^}fnVlTDhW3(Zl#nMIrhW8^pl74-% X+{XjJ~9y(nbM>_ai)#etojs W#{N7^8RR_+e8E3|qp-aG z$l=^GKA=k37!h2RAf#7WM|B--s(ZHFu2ZmqZq%jz4Hq-uy1AgD4o!dph?a1V{tQ6o z&41;!ul3vzExbTnwIEMxE<(GY*R{QfNUSbQcvKG|coOF3%%fK9@e3{Y?Fb2sux1bw zpcc`n6}uYP|9Aw%Uz&TM4e;{|WcLBBL`|AJL_zD43xJ^hf%;bu(Uav8Jwh?Ag`yROC4Y31Oqmp9S8@Zd5AJgDkl412tlsS?ZG=6n}dXR{G=-=5^K*E7G}Q5-{{y1q7_YZ3`B zNf;X7Ordl8XwjubZy3@Kqb#~}l|WLxphrH>iheezDd$i*qp(%w8-p^-@G~TGt&A)ve3G<7|Cro)b4KQ;nH==GKnk{zBO5`%L7z}1G-`QV^VM9S>{MahXDboQbZ zXElg!?e_7fGh&XsfG)?Kghoi9rStOlR3S*obC-OI9u-VO0RG7@bzgW!@wYV7s~wQ% zpy(ro4^Y2yx~`oUGoxxmO151JZ>qXLPX&X{45ZrGEui>|JIj-ZlLvi)g>SwV_b`fzA{0 literal 0 HcmV?d00001 diff --git a/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-000dd0 b/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-000dd0 new file mode 100644 index 0000000000000000000000000000000000000000..2fbe90bd675650b967d5ab654454d827235560fe GIT binary patch literal 83 zcmewn*Z>3zsH$nd}lg jJwogdTiMw)3m9(Rs@>i{rS8?LSHZWX>?D3VgA@S(z^*A@ literal 0 HcmV?d00001 diff --git a/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-113049 b/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-113049 new file mode 100644 index 000000000..e7407c417 --- /dev/null +++ b/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-113049 @@ -0,0 +1 @@ +JN>b$kg$2͠| d \ No newline at end of file diff --git a/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-9d1860 b/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-9d1860 new file mode 100644 index 000000000..d39f6324f --- /dev/null +++ b/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-9d1860 @@ -0,0 +1 @@ +˚?L=d@Ki+ee&R-Er?*Mv(}280@aKj@gEiirhmG4lknQvd++ C9u!Xi literal 0 HcmV?d00001 diff --git a/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-ffc25c b/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-ffc25c new file mode 100644 index 000000000..3044ec772 --- /dev/null +++ b/statediff/indexer/ipld/test_data/eth-storage-trie-rlp-ffc25c @@ -0,0 +1 @@ +Q.ӽbRf-ot6KꀀǿU>z@Ao z*sRq0)%LqT-nQpizDUw49#b{g!LNKVhrL zu$ruM5tlsQcS*c^_ajpA$4`lu;WM8&K7ZtFps|w?i@jtEaX@q`U>Lvz6oH6Bl|WPo zpeO_>f&x?tm?%yfq7y?CNI(InCYS^hW841&Kn`QG(B9=Oi7I=tb|l_tX5?aONlz`w z=t$2u)H5{IGi}Yu%qy*cYT}LEVo;pCpY!4Ny%VChuH&23dG(V2y4>Bt?fu1ZQ}q)~ uJC9zHj0^MI(|zv1!LEdtT$@YVPrqYG7oE55j7z~JZpH;rgK$zEFc|=G=#An4 literal 0 HcmV?d00001 diff --git a/statediff/indexer/ipld/trie_node.go b/statediff/indexer/ipld/trie_node.go new file mode 100644 index 000000000..d66a5f0df --- /dev/null +++ b/statediff/indexer/ipld/trie_node.go @@ -0,0 +1,457 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package ipld + +import ( + "encoding/json" + "fmt" + + "github.com/ipfs/go-cid" + node "github.com/ipfs/go-ipld-format" + + "github.com/ethereum/go-ethereum/rlp" +) + +const ( + extension = "extension" + leaf = "leaf" + branch = "branch" +) + +// TrieNode is the general abstraction for +// ethereum IPLD trie nodes. +type TrieNode struct { + // leaf, extension or branch + nodeKind string + + // If leaf or extension: [0] is key, [1] is val. + // If branch: [0] - [16] are children. + elements []interface{} + + // IPLD block information + cid cid.Cid + rawdata []byte +} + +/* + OUTPUT +*/ + +type trieNodeLeafDecoder func([]interface{}) ([]interface{}, error) + +// decodeTrieNode returns a TrieNode object from an IPLD block's +// cid and rawdata. +func decodeTrieNode(c cid.Cid, b []byte, + leafDecoder trieNodeLeafDecoder) (*TrieNode, error) { + var ( + i, decoded, elements []interface{} + nodeKind string + err error + ) + + if err = rlp.DecodeBytes(b, &i); err != nil { + return nil, err + } + + codec := c.Type() + switch len(i) { + case 2: + nodeKind, decoded, err = decodeCompactKey(i) + if err != nil { + return nil, err + } + + if nodeKind == extension { + elements, err = parseTrieNodeExtension(decoded, codec) + if err != nil { + return nil, err + } + } + if nodeKind == leaf { + elements, err = leafDecoder(decoded) + if err != nil { + return nil, err + } + } + if nodeKind != extension && nodeKind != leaf { + return nil, fmt.Errorf("unexpected nodeKind returned from decoder") + } + case 17: + nodeKind = branch + elements, err = parseTrieNodeBranch(i, codec) + if err != nil { + return nil, err + } + default: + return nil, fmt.Errorf("unknown trie node type") + } + + return &TrieNode{ + nodeKind: nodeKind, + elements: elements, + rawdata: b, + cid: c, + }, nil +} + +// decodeCompactKey takes a compact key, and returns its nodeKind and value. +func decodeCompactKey(i []interface{}) (string, []interface{}, error) { + first := i[0].([]byte) + last := i[1].([]byte) + + switch first[0] / 16 { + case '\x00': + return extension, []interface{}{ + nibbleToByte(first)[2:], + last, + }, nil + case '\x01': + return extension, []interface{}{ + nibbleToByte(first)[1:], + last, + }, nil + case '\x02': + return leaf, []interface{}{ + nibbleToByte(first)[2:], + last, + }, nil + case '\x03': + return leaf, []interface{}{ + nibbleToByte(first)[1:], + last, + }, nil + default: + return "", nil, fmt.Errorf("unknown hex prefix") + } +} + +// parseTrieNodeExtension helper improves readability +func parseTrieNodeExtension(i []interface{}, codec uint64) ([]interface{}, error) { + return []interface{}{ + i[0].([]byte), + keccak256ToCid(codec, i[1].([]byte)), + }, nil +} + +// parseTrieNodeBranch helper improves readability +func parseTrieNodeBranch(i []interface{}, codec uint64) ([]interface{}, error) { + var out []interface{} + + for i, vi := range i { + v, ok := vi.([]byte) + // Sometimes this throws "panic: interface conversion: interface {} is []interface {}, not []uint8" + // Figure out why, and if it is okay to continue + if !ok { + return nil, fmt.Errorf("unable to decode branch node entry into []byte at position: %d value: %+v", i, vi) + } + + switch len(v) { + case 0: + out = append(out, nil) + case 32: + out = append(out, keccak256ToCid(codec, v)) + default: + return nil, fmt.Errorf("unrecognized object: %v", v) + } + } + + return out, nil +} + +/* + Node INTERFACE +*/ + +// Resolve resolves a path through this node, stopping at any link boundary +// and returning the object found as well as the remaining path to traverse +func (t *TrieNode) Resolve(p []string) (interface{}, []string, error) { + switch t.nodeKind { + case extension: + return t.resolveTrieNodeExtension(p) + case leaf: + return t.resolveTrieNodeLeaf(p) + case branch: + return t.resolveTrieNodeBranch(p) + default: + return nil, nil, fmt.Errorf("nodeKind case not implemented") + } +} + +// Tree lists all paths within the object under 'path', and up to the given depth. +// To list the entire object (similar to `find .`) pass "" and -1 +func (t *TrieNode) Tree(p string, depth int) []string { + if p != "" || depth == 0 { + return nil + } + + var out []string + + switch t.nodeKind { + case extension: + var val string + for _, e := range t.elements[0].([]byte) { + val += fmt.Sprintf("%x", e) + } + return []string{val} + case branch: + for i, elem := range t.elements { + if _, ok := elem.(cid.Cid); ok { + out = append(out, fmt.Sprintf("%x", i)) + } + } + return out + + default: + return nil + } +} + +// ResolveLink is a helper function that calls resolve and asserts the +// output is a link +func (t *TrieNode) ResolveLink(p []string) (*node.Link, []string, error) { + obj, rest, err := t.Resolve(p) + if err != nil { + return nil, nil, err + } + + lnk, ok := obj.(*node.Link) + if !ok { + return nil, nil, fmt.Errorf("was not a link") + } + + return lnk, rest, nil +} + +// Copy will go away. It is here to comply with the interface. +func (t *TrieNode) Copy() node.Node { + panic("implement me") +} + +// Links is a helper function that returns all links within this object +func (t *TrieNode) Links() []*node.Link { + var out []*node.Link + + for _, i := range t.elements { + c, ok := i.(cid.Cid) + if ok { + out = append(out, &node.Link{Cid: c}) + } + } + + return out +} + +// Stat will go away. It is here to comply with the interface. +func (t *TrieNode) Stat() (*node.NodeStat, error) { + return &node.NodeStat{}, nil +} + +// Size will go away. It is here to comply with the interface. +func (t *TrieNode) Size() (uint64, error) { + return 0, nil +} + +/* + TrieNode functions +*/ + +// MarshalJSON processes the transaction trie into readable JSON format. +func (t *TrieNode) MarshalJSON() ([]byte, error) { + var out map[string]interface{} + + switch t.nodeKind { + case extension: + fallthrough + case leaf: + var hexPrefix string + for _, e := range t.elements[0].([]byte) { + hexPrefix += fmt.Sprintf("%x", e) + } + + // if we got a byte we need to do this casting otherwise + // it will be marshaled to a base64 encoded value + if _, ok := t.elements[1].([]byte); ok { + var hexVal string + for _, e := range t.elements[1].([]byte) { + hexVal += fmt.Sprintf("%x", e) + } + + t.elements[1] = hexVal + } + + out = map[string]interface{}{ + "type": t.nodeKind, + hexPrefix: t.elements[1], + } + + case branch: + out = map[string]interface{}{ + "type": branch, + "0": t.elements[0], + "1": t.elements[1], + "2": t.elements[2], + "3": t.elements[3], + "4": t.elements[4], + "5": t.elements[5], + "6": t.elements[6], + "7": t.elements[7], + "8": t.elements[8], + "9": t.elements[9], + "a": t.elements[10], + "b": t.elements[11], + "c": t.elements[12], + "d": t.elements[13], + "e": t.elements[14], + "f": t.elements[15], + } + default: + return nil, fmt.Errorf("nodeKind %s not supported", t.nodeKind) + } + + return json.Marshal(out) +} + +// nibbleToByte expands the nibbles of a byte slice into their own bytes. +func nibbleToByte(k []byte) []byte { + var out []byte + + for _, b := range k { + out = append(out, b/16) + out = append(out, b%16) + } + + return out +} + +// Resolve reading conveniences +func (t *TrieNode) resolveTrieNodeExtension(p []string) (interface{}, []string, error) { + nibbles := t.elements[0].([]byte) + idx, rest := shiftFromPath(p, len(nibbles)) + if len(idx) < len(nibbles) { + return nil, nil, fmt.Errorf("not enough nibbles to traverse this extension") + } + + for _, i := range idx { + if getHexIndex(string(i)) == -1 { + return nil, nil, fmt.Errorf("invalid path element") + } + } + + for i, n := range nibbles { + if string(idx[i]) != fmt.Sprintf("%x", n) { + return nil, nil, fmt.Errorf("no such link in this extension") + } + } + + return &node.Link{Cid: t.elements[1].(cid.Cid)}, rest, nil +} + +func (t *TrieNode) resolveTrieNodeLeaf(p []string) (interface{}, []string, error) { + nibbles := t.elements[0].([]byte) + + if len(nibbles) != 0 { + idx, rest := shiftFromPath(p, len(nibbles)) + if len(idx) < len(nibbles) { + return nil, nil, fmt.Errorf("not enough nibbles to traverse this leaf") + } + + for _, i := range idx { + if getHexIndex(string(i)) == -1 { + return nil, nil, fmt.Errorf("invalid path element") + } + } + + for i, n := range nibbles { + if string(idx[i]) != fmt.Sprintf("%x", n) { + return nil, nil, fmt.Errorf("no such link in this extension") + } + } + + p = rest + } + + link, ok := t.elements[1].(node.Node) + if !ok { + return nil, nil, fmt.Errorf("leaf children is not an IPLD node") + } + + return link.Resolve(p) +} + +func (t *TrieNode) resolveTrieNodeBranch(p []string) (interface{}, []string, error) { + idx, rest := shiftFromPath(p, 1) + hidx := getHexIndex(idx) + if hidx == -1 { + return nil, nil, fmt.Errorf("incorrect path") + } + + child := t.elements[hidx] + if child != nil { + return &node.Link{Cid: child.(cid.Cid)}, rest, nil + } + return nil, nil, fmt.Errorf("no such link in this branch") +} + +// shiftFromPath extracts from a given path (as a slice of strings) +// the given number of elements as a single string, returning whatever +// it has not taken. +// +// Examples: +// ["0", "a", "something"] and 1 -> "0" and ["a", "something"] +// ["ab", "c", "d", "1"] and 2 -> "ab" and ["c", "d", "1"] +// ["abc", "d", "1"] and 2 -> "ab" and ["c", "d", "1"] +func shiftFromPath(p []string, i int) (string, []string) { + var ( + out string + rest []string + ) + + for _, pe := range p { + re := "" + for _, c := range pe { + if len(out) < i { + out += string(c) + } else { + re += string(c) + } + } + + if len(out) == i && re != "" { + rest = append(rest, re) + } + } + + return out, rest +} + +// getHexIndex returns to you the integer 0 - 15 equivalent to your +// string character if applicable, or -1 otherwise. +func getHexIndex(s string) int { + if len(s) != 1 { + return -1 + } + + c := s[0] + switch { + case '0' <= c && c <= '9': + return int(c - '0') + case 'a' <= c && c <= 'f': + return int(c - 'a' + 10) + } + + return -1 +} diff --git a/statediff/indexer/mainnet_data/block_12579670.rlp b/statediff/indexer/mainnet_data/block_12579670.rlp new file mode 100644 index 0000000000000000000000000000000000000000..6b4f3f773f278ab72755fa70b9574ae10799bb99 GIT binary patch literal 4454 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 literal 0 HcmV?d00001 diff --git a/statediff/indexer/mainnet_data/block_12600011.rlp b/statediff/indexer/mainnet_data/block_12600011.rlp new file mode 100644 index 0000000000000000000000000000000000000000..96032b0c2152373ca99884090aecef7d84d7ad66 GIT binary patch literal 5883 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 literal 0 HcmV?d00001 diff --git a/statediff/indexer/mainnet_data/block_12619985.rlp b/statediff/indexer/mainnet_data/block_12619985.rlp new file mode 100644 index 0000000000000000000000000000000000000000..0e735313f540a2353b7bbe65abbfa0d23f5bb4cd GIT binary patch literal 4041 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 Z=F2{y1E$Y5=heGk`K(Xwbj`@f{{=n~!tDS6 literal 0 HcmV?d00001 diff --git a/statediff/indexer/mainnet_data/receipts_12600011.rlp b/statediff/indexer/mainnet_data/receipts_12600011.rlp new file mode 100644 index 0000000000000000000000000000000000000000..ae6d4f0c2d082dd5fb959d2df1acc83b64ea7751 GIT binary patch literal 690821 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 F{~tj8_&Wdq literal 0 HcmV?d00001 diff --git a/statediff/indexer/mainnet_data/receipts_12619985.rlp b/statediff/indexer/mainnet_data/receipts_12619985.rlp new file mode 100644 index 0000000000000000000000000000000000000000..a9ba84bd275dc988f3ab79231030dfb3e8c96a6c GIT binary patch literal 571436 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 Rcb}Y#Nf*mb%f-mj{{y6tEmZ&j literal 0 HcmV?d00001 diff --git a/statediff/indexer/mainnet_data/receipts_12625121.rlp b/statediff/indexer/mainnet_data/receipts_12625121.rlp new file mode 100644 index 0000000000000000000000000000000000000000..4d3a8532c2bc91401df73ac14d9328a345b21684 GIT binary patch literal 706015 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 literal 0 HcmV?d00001 diff --git a/statediff/indexer/mainnet_data/receipts_12914664.rlp b/statediff/indexer/mainnet_data/receipts_12914664.rlp new file mode 100644 index 0000000000000000000000000000000000000000..3cf8e88951e7c0e85bc603246dbaf2defdb4a4bf GIT binary patch literal 89259 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. + +package mocks + +import ( + "crypto/ecdsa" + "crypto/elliptic" + "crypto/rand" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + "github.com/ethereum/go-ethereum/statediff/test_helpers" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" + "github.com/ethereum/go-ethereum/trie" +) + +// Test variables +var ( + // block data + TestConfig = params.MainnetChainConfig + BlockNumber = TestConfig.LondonBlock + + // canonical block at London height + // includes 5 transactions: 3 Legacy + 1 EIP-2930 + 1 EIP-1559 + MockHeader = types.Header{ + Time: 0, + Number: new(big.Int).Set(BlockNumber), + Root: common.HexToHash("0x0"), + TxHash: common.HexToHash("0x0"), + ReceiptHash: common.HexToHash("0x0"), + Difficulty: big.NewInt(5000000), + Extra: []byte{}, + BaseFee: big.NewInt(params.InitialBaseFee), + Coinbase: common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476777"), + } + MockTransactions, MockReceipts, SenderAddr = createTransactionsAndReceipts(TestConfig, BlockNumber) + MockBlock = types.NewBlock(&MockHeader, MockTransactions, nil, MockReceipts, new(trie.Trie)) + MockHeaderRlp, _ = rlp.EncodeToBytes(MockBlock.Header()) + + // non-canonical block at London height + // includes 2nd and 5th transactions from the canonical block + MockNonCanonicalHeader = MockHeader + MockNonCanonicalBlockTransactions = types.Transactions{MockTransactions[1], MockTransactions[4]} + MockNonCanonicalBlockReceipts = createNonCanonicalBlockReceipts(TestConfig, BlockNumber, MockNonCanonicalBlockTransactions) + MockNonCanonicalBlock = types.NewBlock(&MockNonCanonicalHeader, MockNonCanonicalBlockTransactions, nil, MockNonCanonicalBlockReceipts, new(trie.Trie)) + MockNonCanonicalHeaderRlp, _ = rlp.EncodeToBytes(MockNonCanonicalBlock.Header()) + + // non-canonical block at London height + 1 + // includes 3rd and 5th transactions from the canonical block + Block2Number = big.NewInt(BlockNumber.Int64() + 1) + MockNonCanonicalHeader2 = types.Header{ + Time: 0, + Number: new(big.Int).Set(Block2Number), + Root: common.HexToHash("0x0"), + TxHash: common.HexToHash("0x0"), + ReceiptHash: common.HexToHash("0x0"), + Difficulty: big.NewInt(6000000), + Extra: []byte{}, + BaseFee: big.NewInt(params.InitialBaseFee), + Coinbase: common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476777"), + } + MockNonCanonicalBlock2Transactions = types.Transactions{MockTransactions[2], MockTransactions[4]} + MockNonCanonicalBlock2Receipts = createNonCanonicalBlockReceipts(TestConfig, Block2Number, MockNonCanonicalBlock2Transactions) + MockNonCanonicalBlock2 = types.NewBlock(&MockNonCanonicalHeader2, MockNonCanonicalBlock2Transactions, nil, MockNonCanonicalBlock2Receipts, new(trie.Trie)) + MockNonCanonicalHeader2Rlp, _ = rlp.EncodeToBytes(MockNonCanonicalBlock2.Header()) + + Address = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476592") + AnotherAddress = common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476593") + ContractAddress = crypto.CreateAddress(SenderAddr, MockTransactions[2].Nonce()) + ContractAddress2 = crypto.CreateAddress(SenderAddr, MockTransactions[3].Nonce()) + MockContractByteCode = []byte{0, 1, 2, 3, 4, 5} + mockTopic11 = common.HexToHash("0x04") + mockTopic12 = common.HexToHash("0x06") + mockTopic21 = common.HexToHash("0x05") + mockTopic22 = common.HexToHash("0x07") + ExpectedPostStatus uint64 = 1 + ExpectedPostState1 = common.Bytes2Hex(common.HexToHash("0x1").Bytes()) + ExpectedPostState2 = common.Bytes2Hex(common.HexToHash("0x2").Bytes()) + ExpectedPostState3 = common.Bytes2Hex(common.HexToHash("0x3").Bytes()) + MockLog1 = &types.Log{ + Address: Address, + Topics: []common.Hash{mockTopic11, mockTopic12}, + Data: []byte{}, + } + MockLog2 = &types.Log{ + Address: AnotherAddress, + Topics: []common.Hash{mockTopic21, mockTopic22}, + Data: []byte{}, + } + MockLog3 = &types.Log{ + Address: Address, + Topics: []common.Hash{mockTopic11, mockTopic22}, + Data: []byte{}, + } + MockLog4 = &types.Log{ + Address: AnotherAddress, + Topics: []common.Hash{mockTopic21, mockTopic12}, + Data: []byte{}, + } + ShortLog1 = &types.Log{ + Address: AnotherAddress, + Topics: []common.Hash{}, + Data: []byte{}, + } + ShortLog2 = &types.Log{ + Address: Address, + Topics: []common.Hash{}, + Data: []byte{}, + } + + // access list entries + AccessListEntry1 = types.AccessTuple{ + Address: Address, + } + AccessListEntry2 = types.AccessTuple{ + Address: AnotherAddress, + StorageKeys: []common.Hash{common.BytesToHash(StorageLeafKey), common.BytesToHash(MockStorageLeafKey)}, + } + AccessListEntry1Model = models.AccessListElementModel{ + BlockNumber: BlockNumber.String(), + Index: 0, + Address: Address.Hex(), + } + AccessListEntry2Model = models.AccessListElementModel{ + BlockNumber: BlockNumber.String(), + Index: 1, + Address: AnotherAddress.Hex(), + StorageKeys: []string{common.BytesToHash(StorageLeafKey).Hex(), common.BytesToHash(MockStorageLeafKey).Hex()}, + } + + // statediff data + storageLocation = common.HexToHash("0") + StorageLeafKey = crypto.Keccak256Hash(storageLocation[:]).Bytes() + mockStorageLocation = common.HexToHash("1") + MockStorageLeafKey = crypto.Keccak256Hash(mockStorageLocation[:]).Bytes() + StorageValue = common.Hex2Bytes("01") + StoragePartialPath = common.Hex2Bytes("20290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e563") + StorageLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + StoragePartialPath, + StorageValue, + }) + + nonce1 = uint64(1) + ContractRoot = "0x821e2556a290c86405f8160a2d662042a431ba456b9db265c79bb837c04be5f0" + ContractCodeHash = common.HexToHash("0x753f98a8d4328b15636e46f66f2cb4bc860100aa17967cc145fcd17d1d4710ea") + ContractLeafKey = test_helpers.AddressToLeafKey(ContractAddress) + ContractAccount, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: nonce1, + Balance: big.NewInt(0), + CodeHash: ContractCodeHash.Bytes(), + Root: common.HexToHash(ContractRoot), + }) + ContractPartialPath = common.Hex2Bytes("3114658a74d9cc9f7acf2c5cd696c3494d7c344d78bfec3add0d91ec4e8d1c45") + ContractLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + ContractPartialPath, + ContractAccount, + }) + + Contract2LeafKey = test_helpers.AddressToLeafKey(ContractAddress2) + storage2Location = common.HexToHash("2") + Storage2LeafKey = crypto.Keccak256Hash(storage2Location[:]).Bytes() + storage3Location = common.HexToHash("3") + Storage3LeafKey = crypto.Keccak256Hash(storage3Location[:]).Bytes() + + nonce0 = uint64(0) + AccountRoot = "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + AccountCodeHash = common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470") + AccountLeafKey = test_helpers.Account2LeafKey + RemovedLeafKey = test_helpers.Account1LeafKey + Account, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: nonce0, + Balance: big.NewInt(1000), + CodeHash: AccountCodeHash.Bytes(), + Root: common.HexToHash(AccountRoot), + }) + AccountPartialPath = common.Hex2Bytes("3957f3e2f04a0764c3a0491b175f69926da61efbcc8f61fa1455fd2d2b4cdd45") + AccountLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + AccountPartialPath, + Account, + }) + + StateDiffs = []sdtypes.StateNode{ + { + Path: []byte{'\x06'}, + NodeType: sdtypes.Leaf, + LeafKey: ContractLeafKey, + NodeValue: ContractLeafNode, + StorageNodes: []sdtypes.StorageNode{ + { + Path: []byte{}, + NodeType: sdtypes.Leaf, + LeafKey: StorageLeafKey, + NodeValue: StorageLeafNode, + }, + { + Path: []byte{'\x03'}, + NodeType: sdtypes.Removed, + LeafKey: RemovedLeafKey, + NodeValue: []byte{}, + }, + }, + }, + { + Path: []byte{'\x0c'}, + NodeType: sdtypes.Leaf, + LeafKey: AccountLeafKey, + NodeValue: AccountLeafNode, + StorageNodes: []sdtypes.StorageNode{}, + }, + { + Path: []byte{'\x02'}, + NodeType: sdtypes.Removed, + LeafKey: RemovedLeafKey, + NodeValue: []byte{}, + }, + { + Path: []byte{'\x07'}, + NodeType: sdtypes.Removed, + LeafKey: Contract2LeafKey, + NodeValue: []byte{}, + StorageNodes: []sdtypes.StorageNode{ + { + Path: []byte{'\x0e'}, + NodeType: sdtypes.Removed, + LeafKey: Storage2LeafKey, + NodeValue: []byte{}, + }, + { + Path: []byte{'\x0f'}, + NodeType: sdtypes.Removed, + LeafKey: Storage3LeafKey, + NodeValue: []byte{}, + }, + }, + }, + } + + // Mock data for testing watched addresses methods + Contract1Address = "0x5d663F5269090bD2A7DC2390c911dF6083D7b28F" + Contract2Address = "0x6Eb7e5C66DB8af2E96159AC440cbc8CDB7fbD26B" + Contract3Address = "0xcfeB164C328CA13EFd3C77E1980d94975aDfedfc" + Contract4Address = "0x0Edf0c4f393a628DE4828B228C48175b3EA297fc" + Contract1CreatedAt = uint64(1) + Contract2CreatedAt = uint64(2) + Contract3CreatedAt = uint64(3) + Contract4CreatedAt = uint64(4) + + LastFilledAt = uint64(0) + WatchedAt1 = uint64(10) + WatchedAt2 = uint64(15) + WatchedAt3 = uint64(20) +) + +type LegacyData struct { + Config *params.ChainConfig + BlockNumber *big.Int + MockHeader types.Header + MockTransactions types.Transactions + MockReceipts types.Receipts + SenderAddr common.Address + MockBlock *types.Block + MockHeaderRlp []byte + Address []byte + AnotherAddress []byte + ContractAddress common.Address + MockContractByteCode []byte + MockLog1 *types.Log + MockLog2 *types.Log + StorageLeafKey []byte + MockStorageLeafKey []byte + StorageLeafNode []byte + ContractLeafKey []byte + ContractAccount []byte + ContractPartialPath []byte + ContractLeafNode []byte + AccountRoot string + AccountLeafNode []byte + StateDiffs []sdtypes.StateNode +} + +func NewLegacyData(config *params.ChainConfig) *LegacyData { + // Block number before london fork. + blockNumber := config.EIP155Block + + mockHeader := types.Header{ + Time: 0, + Number: new(big.Int).Set(blockNumber), + Root: common.HexToHash("0x0"), + TxHash: common.HexToHash("0x0"), + ReceiptHash: common.HexToHash("0x0"), + Difficulty: big.NewInt(5000000), + Extra: []byte{}, + Coinbase: common.HexToAddress("0xaE9BEa628c4Ce503DcFD7E305CaB4e29E7476888"), + } + + mockTransactions, mockReceipts, senderAddr := createLegacyTransactionsAndReceipts(config, blockNumber) + mockBlock := types.NewBlock(&mockHeader, mockTransactions, nil, mockReceipts, new(trie.Trie)) + mockHeaderRlp, _ := rlp.EncodeToBytes(mockBlock.Header()) + contractAddress := crypto.CreateAddress(senderAddr, mockTransactions[2].Nonce()) + + return &LegacyData{ + Config: config, + BlockNumber: blockNumber, + MockHeader: mockHeader, + MockTransactions: mockTransactions, + MockReceipts: mockReceipts, + SenderAddr: senderAddr, + MockBlock: mockBlock, + MockHeaderRlp: mockHeaderRlp, + ContractAddress: contractAddress, + MockContractByteCode: MockContractByteCode, + MockLog1: MockLog1, + MockLog2: MockLog2, + StorageLeafKey: StorageLeafKey, + MockStorageLeafKey: MockStorageLeafKey, + StorageLeafNode: StorageLeafNode, + ContractLeafKey: ContractLeafKey, + ContractAccount: ContractAccount, + ContractPartialPath: ContractPartialPath, + ContractLeafNode: ContractLeafNode, + AccountRoot: AccountRoot, + AccountLeafNode: AccountLeafKey, + StateDiffs: StateDiffs, + } +} + +// createLegacyTransactionsAndReceipts is a helper function to generate signed mock legacy transactions and mock receipts with mock logs +func createLegacyTransactionsAndReceipts(config *params.ChainConfig, blockNumber *big.Int) (types.Transactions, types.Receipts, common.Address) { + // make transactions + trx1 := types.NewTransaction(0, Address, big.NewInt(1000), 50, big.NewInt(100), []byte{}) + trx2 := types.NewTransaction(1, AnotherAddress, big.NewInt(2000), 100, big.NewInt(200), []byte{}) + trx3 := types.NewContractCreation(2, big.NewInt(1500), 75, big.NewInt(150), MockContractByteCode) + + transactionSigner := types.MakeSigner(config, blockNumber) + mockCurve := elliptic.P256() + mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader) + if err != nil { + log.Crit(err.Error()) + } + signedTrx1, err := types.SignTx(trx1, transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + signedTrx2, err := types.SignTx(trx2, transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + signedTrx3, err := types.SignTx(trx3, transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + + senderAddr, err := types.Sender(transactionSigner, signedTrx1) // same for both trx + if err != nil { + log.Crit(err.Error()) + } + + // make receipts + mockReceipt1 := types.NewReceipt(nil, false, 50) + mockReceipt1.Logs = []*types.Log{MockLog1} + mockReceipt1.TxHash = signedTrx1.Hash() + mockReceipt2 := types.NewReceipt(common.HexToHash("0x1").Bytes(), false, 100) + mockReceipt2.Logs = []*types.Log{MockLog2, ShortLog1} + mockReceipt2.TxHash = signedTrx2.Hash() + mockReceipt3 := types.NewReceipt(common.HexToHash("0x2").Bytes(), false, 75) + mockReceipt3.Logs = []*types.Log{} + mockReceipt3.TxHash = signedTrx3.Hash() + + return types.Transactions{signedTrx1, signedTrx2, signedTrx3}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3}, senderAddr +} + +// createTransactionsAndReceipts is a helper function to generate signed mock transactions and mock receipts with mock logs +func createTransactionsAndReceipts(config *params.ChainConfig, blockNumber *big.Int) (types.Transactions, types.Receipts, common.Address) { + // make transactions + trx1 := types.NewTransaction(0, Address, big.NewInt(1000), 50, big.NewInt(100), []byte{}) + trx2 := types.NewTransaction(1, AnotherAddress, big.NewInt(2000), 100, big.NewInt(200), []byte{}) + trx3 := types.NewContractCreation(2, big.NewInt(1500), 75, big.NewInt(150), MockContractByteCode) + trx4 := types.NewTx(&types.AccessListTx{ + ChainID: config.ChainID, + Nonce: 0, + GasPrice: big.NewInt(100), + Gas: 50, + To: &AnotherAddress, + Value: big.NewInt(999), + Data: []byte{}, + AccessList: types.AccessList{ + AccessListEntry1, + AccessListEntry2, + }, + }) + trx5 := types.NewTx(&types.DynamicFeeTx{ + ChainID: config.ChainID, + Nonce: 0, + GasTipCap: big.NewInt(100), + GasFeeCap: big.NewInt(100), + Gas: 50, + To: &AnotherAddress, + Value: big.NewInt(1000), + Data: []byte{}, + AccessList: types.AccessList{ + AccessListEntry1, + AccessListEntry2, + }, + }) + + transactionSigner := types.MakeSigner(config, blockNumber) + mockCurve := elliptic.P256() + mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader) + if err != nil { + log.Crit(err.Error()) + } + signedTrx1, err := types.SignTx(trx1, transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + signedTrx2, err := types.SignTx(trx2, transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + signedTrx3, err := types.SignTx(trx3, transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + signedTrx4, err := types.SignTx(trx4, transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + signedTrx5, err := types.SignTx(trx5, transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + + senderAddr, err := types.Sender(transactionSigner, signedTrx1) // same for both trx + if err != nil { + log.Crit(err.Error()) + } + + // make receipts + mockReceipt1 := types.NewReceipt(nil, false, 50) + mockReceipt1.Logs = []*types.Log{MockLog1} + mockReceipt1.TxHash = signedTrx1.Hash() + mockReceipt2 := types.NewReceipt(common.HexToHash("0x1").Bytes(), false, 100) + mockReceipt2.Logs = []*types.Log{MockLog2, ShortLog1} + mockReceipt2.TxHash = signedTrx2.Hash() + mockReceipt3 := types.NewReceipt(common.HexToHash("0x2").Bytes(), false, 75) + mockReceipt3.Logs = []*types.Log{} + mockReceipt3.TxHash = signedTrx3.Hash() + mockReceipt4 := &types.Receipt{ + Type: types.AccessListTxType, + PostState: common.HexToHash("0x3").Bytes(), + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 175, + Logs: []*types.Log{MockLog3, MockLog4, ShortLog2}, + TxHash: signedTrx4.Hash(), + } + mockReceipt5 := &types.Receipt{ + Type: types.DynamicFeeTxType, + PostState: common.HexToHash("0x3").Bytes(), + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 175, + Logs: []*types.Log{}, + TxHash: signedTrx5.Hash(), + } + + return types.Transactions{signedTrx1, signedTrx2, signedTrx3, signedTrx4, signedTrx5}, types.Receipts{mockReceipt1, mockReceipt2, mockReceipt3, mockReceipt4, mockReceipt5}, senderAddr +} + +// createNonCanonicalBlockReceipts is a helper function to generate mock receipts with mock logs for non-canonical blocks +func createNonCanonicalBlockReceipts(config *params.ChainConfig, blockNumber *big.Int, transactions types.Transactions) types.Receipts { + transactionSigner := types.MakeSigner(config, blockNumber) + mockCurve := elliptic.P256() + mockPrvKey, err := ecdsa.GenerateKey(mockCurve, rand.Reader) + if err != nil { + log.Crit(err.Error()) + } + + signedTrx0, err := types.SignTx(transactions[0], transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + + signedTrx1, err := types.SignTx(transactions[1], transactionSigner, mockPrvKey) + if err != nil { + log.Crit(err.Error()) + } + + mockReceipt0 := types.NewReceipt(common.HexToHash("0x3").Bytes(), false, 300) + mockReceipt0.Logs = []*types.Log{MockLog1, ShortLog1} + mockReceipt0.TxHash = signedTrx0.Hash() + + mockReceipt1 := &types.Receipt{ + Type: types.DynamicFeeTxType, + PostState: common.HexToHash("0x4").Bytes(), + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 300, + Logs: []*types.Log{}, + TxHash: signedTrx1.Hash(), + } + + return types.Receipts{mockReceipt0, mockReceipt1} +} + +// Helper methods for testing watched addresses methods +func GetInsertWatchedAddressesArgs() []sdtypes.WatchAddressArg { + return []sdtypes.WatchAddressArg{ + { + Address: Contract1Address, + CreatedAt: Contract1CreatedAt, + }, + { + Address: Contract2Address, + CreatedAt: Contract2CreatedAt, + }, + } +} + +func GetInsertAlreadyWatchedAddressesArgs() []sdtypes.WatchAddressArg { + return []sdtypes.WatchAddressArg{ + { + Address: Contract3Address, + CreatedAt: Contract3CreatedAt, + }, + { + Address: Contract2Address, + CreatedAt: Contract2CreatedAt, + }, + } +} + +func GetRemoveWatchedAddressesArgs() []sdtypes.WatchAddressArg { + return []sdtypes.WatchAddressArg{ + { + Address: Contract3Address, + CreatedAt: Contract3CreatedAt, + }, + { + Address: Contract2Address, + CreatedAt: Contract2CreatedAt, + }, + } +} + +func GetRemoveNonWatchedAddressesArgs() []sdtypes.WatchAddressArg { + return []sdtypes.WatchAddressArg{ + { + Address: Contract1Address, + CreatedAt: Contract1CreatedAt, + }, + { + Address: Contract2Address, + CreatedAt: Contract2CreatedAt, + }, + } +} + +func GetSetWatchedAddressesArgs() []sdtypes.WatchAddressArg { + return []sdtypes.WatchAddressArg{ + { + Address: Contract1Address, + CreatedAt: Contract1CreatedAt, + }, + { + Address: Contract2Address, + CreatedAt: Contract2CreatedAt, + }, + { + Address: Contract3Address, + CreatedAt: Contract3CreatedAt, + }, + } +} + +func GetSetAlreadyWatchedAddressesArgs() []sdtypes.WatchAddressArg { + return []sdtypes.WatchAddressArg{ + { + Address: Contract4Address, + CreatedAt: Contract4CreatedAt, + }, + { + Address: Contract2Address, + CreatedAt: Contract2CreatedAt, + }, + { + Address: Contract3Address, + CreatedAt: Contract3CreatedAt, + }, + } +} diff --git a/statediff/indexer/models/batch.go b/statediff/indexer/models/batch.go new file mode 100644 index 000000000..76858c96f --- /dev/null +++ b/statediff/indexer/models/batch.go @@ -0,0 +1,126 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package models + +import "github.com/lib/pq" + +// IPLDBatch holds the arguments for a batch insert of IPLD data +type IPLDBatch struct { + BlockNumbers []string + Keys []string + Values [][]byte +} + +// UncleBatch holds the arguments for a batch insert of uncle data +type UncleBatch struct { + BlockNumbers []string + HeaderID []string + BlockHashes []string + ParentHashes []string + CIDs []string + MhKeys []string + Rewards []string +} + +// TxBatch holds the arguments for a batch insert of tx data +type TxBatch struct { + BlockNumbers []string + HeaderIDs []string + Indexes []int64 + TxHashes []string + CIDs []string + MhKeys []string + Dsts []string + Srcs []string + Datas [][]byte + Types []uint8 +} + +// AccessListBatch holds the arguments for a batch insert of access list data +type AccessListBatch struct { + BlockNumbers []string + Indexes []int64 + TxIDs []string + Addresses []string + StorageKeysSets []pq.StringArray +} + +// ReceiptBatch holds the arguments for a batch insert of receipt data +type ReceiptBatch struct { + BlockNumbers []string + HeaderIDs []string + TxIDs []string + LeafCIDs []string + LeafMhKeys []string + PostStatuses []uint64 + PostStates []string + Contracts []string + ContractHashes []string + LogRoots []string +} + +// LogBatch holds the arguments for a batch insert of log data +type LogBatch struct { + BlockNumbers []string + HeaderIDs []string + LeafCIDs []string + LeafMhKeys []string + ReceiptIDs []string + Addresses []string + Indexes []int64 + Datas [][]byte + Topic0s []string + Topic1s []string + Topic2s []string + Topic3s []string +} + +// StateBatch holds the arguments for a batch insert of state data +type StateBatch struct { + BlockNumbers []string + HeaderIDs []string + Paths [][]byte + StateKeys []string + NodeTypes []int + CIDs []string + MhKeys []string + Diff bool +} + +// AccountBatch holds the arguments for a batch insert of account data +type AccountBatch struct { + BlockNumbers []string + HeaderIDs []string + StatePaths [][]byte + Balances []string + Nonces []uint64 + CodeHashes [][]byte + StorageRoots []string +} + +// StorageBatch holds the arguments for a batch insert of storage data +type StorageBatch struct { + BlockNumbers []string + HeaderIDs []string + StatePaths [][]string + Paths [][]byte + StorageKeys []string + NodeTypes []int + CIDs []string + MhKeys []string + Diff bool +} diff --git a/statediff/indexer/models/models.go b/statediff/indexer/models/models.go new file mode 100644 index 000000000..be44e37c7 --- /dev/null +++ b/statediff/indexer/models/models.go @@ -0,0 +1,169 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package models + +import "github.com/lib/pq" + +// IPLDModel is the db model for public.blocks +type IPLDModel struct { + BlockNumber string `db:"block_number"` + Key string `db:"key"` + Data []byte `db:"data"` +} + +// HeaderModel is the db model for eth.header_cids +type HeaderModel struct { + BlockNumber string `db:"block_number"` + BlockHash string `db:"block_hash"` + ParentHash string `db:"parent_hash"` + CID string `db:"cid"` + MhKey string `db:"mh_key"` + TotalDifficulty string `db:"td"` + NodeID string `db:"node_id"` + Reward string `db:"reward"` + StateRoot string `db:"state_root"` + UncleRoot string `db:"uncle_root"` + TxRoot string `db:"tx_root"` + RctRoot string `db:"receipt_root"` + Bloom []byte `db:"bloom"` + Timestamp uint64 `db:"timestamp"` + TimesValidated int64 `db:"times_validated"` + Coinbase string `db:"coinbase"` +} + +// UncleModel is the db model for eth.uncle_cids +type UncleModel struct { + BlockNumber string `db:"block_number"` + HeaderID string `db:"header_id"` + BlockHash string `db:"block_hash"` + ParentHash string `db:"parent_hash"` + CID string `db:"cid"` + MhKey string `db:"mh_key"` + Reward string `db:"reward"` +} + +// TxModel is the db model for eth.transaction_cids +type TxModel struct { + BlockNumber string `db:"block_number"` + HeaderID string `db:"header_id"` + Index int64 `db:"index"` + TxHash string `db:"tx_hash"` + CID string `db:"cid"` + MhKey string `db:"mh_key"` + Dst string `db:"dst"` + Src string `db:"src"` + Data []byte `db:"tx_data"` + Type uint8 `db:"tx_type"` + Value string `db:"value"` +} + +// AccessListElementModel is the db model for eth.access_list_entry +type AccessListElementModel struct { + BlockNumber string `db:"block_number"` + Index int64 `db:"index"` + TxID string `db:"tx_id"` + Address string `db:"address"` + StorageKeys pq.StringArray `db:"storage_keys"` +} + +// ReceiptModel is the db model for eth.receipt_cids +type ReceiptModel struct { + BlockNumber string `db:"block_number"` + HeaderID string `db:"header_id"` + TxID string `db:"tx_id"` + LeafCID string `db:"leaf_cid"` + LeafMhKey string `db:"leaf_mh_key"` + PostStatus uint64 `db:"post_status"` + PostState string `db:"post_state"` + Contract string `db:"contract"` + ContractHash string `db:"contract_hash"` + LogRoot string `db:"log_root"` +} + +// StateNodeModel is the db model for eth.state_cids +type StateNodeModel struct { + BlockNumber string `db:"block_number"` + HeaderID string `db:"header_id"` + Path []byte `db:"state_path"` + StateKey string `db:"state_leaf_key"` + NodeType int `db:"node_type"` + CID string `db:"cid"` + MhKey string `db:"mh_key"` + Diff bool `db:"diff"` +} + +// StorageNodeModel is the db model for eth.storage_cids +type StorageNodeModel struct { + BlockNumber string `db:"block_number"` + HeaderID string `db:"header_id"` + StatePath []byte `db:"state_path"` + Path []byte `db:"storage_path"` + StorageKey string `db:"storage_leaf_key"` + NodeType int `db:"node_type"` + CID string `db:"cid"` + MhKey string `db:"mh_key"` + Diff bool `db:"diff"` +} + +// StorageNodeWithStateKeyModel is a db model for eth.storage_cids + eth.state_cids.state_key +type StorageNodeWithStateKeyModel struct { + BlockNumber string `db:"block_number"` + HeaderID string `db:"header_id"` + StatePath []byte `db:"state_path"` + Path []byte `db:"storage_path"` + StateKey string `db:"state_leaf_key"` + StorageKey string `db:"storage_leaf_key"` + NodeType int `db:"node_type"` + CID string `db:"cid"` + MhKey string `db:"mh_key"` + Diff bool `db:"diff"` +} + +// StateAccountModel is a db model for an eth state account (decoded value of state leaf node) +type StateAccountModel struct { + BlockNumber string `db:"block_number"` + HeaderID string `db:"header_id"` + StatePath []byte `db:"state_path"` + Balance string `db:"balance"` + Nonce uint64 `db:"nonce"` + CodeHash []byte `db:"code_hash"` + StorageRoot string `db:"storage_root"` +} + +// LogsModel is the db model for eth.logs +type LogsModel struct { + BlockNumber string `db:"block_number"` + HeaderID string `db:"header_id"` + ReceiptID string `db:"rct_id"` + LeafCID string `db:"leaf_cid"` + LeafMhKey string `db:"leaf_mh_key"` + Address string `db:"address"` + Index int64 `db:"index"` + Data []byte `db:"log_data"` + Topic0 string `db:"topic0"` + Topic1 string `db:"topic1"` + Topic2 string `db:"topic2"` + Topic3 string `db:"topic3"` +} + +// KnownGaps is the data structure for eth_meta.known_gaps +type KnownGapsModel struct { + StartingBlockNumber string `db:"starting_block_number"` + EndingBlockNumber string `db:"ending_block_number"` + CheckedOut bool `db:"checked_out"` + ProcessingKey int64 `db:"processing_key"` +} diff --git a/statediff/indexer/node/node.go b/statediff/indexer/node/node.go new file mode 100644 index 000000000..527546efa --- /dev/null +++ b/statediff/indexer/node/node.go @@ -0,0 +1,25 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package node + +type Info struct { + GenesisBlock string + NetworkID string + ChainID uint64 + ID string + ClientName string +} diff --git a/statediff/indexer/shared/constants.go b/statediff/indexer/shared/constants.go new file mode 100644 index 000000000..6d1e298ad --- /dev/null +++ b/statediff/indexer/shared/constants.go @@ -0,0 +1,23 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package shared + +const ( + RemovedNodeStorageCID = "bagmacgzayxjemamg64rtzet6pwznzrydydsqbnstzkbcoo337lmaixmfurya" + RemovedNodeStateCID = "baglacgzayxjemamg64rtzet6pwznzrydydsqbnstzkbcoo337lmaixmfurya" + RemovedNodeMhKey = "/blocks/DMQMLUSGAGDPOIZ4SJ7H3MW4Y4B4BZIAWZJ4VARHHN57VWAELWC2I4A" +) diff --git a/statediff/indexer/shared/db_kind.go b/statediff/indexer/shared/db_kind.go new file mode 100644 index 000000000..7e7997f95 --- /dev/null +++ b/statediff/indexer/shared/db_kind.go @@ -0,0 +1,46 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package shared + +import ( + "fmt" + "strings" +) + +// DBType to explicitly type the kind of DB +type DBType string + +const ( + POSTGRES DBType = "Postgres" + DUMP DBType = "Dump" + FILE DBType = "File" + UNKNOWN DBType = "Unknown" +) + +// ResolveDBType resolves a DBType from a provided string +func ResolveDBType(str string) (DBType, error) { + switch strings.ToLower(str) { + case "postgres", "pg": + return POSTGRES, nil + case "dump", "d": + return DUMP, nil + case "file", "f", "fs": + return FILE, nil + default: + return UNKNOWN, fmt.Errorf("unrecognized db type string: %s", str) + } +} diff --git a/statediff/indexer/shared/functions.go b/statediff/indexer/shared/functions.go new file mode 100644 index 000000000..8b0acbb54 --- /dev/null +++ b/statediff/indexer/shared/functions.go @@ -0,0 +1,57 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package shared + +import ( + "github.com/ethereum/go-ethereum/common" + "github.com/ipfs/go-cid" + blockstore "github.com/ipfs/go-ipfs-blockstore" + dshelp "github.com/ipfs/go-ipfs-ds-help" + "github.com/multiformats/go-multihash" +) + +// HandleZeroAddrPointer will return an empty string for a nil address pointer +func HandleZeroAddrPointer(to *common.Address) string { + if to == nil { + return "" + } + return to.Hex() +} + +// HandleZeroAddr will return an empty string for a 0 value address +func HandleZeroAddr(to common.Address) string { + if to.Hex() == "0x0000000000000000000000000000000000000000" { + return "" + } + return to.Hex() +} + +// MultihashKeyFromCID converts a cid into a blockstore-prefixed multihash db key string +func MultihashKeyFromCID(c cid.Cid) string { + dbKey := dshelp.MultihashToDsKey(c.Hash()) + return blockstore.BlockPrefix.String() + dbKey.String() +} + +// MultihashKeyFromKeccak256 converts keccak256 hash bytes into a blockstore-prefixed multihash db key string +func MultihashKeyFromKeccak256(hash common.Hash) (string, error) { + mh, err := multihash.Encode(hash.Bytes(), multihash.KECCAK_256) + if err != nil { + return "", err + } + dbKey := dshelp.MultihashToDsKey(mh) + return blockstore.BlockPrefix.String() + dbKey.String(), nil +} diff --git a/statediff/indexer/shared/reward.go b/statediff/indexer/shared/reward.go new file mode 100644 index 000000000..3d5752e25 --- /dev/null +++ b/statediff/indexer/shared/reward.go @@ -0,0 +1,76 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package shared + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/core/types" +) + +func CalcEthBlockReward(header *types.Header, uncles []*types.Header, txs types.Transactions, receipts types.Receipts) *big.Int { + staticBlockReward := staticRewardByBlockNumber(header.Number.Uint64()) + transactionFees := calcEthTransactionFees(txs, receipts) + uncleInclusionRewards := calcEthUncleInclusionRewards(header, uncles) + tmp := transactionFees.Add(transactionFees, uncleInclusionRewards) + return tmp.Add(tmp, staticBlockReward) +} + +func CalcUncleMinerReward(blockNumber, uncleBlockNumber uint64) *big.Int { + staticBlockReward := staticRewardByBlockNumber(blockNumber) + rewardDiv8 := staticBlockReward.Div(staticBlockReward, big.NewInt(8)) + mainBlock := new(big.Int).SetUint64(blockNumber) + uncleBlock := new(big.Int).SetUint64(uncleBlockNumber) + uncleBlockPlus8 := uncleBlock.Add(uncleBlock, big.NewInt(8)) + uncleBlockPlus8MinusMainBlock := uncleBlockPlus8.Sub(uncleBlockPlus8, mainBlock) + return rewardDiv8.Mul(rewardDiv8, uncleBlockPlus8MinusMainBlock) +} + +func staticRewardByBlockNumber(blockNumber uint64) *big.Int { + staticBlockReward := new(big.Int) + //https://blog.ethereum.org/2017/10/12/byzantium-hf-announcement/ + if blockNumber >= 7280000 { + staticBlockReward.SetString("2000000000000000000", 10) + } else if blockNumber >= 4370000 { + staticBlockReward.SetString("3000000000000000000", 10) + } else { + staticBlockReward.SetString("5000000000000000000", 10) + } + return staticBlockReward +} + +func calcEthTransactionFees(txs types.Transactions, receipts types.Receipts) *big.Int { + transactionFees := new(big.Int) + for i, transaction := range txs { + receipt := receipts[i] + gasPrice := big.NewInt(transaction.GasPrice().Int64()) + gasUsed := big.NewInt(int64(receipt.GasUsed)) + transactionFee := gasPrice.Mul(gasPrice, gasUsed) + transactionFees = transactionFees.Add(transactionFees, transactionFee) + } + return transactionFees +} + +func calcEthUncleInclusionRewards(header *types.Header, uncles []*types.Header) *big.Int { + uncleInclusionRewards := new(big.Int) + for range uncles { + staticBlockReward := staticRewardByBlockNumber(header.Number.Uint64()) + staticBlockReward.Div(staticBlockReward, big.NewInt(32)) + uncleInclusionRewards.Add(uncleInclusionRewards, staticBlockReward) + } + return uncleInclusionRewards +} diff --git a/statediff/indexer/test/test.go b/statediff/indexer/test/test.go new file mode 100644 index 000000000..dedcd3655 --- /dev/null +++ b/statediff/indexer/test/test.go @@ -0,0 +1,1274 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package test + +import ( + "bytes" + "context" + "sort" + "testing" + + "github.com/ipfs/go-cid" + blockstore "github.com/ipfs/go-ipfs-blockstore" + dshelp "github.com/ipfs/go-ipfs-ds-help" + "github.com/stretchr/testify/require" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + "github.com/ethereum/go-ethereum/statediff/indexer/shared" + "github.com/ethereum/go-ethereum/statediff/indexer/test_helpers" +) + +// SetupTestData indexes a single mock block along with it's state nodes +func SetupTestData(t *testing.T, ind interfaces.StateDiffIndexer) { + var tx interfaces.Batch + tx, err = ind.PushBlock( + mockBlock, + mocks.MockReceipts, + mocks.MockBlock.Difficulty()) + if err != nil { + t.Fatal(err) + } + defer func() { + if err := tx.Submit(err); err != nil { + t.Fatal(err) + } + }() + for _, node := range mocks.StateDiffs { + err = ind.PushStateNode(tx, node, mockBlock.Hash().String()) + require.NoError(t, err) + } + + if batchTx, ok := tx.(*sql.BatchTx); ok { + require.Equal(t, mocks.BlockNumber.String(), batchTx.BlockNumber) + } else if batchTx, ok := tx.(*file.BatchTx); ok { + require.Equal(t, mocks.BlockNumber.String(), batchTx.BlockNumber) + } +} + +func TestPublishAndIndexHeaderIPLDs(t *testing.T, db sql.Database) { + pgStr := `SELECT cid, cast(td AS TEXT), cast(reward AS TEXT), block_hash, coinbase + FROM eth.header_cids + WHERE block_number = $1` + // check header was properly indexed + type res struct { + CID string + TD string + Reward string + BlockHash string `db:"block_hash"` + Coinbase string `db:"coinbase"` + } + header := new(res) + err = db.QueryRow(context.Background(), pgStr, mocks.BlockNumber.Uint64()).Scan( + &header.CID, + &header.TD, + &header.Reward, + &header.BlockHash, + &header.Coinbase) + if err != nil { + t.Fatal(err) + } + require.Equal(t, headerCID.String(), header.CID) + require.Equal(t, mocks.MockBlock.Difficulty().String(), header.TD) + require.Equal(t, "2000000000000021250", header.Reward) + require.Equal(t, mocks.MockHeader.Coinbase.String(), header.Coinbase) + dc, err := cid.Decode(header.CID) + if err != nil { + t.Fatal(err) + } + mhKey := dshelp.MultihashToDsKey(dc.Hash()) + prefixedKey := blockstore.BlockPrefix.String() + mhKey.String() + var data []byte + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, mocks.MockHeaderRlp, data) +} + +func TestPublishAndIndexTransactionIPLDs(t *testing.T, db sql.Database) { + // check that txs were properly indexed and published + trxs := make([]string, 0) + pgStr := `SELECT transaction_cids.cid FROM eth.transaction_cids INNER JOIN eth.header_cids ON (transaction_cids.header_id = header_cids.block_hash) + WHERE header_cids.block_number = $1` + err = db.Select(context.Background(), &trxs, pgStr, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, 5, len(trxs)) + expectTrue(t, test_helpers.ListContainsString(trxs, trx1CID.String())) + expectTrue(t, test_helpers.ListContainsString(trxs, trx2CID.String())) + expectTrue(t, test_helpers.ListContainsString(trxs, trx3CID.String())) + expectTrue(t, test_helpers.ListContainsString(trxs, trx4CID.String())) + expectTrue(t, test_helpers.ListContainsString(trxs, trx5CID.String())) + + transactions := mocks.MockBlock.Transactions() + type txResult struct { + TxType uint8 `db:"tx_type"` + Value string + } + for _, c := range trxs { + dc, err := cid.Decode(c) + if err != nil { + t.Fatal(err) + } + mhKey := dshelp.MultihashToDsKey(dc.Hash()) + prefixedKey := blockstore.BlockPrefix.String() + mhKey.String() + var data []byte + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + txTypeAndValueStr := `SELECT tx_type, CAST(value as TEXT) FROM eth.transaction_cids WHERE cid = $1` + switch c { + case trx1CID.String(): + require.Equal(t, tx1, data) + txRes := new(txResult) + err = db.QueryRow(context.Background(), txTypeAndValueStr, c).Scan(&txRes.TxType, &txRes.Value) + if err != nil { + t.Fatal(err) + } + if txRes.TxType != 0 { + t.Fatalf("expected LegacyTxType (0), got %d", txRes.TxType) + } + if txRes.Value != transactions[0].Value().String() { + t.Fatalf("expected tx value %s got %s", transactions[0].Value().String(), txRes.Value) + } + case trx2CID.String(): + require.Equal(t, tx2, data) + txRes := new(txResult) + err = db.QueryRow(context.Background(), txTypeAndValueStr, c).Scan(&txRes.TxType, &txRes.Value) + if err != nil { + t.Fatal(err) + } + if txRes.TxType != 0 { + t.Fatalf("expected LegacyTxType (0), got %d", txRes.TxType) + } + if txRes.Value != transactions[1].Value().String() { + t.Fatalf("expected tx value %s got %s", transactions[1].Value().String(), txRes.Value) + } + case trx3CID.String(): + require.Equal(t, tx3, data) + txRes := new(txResult) + err = db.QueryRow(context.Background(), txTypeAndValueStr, c).Scan(&txRes.TxType, &txRes.Value) + if err != nil { + t.Fatal(err) + } + if txRes.TxType != 0 { + t.Fatalf("expected LegacyTxType (0), got %d", txRes.TxType) + } + if txRes.Value != transactions[2].Value().String() { + t.Fatalf("expected tx value %s got %s", transactions[2].Value().String(), txRes.Value) + } + case trx4CID.String(): + require.Equal(t, tx4, data) + txRes := new(txResult) + err = db.QueryRow(context.Background(), txTypeAndValueStr, c).Scan(&txRes.TxType, &txRes.Value) + if err != nil { + t.Fatal(err) + } + if txRes.TxType != types.AccessListTxType { + t.Fatalf("expected AccessListTxType (1), got %d", txRes.TxType) + } + if txRes.Value != transactions[3].Value().String() { + t.Fatalf("expected tx value %s got %s", transactions[3].Value().String(), txRes.Value) + } + accessListElementModels := make([]models.AccessListElementModel, 0) + pgStr = "SELECT cast(access_list_elements.block_number AS TEXT), access_list_elements.index, access_list_elements.tx_id, " + + "access_list_elements.address, access_list_elements.storage_keys FROM eth.access_list_elements " + + "INNER JOIN eth.transaction_cids ON (tx_id = transaction_cids.tx_hash) WHERE cid = $1 ORDER BY access_list_elements.index ASC" + err = db.Select(context.Background(), &accessListElementModels, pgStr, c) + if err != nil { + t.Fatal(err) + } + if len(accessListElementModels) != 2 { + t.Fatalf("expected two access list entries, got %d", len(accessListElementModels)) + } + model1 := models.AccessListElementModel{ + BlockNumber: mocks.BlockNumber.String(), + Index: accessListElementModels[0].Index, + Address: accessListElementModels[0].Address, + } + model2 := models.AccessListElementModel{ + BlockNumber: mocks.BlockNumber.String(), + Index: accessListElementModels[1].Index, + Address: accessListElementModels[1].Address, + StorageKeys: accessListElementModels[1].StorageKeys, + } + require.Equal(t, mocks.AccessListEntry1Model, model1) + require.Equal(t, mocks.AccessListEntry2Model, model2) + case trx5CID.String(): + require.Equal(t, tx5, data) + txRes := new(txResult) + err = db.QueryRow(context.Background(), txTypeAndValueStr, c).Scan(&txRes.TxType, &txRes.Value) + if err != nil { + t.Fatal(err) + } + if txRes.TxType != types.DynamicFeeTxType { + t.Fatalf("expected DynamicFeeTxType (2), got %d", txRes.TxType) + } + if txRes.Value != transactions[4].Value().String() { + t.Fatalf("expected tx value %s got %s", transactions[4].Value().String(), txRes.Value) + } + } + } +} + +func TestPublishAndIndexLogIPLDs(t *testing.T, db sql.Database) { + rcts := make([]string, 0) + rctsPgStr := `SELECT receipt_cids.leaf_cid FROM eth.receipt_cids, eth.transaction_cids, eth.header_cids + WHERE receipt_cids.tx_id = transaction_cids.tx_hash + AND transaction_cids.header_id = header_cids.block_hash + AND header_cids.block_number = $1 + ORDER BY transaction_cids.index` + logsPgStr := `SELECT log_cids.index, log_cids.address, log_cids.topic0, log_cids.topic1, data FROM eth.log_cids + INNER JOIN eth.receipt_cids ON (log_cids.rct_id = receipt_cids.tx_id) + INNER JOIN public.blocks ON (log_cids.leaf_mh_key = blocks.key) + WHERE receipt_cids.leaf_cid = $1 ORDER BY eth.log_cids.index ASC` + err = db.Select(context.Background(), &rcts, rctsPgStr, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + if len(rcts) != len(mocks.MockReceipts) { + t.Fatalf("expected %d receipts, got %d", len(mocks.MockReceipts), len(rcts)) + } + + type logIPLD struct { + Index int `db:"index"` + Address string `db:"address"` + Data []byte `db:"data"` + Topic0 string `db:"topic0"` + Topic1 string `db:"topic1"` + } + for i := range rcts { + results := make([]logIPLD, 0) + err = db.Select(context.Background(), &results, logsPgStr, rcts[i]) + require.NoError(t, err) + + expectedLogs := mocks.MockReceipts[i].Logs + require.Equal(t, len(expectedLogs), len(results)) + + var nodeElements []interface{} + for idx, r := range results { + // Attempt to decode the log leaf node. + err = rlp.DecodeBytes(r.Data, &nodeElements) + require.NoError(t, err) + if len(nodeElements) == 2 { + logRaw, err := rlp.EncodeToBytes(&expectedLogs[idx]) + require.NoError(t, err) + // 2nd element of the leaf node contains the encoded log data. + require.Equal(t, nodeElements[1].([]byte), logRaw) + } else { + logRaw, err := rlp.EncodeToBytes(&expectedLogs[idx]) + require.NoError(t, err) + // raw log was IPLDized + require.Equal(t, r.Data, logRaw) + } + } + } +} + +func TestPublishAndIndexReceiptIPLDs(t *testing.T, db sql.Database) { + // check receipts were properly indexed and published + rcts := make([]string, 0) + pgStr := `SELECT receipt_cids.leaf_cid FROM eth.receipt_cids, eth.transaction_cids, eth.header_cids + WHERE receipt_cids.tx_id = transaction_cids.tx_hash + AND transaction_cids.header_id = header_cids.block_hash + AND header_cids.block_number = $1 order by transaction_cids.index` + err = db.Select(context.Background(), &rcts, pgStr, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, 5, len(rcts)) + expectTrue(t, test_helpers.ListContainsString(rcts, rct1CID.String())) + expectTrue(t, test_helpers.ListContainsString(rcts, rct2CID.String())) + expectTrue(t, test_helpers.ListContainsString(rcts, rct3CID.String())) + expectTrue(t, test_helpers.ListContainsString(rcts, rct4CID.String())) + expectTrue(t, test_helpers.ListContainsString(rcts, rct5CID.String())) + + for idx, c := range rcts { + result := make([]models.IPLDModel, 0) + pgStr = `SELECT data + FROM eth.receipt_cids + INNER JOIN public.blocks ON (receipt_cids.leaf_mh_key = public.blocks.key) + WHERE receipt_cids.leaf_cid = $1` + err = db.Select(context.Background(), &result, pgStr, c) + if err != nil { + t.Fatal(err) + } + + // Decode the receipt leaf node. + var nodeElements []interface{} + err = rlp.DecodeBytes(result[0].Data, &nodeElements) + require.NoError(t, err) + + expectedRct, err := mocks.MockReceipts[idx].MarshalBinary() + require.NoError(t, err) + + require.Equal(t, nodeElements[1].([]byte), expectedRct) + + dc, err := cid.Decode(c) + if err != nil { + t.Fatal(err) + } + mhKey := dshelp.MultihashToDsKey(dc.Hash()) + prefixedKey := blockstore.BlockPrefix.String() + mhKey.String() + var data []byte + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + + postStatePgStr := `SELECT post_state FROM eth.receipt_cids WHERE leaf_cid = $1` + switch c { + case rct1CID.String(): + require.Equal(t, rctLeaf1, data) + var postStatus uint64 + pgStr = `SELECT post_status FROM eth.receipt_cids WHERE leaf_cid = $1` + err = db.Get(context.Background(), &postStatus, pgStr, c) + if err != nil { + t.Fatal(err) + } + require.Equal(t, mocks.ExpectedPostStatus, postStatus) + case rct2CID.String(): + require.Equal(t, rctLeaf2, data) + var postState string + err = db.Get(context.Background(), &postState, postStatePgStr, c) + if err != nil { + t.Fatal(err) + } + require.Equal(t, mocks.ExpectedPostState1, postState) + case rct3CID.String(): + require.Equal(t, rctLeaf3, data) + var postState string + err = db.Get(context.Background(), &postState, postStatePgStr, c) + if err != nil { + t.Fatal(err) + } + require.Equal(t, mocks.ExpectedPostState2, postState) + case rct4CID.String(): + require.Equal(t, rctLeaf4, data) + var postState string + err = db.Get(context.Background(), &postState, postStatePgStr, c) + if err != nil { + t.Fatal(err) + } + require.Equal(t, mocks.ExpectedPostState3, postState) + case rct5CID.String(): + require.Equal(t, rctLeaf5, data) + var postState string + err = db.Get(context.Background(), &postState, postStatePgStr, c) + if err != nil { + t.Fatal(err) + } + require.Equal(t, mocks.ExpectedPostState3, postState) + } + } +} + +func TestPublishAndIndexStateIPLDs(t *testing.T, db sql.Database) { + // check that state nodes were properly indexed and published + stateNodes := make([]models.StateNodeModel, 0) + pgStr := `SELECT state_cids.cid, state_cids.state_leaf_key, state_cids.node_type, state_cids.state_path, state_cids.header_id + FROM eth.state_cids INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.block_hash) + WHERE header_cids.block_number = $1 AND node_type != 3` + err = db.Select(context.Background(), &stateNodes, pgStr, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, 2, len(stateNodes)) + for _, stateNode := range stateNodes { + var data []byte + dc, err := cid.Decode(stateNode.CID) + if err != nil { + t.Fatal(err) + } + mhKey := dshelp.MultihashToDsKey(dc.Hash()) + prefixedKey := blockstore.BlockPrefix.String() + mhKey.String() + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + pgStr = `SELECT cast(block_number AS TEXT), header_id, state_path, cast(balance AS TEXT), nonce, code_hash, storage_root from eth.state_accounts WHERE header_id = $1 AND state_path = $2` + var account models.StateAccountModel + err = db.Get(context.Background(), &account, pgStr, stateNode.HeaderID, stateNode.Path) + if err != nil { + t.Fatal(err) + } + if stateNode.CID == state1CID.String() { + require.Equal(t, 2, stateNode.NodeType) + require.Equal(t, common.BytesToHash(mocks.ContractLeafKey).Hex(), stateNode.StateKey) + require.Equal(t, []byte{'\x06'}, stateNode.Path) + require.Equal(t, mocks.ContractLeafNode, data) + require.Equal(t, models.StateAccountModel{ + BlockNumber: mocks.BlockNumber.String(), + HeaderID: account.HeaderID, + StatePath: stateNode.Path, + Balance: "0", + CodeHash: mocks.ContractCodeHash.Bytes(), + StorageRoot: mocks.ContractRoot, + Nonce: 1, + }, account) + } + if stateNode.CID == state2CID.String() { + require.Equal(t, 2, stateNode.NodeType) + require.Equal(t, common.BytesToHash(mocks.AccountLeafKey).Hex(), stateNode.StateKey) + require.Equal(t, []byte{'\x0c'}, stateNode.Path) + require.Equal(t, mocks.AccountLeafNode, data) + require.Equal(t, models.StateAccountModel{ + BlockNumber: mocks.BlockNumber.String(), + HeaderID: account.HeaderID, + StatePath: stateNode.Path, + Balance: "1000", + CodeHash: mocks.AccountCodeHash.Bytes(), + StorageRoot: mocks.AccountRoot, + Nonce: 0, + }, account) + } + } + + // check that Removed state nodes were properly indexed and published + stateNodes = make([]models.StateNodeModel, 0) + pgStr = `SELECT state_cids.cid, state_cids.state_leaf_key, state_cids.node_type, state_cids.state_path, state_cids.header_id + FROM eth.state_cids INNER JOIN eth.header_cids ON (state_cids.header_id = header_cids.block_hash) + WHERE header_cids.block_number = $1 AND node_type = 3 + ORDER BY state_path` + err = db.Select(context.Background(), &stateNodes, pgStr, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, 2, len(stateNodes)) + for idx, stateNode := range stateNodes { + var data []byte + dc, err := cid.Decode(stateNode.CID) + if err != nil { + t.Fatal(err) + } + mhKey := dshelp.MultihashToDsKey(dc.Hash()) + prefixedKey := blockstore.BlockPrefix.String() + mhKey.String() + require.Equal(t, shared.RemovedNodeMhKey, prefixedKey) + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + + if idx == 0 { + require.Equal(t, shared.RemovedNodeStateCID, stateNode.CID) + require.Equal(t, common.BytesToHash(mocks.RemovedLeafKey).Hex(), stateNode.StateKey) + require.Equal(t, []byte{'\x02'}, stateNode.Path) + require.Equal(t, []byte{}, data) + } + if idx == 1 { + require.Equal(t, shared.RemovedNodeStateCID, stateNode.CID) + require.Equal(t, common.BytesToHash(mocks.Contract2LeafKey).Hex(), stateNode.StateKey) + require.Equal(t, []byte{'\x07'}, stateNode.Path) + require.Equal(t, []byte{}, data) + } + } +} + +func TestPublishAndIndexStorageIPLDs(t *testing.T, db sql.Database) { + // check that storage nodes were properly indexed + storageNodes := make([]models.StorageNodeWithStateKeyModel, 0) + pgStr := `SELECT cast(storage_cids.block_number AS TEXT), storage_cids.cid, state_cids.state_leaf_key, storage_cids.storage_leaf_key, storage_cids.node_type, storage_cids.storage_path + FROM eth.storage_cids, eth.state_cids, eth.header_cids + WHERE (storage_cids.state_path, storage_cids.header_id) = (state_cids.state_path, state_cids.header_id) + AND state_cids.header_id = header_cids.block_hash + AND header_cids.block_number = $1 + AND storage_cids.node_type != 3 + ORDER BY storage_path` + err = db.Select(context.Background(), &storageNodes, pgStr, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, 1, len(storageNodes)) + require.Equal(t, models.StorageNodeWithStateKeyModel{ + BlockNumber: mocks.BlockNumber.String(), + CID: storageCID.String(), + NodeType: 2, + StorageKey: common.BytesToHash(mocks.StorageLeafKey).Hex(), + StateKey: common.BytesToHash(mocks.ContractLeafKey).Hex(), + Path: []byte{}, + }, storageNodes[0]) + var data []byte + dc, err := cid.Decode(storageNodes[0].CID) + if err != nil { + t.Fatal(err) + } + mhKey := dshelp.MultihashToDsKey(dc.Hash()) + prefixedKey := blockstore.BlockPrefix.String() + mhKey.String() + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, mocks.StorageLeafNode, data) + + // check that Removed storage nodes were properly indexed + storageNodes = make([]models.StorageNodeWithStateKeyModel, 0) + pgStr = `SELECT cast(storage_cids.block_number AS TEXT), storage_cids.cid, state_cids.state_leaf_key, storage_cids.storage_leaf_key, storage_cids.node_type, storage_cids.storage_path + FROM eth.storage_cids, eth.state_cids, eth.header_cids + WHERE (storage_cids.state_path, storage_cids.header_id) = (state_cids.state_path, state_cids.header_id) + AND state_cids.header_id = header_cids.block_hash + AND header_cids.block_number = $1 + AND storage_cids.node_type = 3 + ORDER BY storage_path` + err = db.Select(context.Background(), &storageNodes, pgStr, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, 3, len(storageNodes)) + expectedStorageNodes := []models.StorageNodeWithStateKeyModel{ + { + BlockNumber: mocks.BlockNumber.String(), + CID: shared.RemovedNodeStorageCID, + NodeType: 3, + StorageKey: common.BytesToHash(mocks.RemovedLeafKey).Hex(), + StateKey: common.BytesToHash(mocks.ContractLeafKey).Hex(), + Path: []byte{'\x03'}, + }, + { + BlockNumber: mocks.BlockNumber.String(), + CID: shared.RemovedNodeStorageCID, + NodeType: 3, + StorageKey: common.BytesToHash(mocks.Storage2LeafKey).Hex(), + StateKey: common.BytesToHash(mocks.Contract2LeafKey).Hex(), + Path: []byte{'\x0e'}, + }, + { + BlockNumber: mocks.BlockNumber.String(), + CID: shared.RemovedNodeStorageCID, + NodeType: 3, + StorageKey: common.BytesToHash(mocks.Storage3LeafKey).Hex(), + StateKey: common.BytesToHash(mocks.Contract2LeafKey).Hex(), + Path: []byte{'\x0f'}, + }, + } + for idx, storageNode := range storageNodes { + require.Equal(t, expectedStorageNodes[idx], storageNode) + dc, err = cid.Decode(storageNode.CID) + if err != nil { + t.Fatal(err) + } + mhKey = dshelp.MultihashToDsKey(dc.Hash()) + prefixedKey = blockstore.BlockPrefix.String() + mhKey.String() + require.Equal(t, shared.RemovedNodeMhKey, prefixedKey) + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, []byte{}, data) + } +} + +// SetupTestDataNonCanonical indexes a mock block and a non-canonical mock block at London height +// and a non-canonical block at London height + 1 +// along with their state nodes +func SetupTestDataNonCanonical(t *testing.T, ind interfaces.StateDiffIndexer) { + // index a canonical block at London height + var tx1 interfaces.Batch + tx1, err = ind.PushBlock( + mockBlock, + mocks.MockReceipts, + mocks.MockBlock.Difficulty()) + if err != nil { + t.Fatal(err) + } + for _, node := range mocks.StateDiffs { + err = ind.PushStateNode(tx1, node, mockBlock.Hash().String()) + require.NoError(t, err) + } + + if batchTx, ok := tx1.(*sql.BatchTx); ok { + require.Equal(t, mocks.BlockNumber.String(), batchTx.BlockNumber) + } else if batchTx, ok := tx1.(*file.BatchTx); ok { + require.Equal(t, mocks.BlockNumber.String(), batchTx.BlockNumber) + } + + if err := tx1.Submit(err); err != nil { + t.Fatal(err) + } + + // index a non-canonical block at London height + // has transactions overlapping with that of the canonical block + var tx2 interfaces.Batch + tx2, err = ind.PushBlock( + mockNonCanonicalBlock, + mocks.MockNonCanonicalBlockReceipts, + mockNonCanonicalBlock.Difficulty()) + if err != nil { + t.Fatal(err) + } + for _, node := range mocks.StateDiffs { + err = ind.PushStateNode(tx2, node, mockNonCanonicalBlock.Hash().String()) + require.NoError(t, err) + } + + if tx, ok := tx2.(*sql.BatchTx); ok { + require.Equal(t, mocks.BlockNumber.String(), tx.BlockNumber) + } else if tx, ok := tx2.(*sql.BatchTx); ok { + require.Equal(t, mocks.BlockNumber.String(), tx.BlockNumber) + } + + if err := tx2.Submit(err); err != nil { + t.Fatal(err) + } + + // index a non-canonical block at London height + 1 + // has transactions overlapping with that of the canonical block + var tx3 interfaces.Batch + tx3, err = ind.PushBlock( + mockNonCanonicalBlock2, + mocks.MockNonCanonicalBlock2Receipts, + mockNonCanonicalBlock2.Difficulty()) + if err != nil { + t.Fatal(err) + } + for _, node := range mocks.StateDiffs[:2] { + err = ind.PushStateNode(tx3, node, mockNonCanonicalBlock2.Hash().String()) + require.NoError(t, err) + } + + if batchTx, ok := tx3.(*sql.BatchTx); ok { + require.Equal(t, mocks.Block2Number.String(), batchTx.BlockNumber) + } else if batchTx, ok := tx3.(*file.BatchTx); ok { + require.Equal(t, mocks.Block2Number.String(), batchTx.BlockNumber) + } + + if err := tx3.Submit(err); err != nil { + t.Fatal(err) + } +} + +func TestPublishAndIndexHeaderNonCanonical(t *testing.T, db sql.Database) { + // check indexed headers + pgStr := `SELECT CAST(block_number as TEXT), block_hash, cid, cast(td AS TEXT), cast(reward AS TEXT), + tx_root, receipt_root, uncle_root, coinbase + FROM eth.header_cids + ORDER BY block_number` + headerRes := make([]models.HeaderModel, 0) + err = db.Select(context.Background(), &headerRes, pgStr) + if err != nil { + t.Fatal(err) + } + + // expect three blocks to be indexed + // a canonical and a non-canonical block at London height, + // non-canonical block at London height + 1 + expectedRes := []models.HeaderModel{ + { + BlockNumber: mockBlock.Number().String(), + BlockHash: mockBlock.Hash().String(), + CID: headerCID.String(), + TotalDifficulty: mockBlock.Difficulty().String(), + TxRoot: mockBlock.TxHash().String(), + RctRoot: mockBlock.ReceiptHash().String(), + UncleRoot: mockBlock.UncleHash().String(), + Coinbase: mocks.MockHeader.Coinbase.String(), + }, + { + BlockNumber: mockNonCanonicalBlock.Number().String(), + BlockHash: mockNonCanonicalBlock.Hash().String(), + CID: mockNonCanonicalHeaderCID.String(), + TotalDifficulty: mockNonCanonicalBlock.Difficulty().String(), + TxRoot: mockNonCanonicalBlock.TxHash().String(), + RctRoot: mockNonCanonicalBlock.ReceiptHash().String(), + UncleRoot: mockNonCanonicalBlock.UncleHash().String(), + Coinbase: mocks.MockNonCanonicalHeader.Coinbase.String(), + }, + { + BlockNumber: mockNonCanonicalBlock2.Number().String(), + BlockHash: mockNonCanonicalBlock2.Hash().String(), + CID: mockNonCanonicalHeader2CID.String(), + TotalDifficulty: mockNonCanonicalBlock2.Difficulty().String(), + TxRoot: mockNonCanonicalBlock2.TxHash().String(), + RctRoot: mockNonCanonicalBlock2.ReceiptHash().String(), + UncleRoot: mockNonCanonicalBlock2.UncleHash().String(), + Coinbase: mocks.MockNonCanonicalHeader2.Coinbase.String(), + }, + } + expectedRes[0].Reward = shared.CalcEthBlockReward(mockBlock.Header(), mockBlock.Uncles(), mockBlock.Transactions(), mocks.MockReceipts).String() + expectedRes[1].Reward = shared.CalcEthBlockReward(mockNonCanonicalBlock.Header(), mockNonCanonicalBlock.Uncles(), mockNonCanonicalBlock.Transactions(), mocks.MockNonCanonicalBlockReceipts).String() + expectedRes[2].Reward = shared.CalcEthBlockReward(mockNonCanonicalBlock2.Header(), mockNonCanonicalBlock2.Uncles(), mockNonCanonicalBlock2.Transactions(), mocks.MockNonCanonicalBlock2Receipts).String() + + require.Equal(t, len(expectedRes), len(headerRes)) + require.ElementsMatch(t, + []string{mockBlock.Hash().String(), mockNonCanonicalBlock.Hash().String(), mockNonCanonicalBlock2.Hash().String()}, + []string{headerRes[0].BlockHash, headerRes[1].BlockHash, headerRes[2].BlockHash}, + ) + + if headerRes[0].BlockHash == mockBlock.Hash().String() { + require.Equal(t, expectedRes[0], headerRes[0]) + require.Equal(t, expectedRes[1], headerRes[1]) + require.Equal(t, expectedRes[2], headerRes[2]) + } else { + require.Equal(t, expectedRes[1], headerRes[0]) + require.Equal(t, expectedRes[0], headerRes[1]) + require.Equal(t, expectedRes[2], headerRes[2]) + } + + // check indexed IPLD blocks + headerCIDs := []cid.Cid{headerCID, mockNonCanonicalHeaderCID, mockNonCanonicalHeader2CID} + blockNumbers := []uint64{mocks.BlockNumber.Uint64(), mocks.BlockNumber.Uint64(), mocks.Block2Number.Uint64()} + headerRLPs := [][]byte{mocks.MockHeaderRlp, mocks.MockNonCanonicalHeaderRlp, mocks.MockNonCanonicalHeader2Rlp} + for i := range expectedRes { + var data []byte + prefixedKey := shared.MultihashKeyFromCID(headerCIDs[i]) + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, blockNumbers[i]) + if err != nil { + t.Fatal(err) + } + require.Equal(t, headerRLPs[i], data) + } +} + +func TestPublishAndIndexTransactionsNonCanonical(t *testing.T, db sql.Database) { + // check indexed transactions + pgStr := `SELECT CAST(block_number as TEXT), header_id, tx_hash, cid, dst, src, index, + tx_data, tx_type, CAST(value as TEXT) + FROM eth.transaction_cids + ORDER BY block_number, index` + txRes := make([]models.TxModel, 0) + err = db.Select(context.Background(), &txRes, pgStr) + if err != nil { + t.Fatal(err) + } + + // expected transactions in the canonical block + mockBlockTxs := mocks.MockBlock.Transactions() + expectedBlockTxs := []models.TxModel{ + { + BlockNumber: mockBlock.Number().String(), + HeaderID: mockBlock.Hash().String(), + TxHash: mockBlockTxs[0].Hash().String(), + CID: trx1CID.String(), + Dst: shared.HandleZeroAddrPointer(mockBlockTxs[0].To()), + Src: mocks.SenderAddr.String(), + Index: 0, + Data: mockBlockTxs[0].Data(), + Type: mockBlockTxs[0].Type(), + Value: mockBlockTxs[0].Value().String(), + }, + { + BlockNumber: mockBlock.Number().String(), + HeaderID: mockBlock.Hash().String(), + TxHash: mockBlockTxs[1].Hash().String(), + CID: trx2CID.String(), + Dst: shared.HandleZeroAddrPointer(mockBlockTxs[1].To()), + Src: mocks.SenderAddr.String(), + Index: 1, + Data: mockBlockTxs[1].Data(), + Type: mockBlockTxs[1].Type(), + Value: mockBlockTxs[1].Value().String(), + }, + { + BlockNumber: mockBlock.Number().String(), + HeaderID: mockBlock.Hash().String(), + TxHash: mockBlockTxs[2].Hash().String(), + CID: trx3CID.String(), + Dst: shared.HandleZeroAddrPointer(mockBlockTxs[2].To()), + Src: mocks.SenderAddr.String(), + Index: 2, + Data: mockBlockTxs[2].Data(), + Type: mockBlockTxs[2].Type(), + Value: mockBlockTxs[2].Value().String(), + }, + { + BlockNumber: mockBlock.Number().String(), + HeaderID: mockBlock.Hash().String(), + TxHash: mockBlockTxs[3].Hash().String(), + CID: trx4CID.String(), + Dst: shared.HandleZeroAddrPointer(mockBlockTxs[3].To()), + Src: mocks.SenderAddr.String(), + Index: 3, + Data: mockBlockTxs[3].Data(), + Type: mockBlockTxs[3].Type(), + Value: mockBlockTxs[3].Value().String(), + }, + { + BlockNumber: mockBlock.Number().String(), + HeaderID: mockBlock.Hash().String(), + TxHash: mockBlockTxs[4].Hash().String(), + CID: trx5CID.String(), + Dst: shared.HandleZeroAddrPointer(mockBlockTxs[4].To()), + Src: mocks.SenderAddr.String(), + Index: 4, + Data: mockBlockTxs[4].Data(), + Type: mockBlockTxs[4].Type(), + Value: mockBlockTxs[4].Value().String(), + }, + } + + // expected transactions in the non-canonical block at London height + mockNonCanonicalBlockTxs := mockNonCanonicalBlock.Transactions() + expectedNonCanonicalBlockTxs := []models.TxModel{ + { + BlockNumber: mockNonCanonicalBlock.Number().String(), + HeaderID: mockNonCanonicalBlock.Hash().String(), + TxHash: mockNonCanonicalBlockTxs[0].Hash().String(), + CID: trx2CID.String(), + Dst: mockNonCanonicalBlockTxs[0].To().String(), + Src: mocks.SenderAddr.String(), + Index: 0, + Data: mockNonCanonicalBlockTxs[0].Data(), + Type: mockNonCanonicalBlockTxs[0].Type(), + Value: mockNonCanonicalBlockTxs[0].Value().String(), + }, + { + BlockNumber: mockNonCanonicalBlock.Number().String(), + HeaderID: mockNonCanonicalBlock.Hash().String(), + TxHash: mockNonCanonicalBlockTxs[1].Hash().String(), + CID: trx5CID.String(), + Dst: mockNonCanonicalBlockTxs[1].To().String(), + Src: mocks.SenderAddr.String(), + Index: 1, + Data: mockNonCanonicalBlockTxs[1].Data(), + Type: mockNonCanonicalBlockTxs[1].Type(), + Value: mockNonCanonicalBlockTxs[1].Value().String(), + }, + } + + // expected transactions in the non-canonical block at London height + 1 + mockNonCanonicalBlock2Txs := mockNonCanonicalBlock2.Transactions() + expectedNonCanonicalBlock2Txs := []models.TxModel{ + { + BlockNumber: mockNonCanonicalBlock2.Number().String(), + HeaderID: mockNonCanonicalBlock2.Hash().String(), + TxHash: mockNonCanonicalBlock2Txs[0].Hash().String(), + CID: trx3CID.String(), + Dst: "", + Src: mocks.SenderAddr.String(), + Index: 0, + Data: mockNonCanonicalBlock2Txs[0].Data(), + Type: mockNonCanonicalBlock2Txs[0].Type(), + Value: mockNonCanonicalBlock2Txs[0].Value().String(), + }, + { + BlockNumber: mockNonCanonicalBlock2.Number().String(), + HeaderID: mockNonCanonicalBlock2.Hash().String(), + TxHash: mockNonCanonicalBlock2Txs[1].Hash().String(), + CID: trx5CID.String(), + Dst: mockNonCanonicalBlock2Txs[1].To().String(), + Src: mocks.SenderAddr.String(), + Index: 1, + Data: mockNonCanonicalBlock2Txs[1].Data(), + Type: mockNonCanonicalBlock2Txs[1].Type(), + Value: mockNonCanonicalBlock2Txs[1].Value().String(), + }, + } + + require.Equal(t, len(expectedBlockTxs)+len(expectedNonCanonicalBlockTxs)+len(expectedNonCanonicalBlock2Txs), len(txRes)) + + // sort results such that non-canonical block transactions come after canonical block ones + sort.SliceStable(txRes, func(i, j int) bool { + if txRes[i].BlockNumber < txRes[j].BlockNumber { + return true + } else if txRes[i].HeaderID == txRes[j].HeaderID { + return txRes[i].Index < txRes[j].Index + } else if txRes[i].HeaderID == mockBlock.Hash().String() { + return true + } else { + return false + } + }) + + for i, expectedTx := range expectedBlockTxs { + require.Equal(t, expectedTx, txRes[i]) + } + for i, expectedTx := range expectedNonCanonicalBlockTxs { + require.Equal(t, expectedTx, txRes[len(expectedBlockTxs)+i]) + } + for i, expectedTx := range expectedNonCanonicalBlock2Txs { + require.Equal(t, expectedTx, txRes[len(expectedBlockTxs)+len(expectedNonCanonicalBlockTxs)+i]) + } + + // check indexed IPLD blocks + var data []byte + var prefixedKey string + + txCIDs := []cid.Cid{trx1CID, trx2CID, trx3CID, trx4CID, trx5CID} + txRLPs := [][]byte{tx1, tx2, tx3, tx4, tx5} + for i, txCID := range txCIDs { + prefixedKey = shared.MultihashKeyFromCID(txCID) + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, txRLPs[i], data) + } +} + +func TestPublishAndIndexReceiptsNonCanonical(t *testing.T, db sql.Database) { + // check indexed receipts + pgStr := `SELECT CAST(block_number as TEXT), header_id, tx_id, leaf_cid, leaf_mh_key, post_status, post_state, contract, contract_hash, log_root + FROM eth.receipt_cids + ORDER BY block_number` + rctRes := make([]models.ReceiptModel, 0) + err = db.Select(context.Background(), &rctRes, pgStr) + if err != nil { + t.Fatal(err) + } + + // expected receipts in the canonical block + rctCids := []cid.Cid{rct1CID, rct2CID, rct3CID, rct4CID, rct5CID} + expectedBlockRctsMap := make(map[string]models.ReceiptModel, len(mocks.MockReceipts)) + for i, mockBlockRct := range mocks.MockReceipts { + rctModel := createRctModel(mockBlockRct, rctCids[i], mockBlock.Number().String()) + expectedBlockRctsMap[rctCids[i].String()] = rctModel + } + + // expected receipts in the non-canonical block at London height + nonCanonicalBlockRctCids := []cid.Cid{nonCanonicalBlockRct1CID, nonCanonicalBlockRct2CID} + expectedNonCanonicalBlockRctsMap := make(map[string]models.ReceiptModel, len(mocks.MockNonCanonicalBlockReceipts)) + for i, mockNonCanonicalBlockRct := range mocks.MockNonCanonicalBlockReceipts { + rctModel := createRctModel(mockNonCanonicalBlockRct, nonCanonicalBlockRctCids[i], mockNonCanonicalBlock.Number().String()) + expectedNonCanonicalBlockRctsMap[nonCanonicalBlockRctCids[i].String()] = rctModel + } + + // expected receipts in the non-canonical block at London height + 1 + nonCanonicalBlock2RctCids := []cid.Cid{nonCanonicalBlock2Rct1CID, nonCanonicalBlock2Rct2CID} + expectedNonCanonicalBlock2RctsMap := make(map[string]models.ReceiptModel, len(mocks.MockNonCanonicalBlock2Receipts)) + for i, mockNonCanonicalBlock2Rct := range mocks.MockNonCanonicalBlock2Receipts { + rctModel := createRctModel(mockNonCanonicalBlock2Rct, nonCanonicalBlock2RctCids[i], mockNonCanonicalBlock2.Number().String()) + expectedNonCanonicalBlock2RctsMap[nonCanonicalBlock2RctCids[i].String()] = rctModel + } + + require.Equal(t, len(expectedBlockRctsMap)+len(expectedNonCanonicalBlockRctsMap)+len(expectedNonCanonicalBlock2RctsMap), len(rctRes)) + + // sort results such that non-canonical block reciepts come after canonical block ones + sort.SliceStable(rctRes, func(i, j int) bool { + if rctRes[i].BlockNumber < rctRes[j].BlockNumber { + return true + } else if rctRes[i].HeaderID == rctRes[j].HeaderID { + return false + } else if rctRes[i].HeaderID == mockBlock.Hash().String() { + return true + } else { + return false + } + }) + + for i := 0; i < len(expectedBlockRctsMap); i++ { + rct := rctRes[i] + require.Contains(t, expectedBlockRctsMap, rct.LeafCID) + require.Equal(t, expectedBlockRctsMap[rct.LeafCID], rct) + } + + for i := 0; i < len(expectedNonCanonicalBlockRctsMap); i++ { + rct := rctRes[len(expectedBlockRctsMap)+i] + require.Contains(t, expectedNonCanonicalBlockRctsMap, rct.LeafCID) + require.Equal(t, expectedNonCanonicalBlockRctsMap[rct.LeafCID], rct) + } + + for i := 0; i < len(expectedNonCanonicalBlock2RctsMap); i++ { + rct := rctRes[len(expectedBlockRctsMap)+len(expectedNonCanonicalBlockRctsMap)+i] + require.Contains(t, expectedNonCanonicalBlock2RctsMap, rct.LeafCID) + require.Equal(t, expectedNonCanonicalBlock2RctsMap[rct.LeafCID], rct) + } + + // check indexed rct IPLD blocks + var data []byte + var prefixedKey string + + rctRLPs := [][]byte{ + rctLeaf1, rctLeaf2, rctLeaf3, rctLeaf4, rctLeaf5, + nonCanonicalBlockRctLeaf1, nonCanonicalBlockRctLeaf2, + } + for i, rctCid := range append(rctCids, nonCanonicalBlockRctCids...) { + prefixedKey = shared.MultihashKeyFromCID(rctCid) + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.BlockNumber.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, rctRLPs[i], data) + } + + nonCanonicalBlock2RctRLPs := [][]byte{nonCanonicalBlock2RctLeaf1, nonCanonicalBlock2RctLeaf2} + for i, rctCid := range nonCanonicalBlock2RctCids { + prefixedKey = shared.MultihashKeyFromCID(rctCid) + err = db.Get(context.Background(), &data, ipfsPgGet, prefixedKey, mocks.Block2Number.Uint64()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, nonCanonicalBlock2RctRLPs[i], data) + } +} + +func TestPublishAndIndexLogsNonCanonical(t *testing.T, db sql.Database) { + // check indexed logs + pgStr := `SELECT address, log_data, topic0, topic1, topic2, topic3, data + FROM eth.log_cids + INNER JOIN public.blocks ON (log_cids.block_number = blocks.block_number AND log_cids.leaf_mh_key = blocks.key) + WHERE log_cids.block_number = $1 AND header_id = $2 AND rct_id = $3 + ORDER BY log_cids.index ASC` + + type rctWithBlockHash struct { + rct *types.Receipt + blockHash string + blockNumber uint64 + } + mockRcts := make([]rctWithBlockHash, 0) + + // logs in the canonical block + for _, mockBlockRct := range mocks.MockReceipts { + mockRcts = append(mockRcts, rctWithBlockHash{ + mockBlockRct, + mockBlock.Hash().String(), + mockBlock.NumberU64(), + }) + } + + // logs in the non-canonical block at London height + for _, mockBlockRct := range mocks.MockNonCanonicalBlockReceipts { + mockRcts = append(mockRcts, rctWithBlockHash{ + mockBlockRct, + mockNonCanonicalBlock.Hash().String(), + mockNonCanonicalBlock.NumberU64(), + }) + } + + // logs in the non-canonical block at London height + 1 + for _, mockBlockRct := range mocks.MockNonCanonicalBlock2Receipts { + mockRcts = append(mockRcts, rctWithBlockHash{ + mockBlockRct, + mockNonCanonicalBlock2.Hash().String(), + mockNonCanonicalBlock2.NumberU64(), + }) + } + + for _, mockRct := range mockRcts { + type logWithIPLD struct { + models.LogsModel + IPLDData []byte `db:"data"` + } + logRes := make([]logWithIPLD, 0) + err = db.Select(context.Background(), &logRes, pgStr, mockRct.blockNumber, mockRct.blockHash, mockRct.rct.TxHash.String()) + require.NoError(t, err) + require.Equal(t, len(mockRct.rct.Logs), len(logRes)) + + for i, log := range mockRct.rct.Logs { + topicSet := make([]string, 4) + for ti, topic := range log.Topics { + topicSet[ti] = topic.Hex() + } + + expectedLog := models.LogsModel{ + Address: log.Address.String(), + Data: log.Data, + Topic0: topicSet[0], + Topic1: topicSet[1], + Topic2: topicSet[2], + Topic3: topicSet[3], + } + require.Equal(t, expectedLog, logRes[i].LogsModel) + + // check indexed log IPLD block + var nodeElements []interface{} + err = rlp.DecodeBytes(logRes[i].IPLDData, &nodeElements) + require.NoError(t, err) + + if len(nodeElements) == 2 { + logRaw, err := rlp.EncodeToBytes(log) + require.NoError(t, err) + // 2nd element of the leaf node contains the encoded log data. + require.Equal(t, nodeElements[1].([]byte), logRaw) + } else { + logRaw, err := rlp.EncodeToBytes(log) + require.NoError(t, err) + // raw log was IPLDized + require.Equal(t, logRes[i].IPLDData, logRaw) + } + } + } +} + +func TestPublishAndIndexStateNonCanonical(t *testing.T, db sql.Database) { + // check indexed state nodes + pgStr := `SELECT state_path, state_leaf_key, node_type, cid, mh_key, diff + FROM eth.state_cids + WHERE block_number = $1 + AND header_id = $2 + ORDER BY state_path` + + removedNodeCID, _ := cid.Decode(shared.RemovedNodeStateCID) + stateNodeCIDs := []cid.Cid{state1CID, state2CID, removedNodeCID, removedNodeCID} + + // expected state nodes in the canonical and the non-canonical block at London height + expectedStateNodes := make([]models.StateNodeModel, 0) + for i, stateDiff := range mocks.StateDiffs { + expectedStateNodes = append(expectedStateNodes, models.StateNodeModel{ + Path: stateDiff.Path, + StateKey: common.BytesToHash(stateDiff.LeafKey).Hex(), + NodeType: stateDiff.NodeType.Int(), + CID: stateNodeCIDs[i].String(), + MhKey: shared.MultihashKeyFromCID(stateNodeCIDs[i]), + Diff: true, + }) + } + sort.Slice(expectedStateNodes, func(i, j int) bool { + if bytes.Compare(expectedStateNodes[i].Path, expectedStateNodes[j].Path) < 0 { + return true + } else { + return false + } + }) + + // expected state nodes in the non-canonical block at London height + 1 + expectedNonCanonicalBlock2StateNodes := make([]models.StateNodeModel, 0) + for i, stateDiff := range mocks.StateDiffs[:2] { + expectedNonCanonicalBlock2StateNodes = append(expectedNonCanonicalBlock2StateNodes, models.StateNodeModel{ + Path: stateDiff.Path, + StateKey: common.BytesToHash(stateDiff.LeafKey).Hex(), + NodeType: stateDiff.NodeType.Int(), + CID: stateNodeCIDs[i].String(), + MhKey: shared.MultihashKeyFromCID(stateNodeCIDs[i]), + Diff: true, + }) + } + + // check state nodes for canonical block + stateNodes := make([]models.StateNodeModel, 0) + err = db.Select(context.Background(), &stateNodes, pgStr, mocks.BlockNumber.Uint64(), mockBlock.Hash().String()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, len(expectedStateNodes), len(stateNodes)) + + for i, expectedStateNode := range expectedStateNodes { + require.Equal(t, expectedStateNode, stateNodes[i]) + } + + // check state nodes for non-canonical block at London height + stateNodes = make([]models.StateNodeModel, 0) + err = db.Select(context.Background(), &stateNodes, pgStr, mocks.BlockNumber.Uint64(), mockNonCanonicalBlock.Hash().String()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, len(expectedStateNodes), len(stateNodes)) + + for i, expectedStateNode := range expectedStateNodes { + require.Equal(t, expectedStateNode, stateNodes[i]) + } + + // check state nodes for non-canonical block at London height + 1 + stateNodes = make([]models.StateNodeModel, 0) + err = db.Select(context.Background(), &stateNodes, pgStr, mocks.Block2Number.Uint64(), mockNonCanonicalBlock2.Hash().String()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, len(expectedNonCanonicalBlock2StateNodes), len(stateNodes)) + + for i, expectedStateNode := range expectedNonCanonicalBlock2StateNodes { + require.Equal(t, expectedStateNode, stateNodes[i]) + } +} + +func TestPublishAndIndexStorageNonCanonical(t *testing.T, db sql.Database) { + // check indexed storage nodes + pgStr := `SELECT state_path, storage_path, storage_leaf_key, node_type, cid, mh_key, diff + FROM eth.storage_cids + WHERE block_number = $1 + AND header_id = $2 + ORDER BY state_path, storage_path` + + removedNodeCID, _ := cid.Decode(shared.RemovedNodeStorageCID) + storageNodeCIDs := []cid.Cid{storageCID, removedNodeCID, removedNodeCID, removedNodeCID} + + // expected storage nodes in the canonical and the non-canonical block at London height + expectedStorageNodes := make([]models.StorageNodeModel, 0) + storageNodeIndex := 0 + for _, stateDiff := range mocks.StateDiffs { + for _, storageNode := range stateDiff.StorageNodes { + expectedStorageNodes = append(expectedStorageNodes, models.StorageNodeModel{ + StatePath: stateDiff.Path, + Path: storageNode.Path, + StorageKey: common.BytesToHash(storageNode.LeafKey).Hex(), + NodeType: storageNode.NodeType.Int(), + CID: storageNodeCIDs[storageNodeIndex].String(), + MhKey: shared.MultihashKeyFromCID(storageNodeCIDs[storageNodeIndex]), + Diff: true, + }) + storageNodeIndex++ + } + } + sort.Slice(expectedStorageNodes, func(i, j int) bool { + if bytes.Compare(expectedStorageNodes[i].Path, expectedStorageNodes[j].Path) < 0 { + return true + } else { + return false + } + }) + + // expected storage nodes in the non-canonical block at London height + 1 + expectedNonCanonicalBlock2StorageNodes := make([]models.StorageNodeModel, 0) + storageNodeIndex = 0 + for _, stateDiff := range mocks.StateDiffs[:2] { + for _, storageNode := range stateDiff.StorageNodes { + expectedNonCanonicalBlock2StorageNodes = append(expectedNonCanonicalBlock2StorageNodes, models.StorageNodeModel{ + StatePath: stateDiff.Path, + Path: storageNode.Path, + StorageKey: common.BytesToHash(storageNode.LeafKey).Hex(), + NodeType: storageNode.NodeType.Int(), + CID: storageNodeCIDs[storageNodeIndex].String(), + MhKey: shared.MultihashKeyFromCID(storageNodeCIDs[storageNodeIndex]), + Diff: true, + }) + storageNodeIndex++ + } + } + + // check storage nodes for canonical block + storageNodes := make([]models.StorageNodeModel, 0) + err = db.Select(context.Background(), &storageNodes, pgStr, mocks.BlockNumber.Uint64(), mockBlock.Hash().String()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, len(expectedStorageNodes), len(storageNodes)) + + for i, expectedStorageNode := range expectedStorageNodes { + require.Equal(t, expectedStorageNode, storageNodes[i]) + } + + // check storage nodes for non-canonical block at London height + storageNodes = make([]models.StorageNodeModel, 0) + err = db.Select(context.Background(), &storageNodes, pgStr, mocks.BlockNumber.Uint64(), mockNonCanonicalBlock.Hash().String()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, len(expectedStorageNodes), len(storageNodes)) + + for i, expectedStorageNode := range expectedStorageNodes { + require.Equal(t, expectedStorageNode, storageNodes[i]) + } + + // check storage nodes for non-canonical block at London height + 1 + storageNodes = make([]models.StorageNodeModel, 0) + err = db.Select(context.Background(), &storageNodes, pgStr, mockNonCanonicalBlock2.NumberU64(), mockNonCanonicalBlock2.Hash().String()) + if err != nil { + t.Fatal(err) + } + require.Equal(t, len(expectedNonCanonicalBlock2StorageNodes), len(storageNodes)) + + for i, expectedStorageNode := range expectedNonCanonicalBlock2StorageNodes { + require.Equal(t, expectedStorageNode, storageNodes[i]) + } +} diff --git a/statediff/indexer/test/test_init.go b/statediff/indexer/test/test_init.go new file mode 100644 index 000000000..283d3e0b0 --- /dev/null +++ b/statediff/indexer/test/test_init.go @@ -0,0 +1,248 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package test + +import ( + "bytes" + "fmt" + "os" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" + "github.com/ethereum/go-ethereum/statediff/indexer/models" + "github.com/ethereum/go-ethereum/statediff/indexer/shared" + "github.com/ipfs/go-cid" + "github.com/multiformats/go-multihash" +) + +var ( + err error + ipfsPgGet = `SELECT data FROM public.blocks + WHERE key = $1 AND block_number = $2` + watchedAddressesPgGet = `SELECT * + FROM eth_meta.watched_addresses` + tx1, tx2, tx3, tx4, tx5, rct1, rct2, rct3, rct4, rct5 []byte + nonCanonicalBlockRct1, nonCanonicalBlockRct2 []byte + nonCanonicalBlock2Rct1, nonCanonicalBlock2Rct2 []byte + mockBlock, mockNonCanonicalBlock, mockNonCanonicalBlock2 *types.Block + headerCID, mockNonCanonicalHeaderCID, mockNonCanonicalHeader2CID cid.Cid + trx1CID, trx2CID, trx3CID, trx4CID, trx5CID cid.Cid + rct1CID, rct2CID, rct3CID, rct4CID, rct5CID cid.Cid + nonCanonicalBlockRct1CID, nonCanonicalBlockRct2CID cid.Cid + nonCanonicalBlock2Rct1CID, nonCanonicalBlock2Rct2CID cid.Cid + rctLeaf1, rctLeaf2, rctLeaf3, rctLeaf4, rctLeaf5 []byte + nonCanonicalBlockRctLeaf1, nonCanonicalBlockRctLeaf2 []byte + nonCanonicalBlock2RctLeaf1, nonCanonicalBlock2RctLeaf2 []byte + state1CID, state2CID, storageCID cid.Cid +) + +func init() { + if os.Getenv("MODE") != "statediff" { + fmt.Println("Skipping statediff test") + os.Exit(0) + } + + // canonical block at LondonBlock height + mockBlock = mocks.MockBlock + txs, rcts := mocks.MockBlock.Transactions(), mocks.MockReceipts + + // non-canonical block at LondonBlock height + mockNonCanonicalBlock = mocks.MockNonCanonicalBlock + nonCanonicalBlockRcts := mocks.MockNonCanonicalBlockReceipts + + // non-canonical block at LondonBlock height + 1 + mockNonCanonicalBlock2 = mocks.MockNonCanonicalBlock2 + nonCanonicalBlock2Rcts := mocks.MockNonCanonicalBlock2Receipts + + // encode mock receipts + buf := new(bytes.Buffer) + txs.EncodeIndex(0, buf) + tx1 = make([]byte, buf.Len()) + copy(tx1, buf.Bytes()) + buf.Reset() + + txs.EncodeIndex(1, buf) + tx2 = make([]byte, buf.Len()) + copy(tx2, buf.Bytes()) + buf.Reset() + + txs.EncodeIndex(2, buf) + tx3 = make([]byte, buf.Len()) + copy(tx3, buf.Bytes()) + buf.Reset() + + txs.EncodeIndex(3, buf) + tx4 = make([]byte, buf.Len()) + copy(tx4, buf.Bytes()) + buf.Reset() + + txs.EncodeIndex(4, buf) + tx5 = make([]byte, buf.Len()) + copy(tx5, buf.Bytes()) + buf.Reset() + + rcts.EncodeIndex(0, buf) + rct1 = make([]byte, buf.Len()) + copy(rct1, buf.Bytes()) + buf.Reset() + + rcts.EncodeIndex(1, buf) + rct2 = make([]byte, buf.Len()) + copy(rct2, buf.Bytes()) + buf.Reset() + + rcts.EncodeIndex(2, buf) + rct3 = make([]byte, buf.Len()) + copy(rct3, buf.Bytes()) + buf.Reset() + + rcts.EncodeIndex(3, buf) + rct4 = make([]byte, buf.Len()) + copy(rct4, buf.Bytes()) + buf.Reset() + + rcts.EncodeIndex(4, buf) + rct5 = make([]byte, buf.Len()) + copy(rct5, buf.Bytes()) + buf.Reset() + + // encode mock receipts for non-canonical blocks + nonCanonicalBlockRcts.EncodeIndex(0, buf) + nonCanonicalBlockRct1 = make([]byte, buf.Len()) + copy(nonCanonicalBlockRct1, buf.Bytes()) + buf.Reset() + + nonCanonicalBlockRcts.EncodeIndex(1, buf) + nonCanonicalBlockRct2 = make([]byte, buf.Len()) + copy(nonCanonicalBlockRct2, buf.Bytes()) + buf.Reset() + + nonCanonicalBlock2Rcts.EncodeIndex(0, buf) + nonCanonicalBlock2Rct1 = make([]byte, buf.Len()) + copy(nonCanonicalBlock2Rct1, buf.Bytes()) + buf.Reset() + + nonCanonicalBlock2Rcts.EncodeIndex(1, buf) + nonCanonicalBlock2Rct2 = make([]byte, buf.Len()) + copy(nonCanonicalBlock2Rct2, buf.Bytes()) + buf.Reset() + + headerCID, _ = ipld.RawdataToCid(ipld.MEthHeader, mocks.MockHeaderRlp, multihash.KECCAK_256) + mockNonCanonicalHeaderCID, _ = ipld.RawdataToCid(ipld.MEthHeader, mocks.MockNonCanonicalHeaderRlp, multihash.KECCAK_256) + mockNonCanonicalHeader2CID, _ = ipld.RawdataToCid(ipld.MEthHeader, mocks.MockNonCanonicalHeader2Rlp, multihash.KECCAK_256) + trx1CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx1, multihash.KECCAK_256) + trx2CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx2, multihash.KECCAK_256) + trx3CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx3, multihash.KECCAK_256) + trx4CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx4, multihash.KECCAK_256) + trx5CID, _ = ipld.RawdataToCid(ipld.MEthTx, tx5, multihash.KECCAK_256) + state1CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, mocks.ContractLeafNode, multihash.KECCAK_256) + state2CID, _ = ipld.RawdataToCid(ipld.MEthStateTrie, mocks.AccountLeafNode, multihash.KECCAK_256) + storageCID, _ = ipld.RawdataToCid(ipld.MEthStorageTrie, mocks.StorageLeafNode, multihash.KECCAK_256) + + // create raw receipts + rawRctLeafNodes, rctleafNodeCids := createRctTrie([][]byte{rct1, rct2, rct3, rct4, rct5}) + + rct1CID = rctleafNodeCids[0] + rct2CID = rctleafNodeCids[1] + rct3CID = rctleafNodeCids[2] + rct4CID = rctleafNodeCids[3] + rct5CID = rctleafNodeCids[4] + + rctLeaf1 = rawRctLeafNodes[0] + rctLeaf2 = rawRctLeafNodes[1] + rctLeaf3 = rawRctLeafNodes[2] + rctLeaf4 = rawRctLeafNodes[3] + rctLeaf5 = rawRctLeafNodes[4] + + // create raw receipts for non-canonical blocks + nonCanonicalBlockRawRctLeafNodes, nonCanonicalBlockRctLeafNodeCids := createRctTrie([][]byte{nonCanonicalBlockRct1, nonCanonicalBlockRct2}) + + nonCanonicalBlockRct1CID = nonCanonicalBlockRctLeafNodeCids[0] + nonCanonicalBlockRct2CID = nonCanonicalBlockRctLeafNodeCids[1] + + nonCanonicalBlockRctLeaf1 = nonCanonicalBlockRawRctLeafNodes[0] + nonCanonicalBlockRctLeaf2 = nonCanonicalBlockRawRctLeafNodes[1] + + nonCanonicalBlock2RawRctLeafNodes, nonCanonicalBlock2RctLeafNodeCids := createRctTrie([][]byte{nonCanonicalBlockRct1, nonCanonicalBlockRct2}) + + nonCanonicalBlock2Rct1CID = nonCanonicalBlock2RctLeafNodeCids[0] + nonCanonicalBlock2Rct2CID = nonCanonicalBlock2RctLeafNodeCids[1] + + nonCanonicalBlock2RctLeaf1 = nonCanonicalBlock2RawRctLeafNodes[0] + nonCanonicalBlock2RctLeaf2 = nonCanonicalBlock2RawRctLeafNodes[1] +} + +// createRctTrie creates a receipt trie from the given raw receipts +// returns receipt leaf nodes and their CIDs +func createRctTrie(rcts [][]byte) ([][]byte, []cid.Cid) { + receiptTrie := ipld.NewRctTrie() + + for i, rct := range rcts { + receiptTrie.Add(i, rct) + } + rctLeafNodes, keys, _ := receiptTrie.GetLeafNodes() + + rctleafNodeCids := make([]cid.Cid, len(rctLeafNodes)) + orderedRctLeafNodes := make([][]byte, len(rctLeafNodes)) + for i, rln := range rctLeafNodes { + var idx uint + + r := bytes.NewReader(keys[i].TrieKey) + rlp.Decode(r, &idx) + rctleafNodeCids[idx] = rln.Cid() + orderedRctLeafNodes[idx] = rln.RawData() + } + + return orderedRctLeafNodes, rctleafNodeCids +} + +// createRctModel creates a models.ReceiptModel object from a given ethereum receipt +func createRctModel(rct *types.Receipt, cid cid.Cid, blockNumber string) models.ReceiptModel { + rctModel := models.ReceiptModel{ + BlockNumber: blockNumber, + HeaderID: rct.BlockHash.String(), + TxID: rct.TxHash.String(), + LeafCID: cid.String(), + LeafMhKey: shared.MultihashKeyFromCID(cid), + LogRoot: rct.LogRoot.String(), + } + + contract := shared.HandleZeroAddr(rct.ContractAddress) + rctModel.Contract = contract + if contract != "" { + rctModel.ContractHash = crypto.Keccak256Hash(common.HexToAddress(contract).Bytes()).String() + } + + if len(rct.PostState) == 0 { + rctModel.PostStatus = rct.Status + } else { + rctModel.PostState = common.Bytes2Hex(rct.PostState) + } + + return rctModel +} + +func expectTrue(t *testing.T, value bool) { + if !value { + t.Fatalf("Assertion failed") + } +} diff --git a/statediff/indexer/test/test_legacy.go b/statediff/indexer/test/test_legacy.go new file mode 100644 index 000000000..5838fea71 --- /dev/null +++ b/statediff/indexer/test/test_legacy.go @@ -0,0 +1,96 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package test + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/ipld" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" + "github.com/ipfs/go-cid" + "github.com/multiformats/go-multihash" + "github.com/stretchr/testify/require" +) + +var ( + LegacyConfig = params.MainnetChainConfig + legacyData = mocks.NewLegacyData(LegacyConfig) + mockLegacyBlock *types.Block + legacyHeaderCID cid.Cid +) + +func SetupLegacyTestData(t *testing.T, ind interfaces.StateDiffIndexer) { + mockLegacyBlock = legacyData.MockBlock + legacyHeaderCID, _ = ipld.RawdataToCid(ipld.MEthHeader, legacyData.MockHeaderRlp, multihash.KECCAK_256) + + var tx interfaces.Batch + tx, err = ind.PushBlock( + mockLegacyBlock, + legacyData.MockReceipts, + legacyData.MockBlock.Difficulty()) + require.NoError(t, err) + + defer func() { + if err := tx.Submit(err); err != nil { + t.Fatal(err) + } + }() + for _, node := range legacyData.StateDiffs { + err = ind.PushStateNode(tx, node, mockLegacyBlock.Hash().String()) + require.NoError(t, err) + } + + if batchTx, ok := tx.(*sql.BatchTx); ok { + require.Equal(t, legacyData.BlockNumber.String(), batchTx.BlockNumber) + } else if batchTx, ok := tx.(*file.BatchTx); ok { + require.Equal(t, legacyData.BlockNumber.String(), batchTx.BlockNumber) + } +} + +func TestLegacyIndexer(t *testing.T, db sql.Database) { + pgStr := `SELECT cid, cast(td AS TEXT), cast(reward AS TEXT), block_hash, coinbase + FROM eth.header_cids + WHERE block_number = $1` + // check header was properly indexed + type res struct { + CID string + TD string + Reward string + BlockHash string `db:"block_hash"` + Coinbase string `db:"coinbase"` + } + header := new(res) + err = db.QueryRow(context.Background(), pgStr, legacyData.BlockNumber.Uint64()).Scan( + &header.CID, + &header.TD, + &header.Reward, + &header.BlockHash, + &header.Coinbase) + require.NoError(t, err) + + require.Equal(t, legacyHeaderCID.String(), header.CID) + require.Equal(t, legacyData.MockBlock.Difficulty().String(), header.TD) + require.Equal(t, "5000000000000011250", header.Reward) + require.Equal(t, legacyData.MockHeader.Coinbase.String(), header.Coinbase) + require.Nil(t, legacyData.MockHeader.BaseFee) +} diff --git a/statediff/indexer/test/test_mainnet.go b/statediff/indexer/test/test_mainnet.go new file mode 100644 index 000000000..24f74eb96 --- /dev/null +++ b/statediff/indexer/test/test_mainnet.go @@ -0,0 +1,53 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package test + +import ( + "testing" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/statediff/indexer/database/file" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" + "github.com/stretchr/testify/require" +) + +func TestBlock(t *testing.T, ind interfaces.StateDiffIndexer, testBlock *types.Block, testReceipts types.Receipts) { + var tx interfaces.Batch + tx, err = ind.PushBlock( + testBlock, + testReceipts, + testBlock.Difficulty()) + require.NoError(t, err) + + defer func() { + if err := tx.Submit(err); err != nil { + t.Fatal(err) + } + }() + for _, node := range mocks.StateDiffs { + err = ind.PushStateNode(tx, node, testBlock.Hash().String()) + require.NoError(t, err) + } + + if batchTx, ok := tx.(*sql.BatchTx); ok { + require.Equal(t, testBlock.Number().String(), batchTx.BlockNumber) + } else if batchTx, ok := tx.(*file.BatchTx); ok { + require.Equal(t, testBlock.Number().String(), batchTx.BlockNumber) + } +} diff --git a/statediff/indexer/test/test_watched_addresses.go b/statediff/indexer/test/test_watched_addresses.go new file mode 100644 index 000000000..02949e927 --- /dev/null +++ b/statediff/indexer/test/test_watched_addresses.go @@ -0,0 +1,258 @@ +// VulcanizeDB +// Copyright © 2022 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package test + +import ( + "context" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + "github.com/ethereum/go-ethereum/statediff/indexer/mocks" + "github.com/stretchr/testify/require" +) + +type res struct { + Address string `db:"address"` + CreatedAt uint64 `db:"created_at"` + WatchedAt uint64 `db:"watched_at"` + LastFilledAt uint64 `db:"last_filled_at"` +} + +func TestLoadEmptyWatchedAddresses(t *testing.T, ind interfaces.StateDiffIndexer) { + expectedData := []common.Address{} + + rows, err := ind.LoadWatchedAddresses() + require.NoError(t, err) + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} + +func TestInsertWatchedAddresses(t *testing.T, db sql.Database) { + expectedData := []res{ + { + Address: mocks.Contract1Address, + CreatedAt: mocks.Contract1CreatedAt, + WatchedAt: mocks.WatchedAt1, + LastFilledAt: mocks.LastFilledAt, + }, + { + Address: mocks.Contract2Address, + CreatedAt: mocks.Contract2CreatedAt, + WatchedAt: mocks.WatchedAt1, + LastFilledAt: mocks.LastFilledAt, + }, + } + + rows := []res{} + err = db.Select(context.Background(), &rows, watchedAddressesPgGet) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} + +func TestInsertAlreadyWatchedAddresses(t *testing.T, db sql.Database) { + expectedData := []res{ + { + Address: mocks.Contract1Address, + CreatedAt: mocks.Contract1CreatedAt, + WatchedAt: mocks.WatchedAt1, + LastFilledAt: mocks.LastFilledAt, + }, + { + Address: mocks.Contract2Address, + CreatedAt: mocks.Contract2CreatedAt, + WatchedAt: mocks.WatchedAt1, + LastFilledAt: mocks.LastFilledAt, + }, + { + Address: mocks.Contract3Address, + CreatedAt: mocks.Contract3CreatedAt, + WatchedAt: mocks.WatchedAt2, + LastFilledAt: mocks.LastFilledAt, + }, + } + + rows := []res{} + err = db.Select(context.Background(), &rows, watchedAddressesPgGet) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} + +func TestRemoveWatchedAddresses(t *testing.T, db sql.Database) { + expectedData := []res{ + { + Address: mocks.Contract1Address, + CreatedAt: mocks.Contract1CreatedAt, + WatchedAt: mocks.WatchedAt1, + LastFilledAt: mocks.LastFilledAt, + }, + } + + rows := []res{} + err = db.Select(context.Background(), &rows, watchedAddressesPgGet) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} + +func TestRemoveNonWatchedAddresses(t *testing.T, db sql.Database) { + expectedData := []res{} + + rows := []res{} + err = db.Select(context.Background(), &rows, watchedAddressesPgGet) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} + +func TestSetWatchedAddresses(t *testing.T, db sql.Database) { + expectedData := []res{ + { + Address: mocks.Contract1Address, + CreatedAt: mocks.Contract1CreatedAt, + WatchedAt: mocks.WatchedAt2, + LastFilledAt: mocks.LastFilledAt, + }, + { + Address: mocks.Contract2Address, + CreatedAt: mocks.Contract2CreatedAt, + WatchedAt: mocks.WatchedAt2, + LastFilledAt: mocks.LastFilledAt, + }, + { + Address: mocks.Contract3Address, + CreatedAt: mocks.Contract3CreatedAt, + WatchedAt: mocks.WatchedAt2, + LastFilledAt: mocks.LastFilledAt, + }, + } + + rows := []res{} + err = db.Select(context.Background(), &rows, watchedAddressesPgGet) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} + +func TestSetAlreadyWatchedAddresses(t *testing.T, db sql.Database) { + expectedData := []res{ + { + Address: mocks.Contract4Address, + CreatedAt: mocks.Contract4CreatedAt, + WatchedAt: mocks.WatchedAt3, + LastFilledAt: mocks.LastFilledAt, + }, + { + Address: mocks.Contract2Address, + CreatedAt: mocks.Contract2CreatedAt, + WatchedAt: mocks.WatchedAt3, + LastFilledAt: mocks.LastFilledAt, + }, + { + Address: mocks.Contract3Address, + CreatedAt: mocks.Contract3CreatedAt, + WatchedAt: mocks.WatchedAt3, + LastFilledAt: mocks.LastFilledAt, + }, + } + + rows := []res{} + err = db.Select(context.Background(), &rows, watchedAddressesPgGet) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} + +func TestLoadWatchedAddresses(t *testing.T, ind interfaces.StateDiffIndexer) { + expectedData := []common.Address{ + common.HexToAddress(mocks.Contract4Address), + common.HexToAddress(mocks.Contract2Address), + common.HexToAddress(mocks.Contract3Address), + } + + rows, err := ind.LoadWatchedAddresses() + require.NoError(t, err) + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} + +func TestClearWatchedAddresses(t *testing.T, db sql.Database) { + expectedData := []res{} + rows := []res{} + err = db.Select(context.Background(), &rows, watchedAddressesPgGet) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} + +func TestClearEmptyWatchedAddresses(t *testing.T, db sql.Database) { + expectedData := []res{} + rows := []res{} + err = db.Select(context.Background(), &rows, watchedAddressesPgGet) + if err != nil { + t.Fatal(err) + } + + require.Equal(t, len(expectedData), len(rows)) + for idx, row := range rows { + require.Equal(t, expectedData[idx], row) + } +} diff --git a/statediff/indexer/test_helpers/mainnet_test_helpers.go b/statediff/indexer/test_helpers/mainnet_test_helpers.go new file mode 100644 index 000000000..faedee5b8 --- /dev/null +++ b/statediff/indexer/test_helpers/mainnet_test_helpers.go @@ -0,0 +1,248 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package test_helpers + +import ( + "context" + "errors" + "fmt" + "math/big" + "os" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethclient" + "github.com/ethereum/go-ethereum/rlp" +) + +const ( + defaultBlockFilePath = "../../../mainnet_data/block" + defaultReceiptsFilePath = "../../../mainnet_data/receipts" +) + +const ( + TEST_RAW_URL = "TEST_RAW_URL" + TEST_BLOCK_NUMBER = "TEST_BLOCK_NUMBER" +) + +// ProblemBlocks list of known problem blocks, with funky edge cases +var ProblemBlocks = []int64{ + 12600011, + 12619985, + 12625121, + 12655432, + 12579670, + 12914664, +} + +// TestConfig holds configuration params for mainnet tests +type TestConfig struct { + RawURL string + BlockNumber *big.Int + LocalCache bool +} + +// DefaultTestConfig is the default TestConfig +var DefaultTestConfig = TestConfig{ + RawURL: "http://127.0.0.1:8545", + BlockNumber: big.NewInt(12914664), + LocalCache: true, +} + +func GetTestConfig() TestConfig { + conf := DefaultTestConfig + rawURL := os.Getenv(TEST_RAW_URL) + if rawURL == "" { + fmt.Printf("Warning: no raw url configured for statediffing mainnet tests, will look for local file and"+ + "then try default endpoint (%s)\r\n", DefaultTestConfig.RawURL) + } else { + conf.RawURL = rawURL + } + return conf +} + +// TestBlockAndReceiptsFromEnv retrieves the block and receipts using env variables to override default config block number +func TestBlockAndReceiptsFromEnv(conf TestConfig) (*types.Block, types.Receipts, error) { + blockNumberStr := os.Getenv(TEST_BLOCK_NUMBER) + blockNumber, ok := new(big.Int).SetString(blockNumberStr, 10) + if !ok { + fmt.Printf("Warning: no blockNumber configured for statediffing mainnet tests, using default (%d)\r\n", + DefaultTestConfig.BlockNumber) + } else { + conf.BlockNumber = blockNumber + } + return TestBlockAndReceipts(conf) +} + +// TestBlockAndReceipts retrieves the block and receipts for the provided test config +// It first tries to load files from the local system before setting up and using an ethclient.Client to pull the data +func TestBlockAndReceipts(conf TestConfig) (*types.Block, types.Receipts, error) { + var cli *ethclient.Client + var err error + var block *types.Block + var receipts types.Receipts + blockFilePath := fmt.Sprintf("%s_%s.rlp", defaultBlockFilePath, conf.BlockNumber.String()) + if _, err = os.Stat(blockFilePath); !errors.Is(err, os.ErrNotExist) { + fmt.Printf("local file (%s) found for block %s\n", blockFilePath, conf.BlockNumber.String()) + block, err = LoadBlockRLP(blockFilePath) + if err != nil { + fmt.Printf("loading local file (%s) failed (%s), dialing remote client at %s\n", blockFilePath, err.Error(), conf.RawURL) + cli, err = ethclient.Dial(conf.RawURL) + if err != nil { + return nil, nil, err + } + block, err = FetchBlock(cli, conf.BlockNumber) + if err != nil { + return nil, nil, err + } + if conf.LocalCache { + if err := WriteBlockRLP(blockFilePath, block); err != nil { + return nil, nil, err + } + } + } + } else { + fmt.Printf("no local file found for block %s, dialing remote client at %s\n", conf.BlockNumber.String(), conf.RawURL) + cli, err = ethclient.Dial(conf.RawURL) + if err != nil { + return nil, nil, err + } + block, err = FetchBlock(cli, conf.BlockNumber) + if err != nil { + return nil, nil, err + } + if conf.LocalCache { + if err := WriteBlockRLP(blockFilePath, block); err != nil { + return nil, nil, err + } + } + } + receiptsFilePath := fmt.Sprintf("%s_%s.rlp", defaultReceiptsFilePath, conf.BlockNumber.String()) + if _, err = os.Stat(receiptsFilePath); !errors.Is(err, os.ErrNotExist) { + fmt.Printf("local file (%s) found for block %s receipts\n", receiptsFilePath, conf.BlockNumber.String()) + receipts, err = LoadReceiptsEncoding(receiptsFilePath, len(block.Transactions())) + if err != nil { + fmt.Printf("loading local file (%s) failed (%s), dialing remote client at %s\n", receiptsFilePath, err.Error(), conf.RawURL) + if cli == nil { + cli, err = ethclient.Dial(conf.RawURL) + if err != nil { + return nil, nil, err + } + } + receipts, err = FetchReceipts(cli, block) + if err != nil { + return nil, nil, err + } + if conf.LocalCache { + if err := WriteReceiptsEncoding(receiptsFilePath, block.Number(), receipts); err != nil { + return nil, nil, err + } + } + } + } else { + fmt.Printf("no local file found for block %s receipts, dialing remote client at %s\n", conf.BlockNumber.String(), conf.RawURL) + if cli == nil { + cli, err = ethclient.Dial(conf.RawURL) + if err != nil { + return nil, nil, err + } + } + receipts, err = FetchReceipts(cli, block) + if err != nil { + return nil, nil, err + } + if conf.LocalCache { + if err := WriteReceiptsEncoding(receiptsFilePath, block.Number(), receipts); err != nil { + return nil, nil, err + } + } + } + return block, receipts, nil +} + +// FetchBlock fetches the block at the provided height using the ethclient.Client +func FetchBlock(cli *ethclient.Client, blockNumber *big.Int) (*types.Block, error) { + return cli.BlockByNumber(context.Background(), blockNumber) +} + +// FetchReceipts fetches the receipts for the provided block using the ethclient.Client +func FetchReceipts(cli *ethclient.Client, block *types.Block) (types.Receipts, error) { + receipts := make(types.Receipts, len(block.Transactions())) + for i, tx := range block.Transactions() { + rct, err := cli.TransactionReceipt(context.Background(), tx.Hash()) + if err != nil { + return nil, err + } + receipts[i] = rct + } + return receipts, nil +} + +// WriteBlockRLP writes out the RLP encoding of the block to the provided filePath +func WriteBlockRLP(filePath string, block *types.Block) error { + if filePath == "" { + filePath = fmt.Sprintf("%s_%s.rlp", defaultBlockFilePath, block.Number().String()) + } + if _, err := os.Stat(filePath); !errors.Is(err, os.ErrNotExist) { + return fmt.Errorf("cannot create file, file (%s) already exists", filePath) + } + file, err := os.Create(filePath) + if err != nil { + return fmt.Errorf("unable to create file (%s), err: %v", filePath, err) + } + fmt.Printf("writing block rlp to file at %s\r\n", filePath) + if err := block.EncodeRLP(file); err != nil { + return err + } + return file.Close() +} + +// LoadBlockRLP loads block from the rlp at filePath +func LoadBlockRLP(filePath string) (*types.Block, error) { + blockBytes, err := os.ReadFile(filePath) + if err != nil { + return nil, err + } + block := new(types.Block) + return block, rlp.DecodeBytes(blockBytes, block) +} + +// LoadReceiptsEncoding loads receipts from the encoding at filePath +func LoadReceiptsEncoding(filePath string, cap int) (types.Receipts, error) { + rctsBytes, err := os.ReadFile(filePath) + if err != nil { + return nil, err + } + receipts := new(types.Receipts) + return *receipts, rlp.DecodeBytes(rctsBytes, receipts) +} + +// WriteReceiptsEncoding writes out the consensus encoding of the receipts to the provided io.WriteCloser +func WriteReceiptsEncoding(filePath string, blockNumber *big.Int, receipts types.Receipts) error { + if filePath == "" { + filePath = fmt.Sprintf("%s_%s.rlp", defaultReceiptsFilePath, blockNumber.String()) + } + if _, err := os.Stat(filePath); !errors.Is(err, os.ErrNotExist) { + return fmt.Errorf("cannot create file, file (%s) already exists", filePath) + } + file, err := os.Create(filePath) + if err != nil { + return fmt.Errorf("unable to create file (%s), err: %v", filePath, err) + } + defer file.Close() + fmt.Printf("writing receipts rlp to file at %s\r\n", filePath) + return rlp.Encode(file, receipts) +} diff --git a/statediff/indexer/test_helpers/test_helpers.go b/statediff/indexer/test_helpers/test_helpers.go new file mode 100644 index 000000000..1b5335b78 --- /dev/null +++ b/statediff/indexer/test_helpers/test_helpers.go @@ -0,0 +1,131 @@ +// VulcanizeDB +// Copyright © 2019 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package test_helpers + +import ( + "bufio" + "context" + "os" + "testing" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/sql" +) + +// ListContainsString used to check if a list of strings contains a particular string +func ListContainsString(sss []string, s string) bool { + for _, str := range sss { + if s == str { + return true + } + } + return false +} + +// DedupFile removes duplicates from the given file +func DedupFile(filePath string) error { + f, err := os.OpenFile(filePath, os.O_CREATE|os.O_RDONLY, os.ModePerm) + if err != nil { + return err + } + + stmts := make(map[string]struct{}, 0) + sc := bufio.NewScanner(f) + + for sc.Scan() { + s := sc.Text() + stmts[s] = struct{}{} + } + if err != nil { + return err + } + + f.Close() + + f, err = os.Create(filePath) + if err != nil { + return err + } + defer f.Close() + + for stmt := range stmts { + f.Write([]byte(stmt + "\n")) + } + + return nil +} + +// TearDownDB is used to tear down the watcher dbs after tests +func TearDownDB(t *testing.T, db sql.Database) { + ctx := context.Background() + tx, err := db.Begin(ctx) + if err != nil { + t.Fatal(err) + } + + _, err = tx.Exec(ctx, `DELETE FROM eth.header_cids`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM eth.uncle_cids`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM eth.transaction_cids`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM eth.receipt_cids`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM eth.state_cids`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM eth.storage_cids`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM eth.state_accounts`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM eth.access_list_elements`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM eth.log_cids`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM blocks`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM nodes`) + if err != nil { + t.Fatal(err) + } + _, err = tx.Exec(ctx, `DELETE FROM eth_meta.watched_addresses`) + if err != nil { + t.Fatal(err) + } + err = tx.Commit(ctx) + if err != nil { + t.Fatal(err) + } +} diff --git a/statediff/mainnet_tests/block0_rlp b/statediff/mainnet_tests/block0_rlp new file mode 100644 index 0000000000000000000000000000000000000000..eb912911d159fcb7116d8bb9aee0f20f04a1bdcd GIT binary patch literal 540 zcmey#B>9s`WB~&Kut4^V?~8lKW2;uTZcX2I=8Dv1Ay?@sT_wUF7CQZPxH8#&3N`~4 zT>mlMf9slxn`<~{&$`Ok{r1o~uA*BPo2tY)Zy7}Jv$`w@dm%3_eI|6-|7O=`lMejI zi}rXRJu_$R0mdZ#t&fwpC=yh#lM$Q6BTB551?1g^CgF~Th6RGVU)=UHsrKucTqDz5 i@MP;-eqDFg%TGgWSKmh^`?h+u1H-La+RLaRU-Uhq0?W7E0f))urAHh4LTt%Cei$r$3@0SR&|VnN5tTvzjbOKu*B6$+WjzF9T#@_xfFQR|9*?g-8ocF5VbK=zF9i+jgo zt5&yeP2YCriqvHxSLrETCBh#TI{kIHGTD8~U46Mc&nBi9x&0wd>mySemVB_$S>Wk> z(=oY3P@rVWt$8Q*u$ay*mj27JUE7!M&R(BOZ#FwF2zwzfE`26++5cwOXOj;6$cy%P zAU!i@?E%Il{jHCawsml^6A=o#o5 zB&Q^so0*vF=Va!UR_Lea8|s-X&}W};bd}-iDUxyWDbCki*GHEg$zl2ZbE3GQWEani SzqdMe1piW#YFjn$zySc*K!fW5 literal 0 HcmV?d00001 diff --git a/statediff/mainnet_tests/block3_rlp b/statediff/mainnet_tests/block3_rlp new file mode 100644 index 0000000000000000000000000000000000000000..86f90a83a6e553ed112ceb9f361344f32f5a48b5 GIT binary patch literal 1079 zcmey#V)BzoV!@WF3$H&*GYnccsi1dBi?R962$2NQMGg9nla~mvxXn1ZAX|K=#jz*v zB{pTi{_P^Qn*`xzM@}fN+ zNYBh!dw?-Xf9vDqEs6vc>||sZ>7bSQUxWTX<|g5ehL+G>P6-R#Q%f@R%MA4l^bB;< zlFcnsjEz$Cb29TvEA-Rz4fRYGq(0Ppqx>&5^x2-WI0^@n(n$#;=+V1lV`Ku^zd#x z-M@H&>>1w|_m0O_t!~|#zU|BvsmnsH(o?!hgg-2F`s;9Ivip=1ug@I)nlXPx>fGi+ zW5=g!B~7MyERf4%W^Mc{QM{$XsiAew<;@4YR)i{i=rQp5`Y!qMK01? literal 0 HcmV?d00001 diff --git a/statediff/mainnet_tests/builder_test.go b/statediff/mainnet_tests/builder_test.go new file mode 100644 index 000000000..f5027986e --- /dev/null +++ b/statediff/mainnet_tests/builder_test.go @@ -0,0 +1,692 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package statediff_test + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "math/big" + "os" + "sort" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff" + "github.com/ethereum/go-ethereum/statediff/test_helpers" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +var ( + db ethdb.Database + genesisBlock, block0, block1, block2, block3 *types.Block + block1CoinbaseAddr, block2CoinbaseAddr, block3CoinbaseAddr common.Address + block1CoinbaseHash, block2CoinbaseHash, block3CoinbaseHash common.Hash + builder statediff.Builder + emptyStorage = make([]sdtypes.StorageNode, 0) + + // block 1 data + block1CoinbaseAccount, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(5000000000000000000), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + block1CoinbaseLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("38251692195afc818c92b485fcb8a4691af89cbe5a2ab557b83a4261be2a9a"), + block1CoinbaseAccount, + }) + block1CoinbaseLeafNodeHash = crypto.Keccak256(block1CoinbaseLeafNode) + block1x040bBranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("cc947d5ebb80600bad471f12c6ad5e4981e3525ecf8a2d982cc032536ae8b66d"), + common.Hex2Bytes("e80e52462e635a834e90e86ccf7673a6430384aac17004d626f4db831f0624bc"), + common.Hex2Bytes("59a8f11f60cb0a8488831f242da02944a26fd269d0608a44b8b873ded9e59e1b"), + common.Hex2Bytes("1ffb51e987e3cbd2e1dc1a64508d2e2b265477e21698b0d10fdf137f35027f40"), + []byte{}, + common.Hex2Bytes("ce5077f49a13ff8199d0e77715fdd7bfd6364774effcd5499bd93cba54b3c644"), + common.Hex2Bytes("f5146783c048e66ce1a776ae990b4255e5fba458ece77fcb83ff6e91d6637a88"), + common.Hex2Bytes("6a0558b6c38852e985cf01c2156517c1c6a1e64c787a953c347825f050b236c6"), + common.Hex2Bytes("56b6e93958b99aaae158cc2329e71a1865ba6f39c67b096922c5cf3ed86b0ae5"), + []byte{}, + common.Hex2Bytes("50d317a89a3405367d66668902f2c9f273a8d0d7d5d790dc516bca142f4a84af"), + common.Hex2Bytes("c72ca72750fdc1af3e6da5c7c5d82c54e4582f15b488a8aa1674058a99825dae"), + common.Hex2Bytes("e1a489df7b18cde818da6d38e235b026c2e61bcd3d34880b3ed0d67e0e4f0159"), + common.Hex2Bytes("b58d5062f2609fd2d68f00d14ab33fef2b373853877cf40bf64729e85b8fdc54"), + block1CoinbaseLeafNodeHash, + []byte{}, + []byte{}, + }) + block1x040bBranchNodeHash = crypto.Keccak256(block1x040bBranchNode) + block1x04BranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("a9317a59365ca09cefcd384018696590afffc432e35a97e8f85aa48907bf3247"), + common.Hex2Bytes("e0bc229254ce7a6a736c3953e570ab18b4a7f5f2a9aa3c3057b5f17d250a1cad"), + common.Hex2Bytes("a2484ec8884dbe0cf24ece99d67df0d1fe78992d67cc777636a817cb2ef205aa"), + common.Hex2Bytes("12b78d4078c607747f06bb88bd08f839eaae0e3ac6854e5f65867d4f78abb84e"), + common.Hex2Bytes("359a51862df5462e4cd302f69cb338512f21eb37ce0791b9a562e72ec48b7dbf"), + common.Hex2Bytes("13f8d617b6a734da9235b6ac80bdd7aeaff6120c39aa223638d88f22d4ba4007"), + common.Hex2Bytes("02055c6400e0ec3440a8bb8fdfd7d6b6c57b7bf83e37d7e4e983d416fdd8314e"), + common.Hex2Bytes("4b1cca9eb3e47e805e7f4c80671a9fcd589fd6ddbe1790c3f3e177e8ede01b9e"), + common.Hex2Bytes("70c3815efb23b986018089e009a38e6238b8850b3efd33831913ca6fa9240249"), + common.Hex2Bytes("7084699d2e72a193fd75bb6108ae797b4661696eba2d631d521fc94acc7b3247"), + common.Hex2Bytes("b2b3cd9f1e46eb583a6185d9a96b4e80125e3d75e6191fdcf684892ef52935cb"), + block1x040bBranchNodeHash, + common.Hex2Bytes("34d9ff0fee6c929424e52268dedbc596d10786e909c5a68d6466c2aba17387ce"), + common.Hex2Bytes("7484d5e44b6ee6b10000708c37e035b42b818475620f9316beffc46531d1eebf"), + common.Hex2Bytes("30c8a283adccf2742272563cd3d6710c89ba21eac0118bf5310cfb231bcca77f"), + common.Hex2Bytes("4bae8558d2385b8d3bc6e6ede20bdbc5dbb0b5384c316ba8985682f88d2e506d"), + []byte{}, + }) + block1x04BranchNodeHash = crypto.Keccak256(block1x04BranchNode) + block1RootBranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("90dcaf88c40c7bbc95a912cbdde67c175767b31173df9ee4b0d733bfdd511c43"), + common.Hex2Bytes("babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bd"), + common.Hex2Bytes("473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021"), + common.Hex2Bytes("bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0"), + block1x04BranchNodeHash, + common.Hex2Bytes("a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7"), + common.Hex2Bytes("e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92d"), + common.Hex2Bytes("f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721"), + common.Hex2Bytes("7117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681"), + common.Hex2Bytes("69eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472"), + common.Hex2Bytes("203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8e"), + common.Hex2Bytes("9287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208"), + common.Hex2Bytes("6fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94ec"), + common.Hex2Bytes("7b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475"), + common.Hex2Bytes("51f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0"), + common.Hex2Bytes("89d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb"), + []byte{}, + }) + + // block 2 data + block2CoinbaseAccount, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: big.NewInt(5000000000000000000), + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + block2CoinbaseLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("20679cbcf198c1741a6f4e4473845659a30caa8b26f8d37a0be2e2bc0d8892"), + block2CoinbaseAccount, + }) + block2CoinbaseLeafNodeHash = crypto.Keccak256(block2CoinbaseLeafNode) + block2MovedPremineBalance, _ = new(big.Int).SetString("4000000000000000000000", 10) + block2MovedPremineAccount, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: block2MovedPremineBalance, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + block2MovedPremineLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("20f2e24db7943eab4415f99e109698863b0fecca1cf9ffc500f38cefbbe29e"), + block2MovedPremineAccount, + }) + block2MovedPremineLeafNodeHash = crypto.Keccak256(block2MovedPremineLeafNode) + block2x00080dBranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + block2MovedPremineLeafNodeHash, + []byte{}, + []byte{}, + []byte{}, + block2CoinbaseLeafNodeHash, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + }) + block2x00080dBranchNodeHash = crypto.Keccak256(block2x00080dBranchNode) + block2x0008BranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("def97a26f824fc3911cf7f8c41dfc9bc93cc36ae2248de22ecae01d6950b2dc9"), + common.Hex2Bytes("234a575e2c5badab8de0f6515b6723195323a0562fbe1316255888637043f1c1"), + common.Hex2Bytes("29659740af1c23306ee8f8294c71a5632ace8c80b1eb61cfdf7022f47ff52305"), + common.Hex2Bytes("cf2681d23bb666d89dec8123bce9e626240a7e2ce7a1e8316b1ee88181c9471c"), + common.Hex2Bytes("18d8de6967fe34b9fd411c74fecc45f8a737961791e70d8ece967bb07cf4d4dc"), + common.Hex2Bytes("7cad60c7cbca8c79c2db5a8fc1baa9381484d43d6c37dfb97718c3a109d47dfc"), + common.Hex2Bytes("2138f5a9062b750b6320e5fac5b134da90a9edbda06ef3e1ae64fb1366ca998c"), + common.Hex2Bytes("532826502a9661fcae7c0f5d2a4c8cb287dfc521e828349543c5a461a9d591ed"), + common.Hex2Bytes("30543537413dd086d4b1560f46b90e8da0f43de5584a138ab036d74e84657523"), + common.Hex2Bytes("c98042928af640bfa1142aca895cd76e146332dce94ddad3426e74ed519ca1e0"), + common.Hex2Bytes("43de3e62cc3148193899d018dff813c04c5b636ce95bd7e828416204292d9ff9"), + []byte{}, + common.Hex2Bytes("78d533b9182bb42f6c16e9ebd5734f0d280179ba1c9b6316c2c1df73f7dd8a54"), + block2x00080dBranchNodeHash, + common.Hex2Bytes("934b736b57a892aaa15a03c7e37746bb096313727135f9841cb64c263785cf81"), + common.Hex2Bytes("38ce97150e90dfd7258901a0ddee72d8e30760a3d0419dbb80135c66588739a2"), + []byte{}, + }) + block2x0008BranchNodeHash = crypto.Keccak256(block2x0008BranchNode) + block2x00BranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("e45a9e85cab1b6eb18b30df2c6acc448bbac6a30d81646823b31223e16e5063e"), + common.Hex2Bytes("33bd7171d556b981f6849064eb09412b24fedc0812127db936067043f53db1b9"), + common.Hex2Bytes("ca56945f074da4f15587404593faf3a50d17ea0e21a418ad6ec99bdf4bf3f914"), + common.Hex2Bytes("da23e9004f782df128eea1adff77952dc85f91b7f7ca4893aac5f21d24c3a1c9"), + common.Hex2Bytes("ba5ec61fa780ee02af19db99677c37560fc4f0df5c278d9dfa2837f30f72bc6b"), + common.Hex2Bytes("8310ad91625c2e3429a74066b7e2e0c958325e4e7fa3ec486b73b7c8300cfef7"), + common.Hex2Bytes("732e5c103bf4d5adfef83773026809d9405539b67e93293a02342e83ad2fb766"), + common.Hex2Bytes("30d14ff0c2aab57d1fbaf498ab14519b4e9d94f149a3dc15f0eec5adf8df25e1"), + block2x0008BranchNodeHash, + common.Hex2Bytes("5a43bd92e55aa78df60e70b6b53b6366c4080fd6a5bdd7b533b46aff4a75f6f2"), + common.Hex2Bytes("a0c410aa59efe416b1213166fab680ce330bd46c3ebf877ff14609ee6a383600"), + common.Hex2Bytes("2f41e918786e557293068b1eda9b3f9f86ed4e65a6a5363ee3262109f6e08b17"), + common.Hex2Bytes("01f42a40f02f6f24bb97b09c4d3934e8b03be7cfbb902acc1c8fd67a7a5abace"), + common.Hex2Bytes("0acbdce2787a6ea177209bd13bfc9d0779d7e2b5249e0211a2974164e14312f5"), + common.Hex2Bytes("dadbe113e4132e0c0c3cd4867e0a2044d0e5a3d44b350677ed42fc9244d004d4"), + common.Hex2Bytes("aa7441fefc17d76aedfcaf692fe71014b94c1547b6d129562b34fc5995ca0d1a"), + []byte{}, + }) + block2x00BranchNodeHash = crypto.Keccak256(block2x00BranchNode) + block2RootBranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + block2x00BranchNodeHash, + common.Hex2Bytes("babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bd"), + common.Hex2Bytes("473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021"), + common.Hex2Bytes("bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0"), + block1x04BranchNodeHash, + common.Hex2Bytes("a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7"), + common.Hex2Bytes("e823850f50bf72baae9d1733a36a444ab65d0a6faaba404f0583ce0ca4dad92d"), + common.Hex2Bytes("f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721"), + common.Hex2Bytes("7117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681"), + common.Hex2Bytes("69eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472"), + common.Hex2Bytes("203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8e"), + common.Hex2Bytes("9287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208"), + common.Hex2Bytes("6fc2d754e304c48ce6a517753c62b1a9c1d5925b89707486d7fc08919e0a94ec"), + common.Hex2Bytes("7b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475"), + common.Hex2Bytes("51f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0"), + common.Hex2Bytes("89d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb"), + []byte{}, + }) + + // block3 data + // path 060e0f + blcok3CoinbaseBalance, _ = new(big.Int).SetString("5156250000000000000", 10) + block3CoinbaseAccount, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: blcok3CoinbaseBalance, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + block3CoinbaseLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3a174f00e64521a535f35e67c1aa241951c791639b2f3d060f49c5d9fa8b9e"), + block3CoinbaseAccount, + }) + block3CoinbaseLeafNodeHash = crypto.Keccak256(block3CoinbaseLeafNode) + // path 0c0e050703 + block3MovedPremineBalance1, _ = new(big.Int).SetString("3750000000000000000", 10) + block3MovedPremineAccount1, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: block3MovedPremineBalance1, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + block3MovedPremineLeafNode1, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3ced93917e658d10e2d9009470dad72b63c898d173721194a12f2ae5e190"), // ce573ced93917e658d10e2d9009470dad72b63c898d173721194a12f2ae5e190 + block3MovedPremineAccount1, + }) + block3MovedPremineLeafNodeHash1 = crypto.Keccak256(block3MovedPremineLeafNode1) + // path 0c0e050708 + block3MovedPremineBalance2, _ = new(big.Int).SetString("1999944000000000000000", 10) + block3MovedPremineAccount2, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: 0, + Balance: block3MovedPremineBalance2, + CodeHash: test_helpers.NullCodeHash.Bytes(), + Root: test_helpers.EmptyContractRoot, + }) + block3MovedPremineLeafNode2, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("33bc1e69eedf90f402e11f6862da14ed8e50156635a04d6393bbae154012"), // ce5783bc1e69eedf90f402e11f6862da14ed8e50156635a04d6393bbae154012 + block3MovedPremineAccount2, + }) + block3MovedPremineLeafNodeHash2 = crypto.Keccak256(block3MovedPremineLeafNode2) + + block3x0c0e0507BranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + []byte{}, + []byte{}, + []byte{}, + block3MovedPremineLeafNodeHash1, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + block3MovedPremineLeafNodeHash2, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + }) + block3x0c0e0507BranchNodeHash = crypto.Keccak256(block3x0c0e0507BranchNode) + + block3x0c0e05BranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("452e3beb503b1d87ae7c672b98a8e3fd043a671405502562ae1043dc97151a50"), + []byte{}, + common.Hex2Bytes("2f5bb16f77086f67ce8c4258cb9061cb299e597b2ad4ad6d7ccc474d6d88e85e"), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + block3x0c0e0507BranchNodeHash, + []byte{}, + common.Hex2Bytes("44623e5a9319f83870db0ea4611a25fca1e1da3eeea2be4a091dfc15ab45689e"), + common.Hex2Bytes("b41e047a97f44fa4cb8146467b88c8f4705811029d9e170abb0aba7d0af9f0da"), + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + []byte{}, + }) + block3x0c0e05BranchNodeHash = crypto.Keccak256(block3x0c0e05BranchNode) + + block3x060eBranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("94d77c7c30b88829c9989948b206cda5e532b38b49534261c517aebf4a3e6fdb"), + common.Hex2Bytes("a5cf57a50da8204964e834a12a53f9bed7afc9b700a4a81b440122d60c7603a7"), + []byte{}, + common.Hex2Bytes("3730ec0571f34b6c3b178dc26ccb31a3f50c29da9b1921e41b9477ddab41b0fe"), + []byte{}, + common.Hex2Bytes("543952bb9566c2018cf8d7b90d6a7903cdfff3d79ac36189be5322de42fc3fc0"), + []byte{}, + common.Hex2Bytes("c4a49b66f0bcc08531e50cdea5577a281d111fa542eaefd9a9aead8febb0735e"), + common.Hex2Bytes("362ad58916c71463b98c079649fc486c5f082c4f548bd4ab501515f0c5641cb4"), + common.Hex2Bytes("36aae109f6f55f0bd05eb05bb365af2332dfe5f06d3d17903e88534c319eb709"), + common.Hex2Bytes("430dcfc5cc49a6b490dd54138920e8f94e427239c2bccc14705cfd4ff6cc4383"), + common.Hex2Bytes("73ed77563dfed2fdb38900b474db88b2270f449167e0d877fda9e2229f119fe8"), + common.Hex2Bytes("5dfe06013f2a41f1779194ceb07769d019f518b2a694a82fa1661e60fd973eaa"), + common.Hex2Bytes("80bdfd85fbb6b45850bad6e34136aaa1b04711e47469fa2f0d19eca52089efb5"), + []byte{}, + block3CoinbaseLeafNodeHash, + []byte{}, + }) + block3x060eBranchNodeHash = crypto.Keccak256(block3x060eBranchNode) + + block3x0c0eBranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("70647f11b2b995d718f9e8aceb44c8839e0055641930d216fa6090280a9d63d5"), + common.Hex2Bytes("fdfb17cd2fba2a14219981cb7886a1977cd85dbef5c767c562f4a5f547febff0"), + common.Hex2Bytes("ff87313253ec6f860142b7bf62efb4cb07ea668c57aa90cbe9ef22b72fee15c7"), + common.Hex2Bytes("3a77b3c26a54ad37bdf4e19c1bce93493ec0f79d9ad90190b70bc840b54918e1"), + common.Hex2Bytes("af1b3b14324561b68f2e24dbcc28673ab35ce3fd0230fe2bc86b3d1931745195"), + block3x0c0e05BranchNodeHash, + common.Hex2Bytes("647dcbfe6aabcd9d219ff40422af4326bfc1ec66703195a78eb48618ddef248d"), + common.Hex2Bytes("2d2bf06159cc8928283c3419a03f08ea34c493a9d002a0ec76d5c429508ccaf4"), + common.Hex2Bytes("d7147251b3f48f25e1e4c6d8f83a00b1eca66e99a4ea0d238942ce72d0ba6414"), + common.Hex2Bytes("cb859370869967594fb29f4e2904413310146733d7fcbd11407f3e47626e0e34"), + common.Hex2Bytes("b93ab9b0bd83963860fbe0b7d543879cfde756ea1618d2a40d85483058cc5a26"), + common.Hex2Bytes("45aee096499d209931457ce251c5c7e5543f22524f67785ff8f0f3f02588b0ed"), + []byte{}, + common.Hex2Bytes("aa2ae9379797c5066bba646108074ae8677e82c923d584b6d1c1268ca3708c5c"), + common.Hex2Bytes("e6eb055f0d8e194c083471479a3de87fa0f90c0f4aaa518416ec1e469ec32e3a"), + common.Hex2Bytes("0cc9c50fc7eba162fb17f2e04e3599c13abbf210d9781864d0edec401ecaebba"), + []byte{}, + }) + block3x0c0eBranchNodeHash = crypto.Keccak256(block3x0c0eBranchNode) + + block3x06BranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("68f7ff8c074d6e4cccd55b5b1c2116a6dd7047d4332090e6db8839362991b0ae"), + common.Hex2Bytes("c446eb4377c750701374c56e50759e6ba68b7adf4d543e718c8b28a99ae3b6ad"), + common.Hex2Bytes("ef2c49ec64cb65eae0d99684e74c8af2bd0206c9a0214d9d3eddf0881dd8412a"), + common.Hex2Bytes("7096c4cc7e8125f0b142d8644ad681f8a8142e210c806f33f3f7004f0e9d6002"), + common.Hex2Bytes("bc9a8ae647b234cd6607b6b0245e3b3d5ec4f7ea006e7eda1f92d02f0ea91116"), + common.Hex2Bytes("a87720deb92ff2f899e809befab9970a61c86148c4fa09d04b77505ee4a5bda5"), + common.Hex2Bytes("2460e5b6ded7c0001de29c15db124614432fef6486370cc9970f63b0d95fd5e2"), + common.Hex2Bytes("ed1c447d4a32bc31e9e32259dc63da10df91231e786332e3df122b301b1f8fc3"), + common.Hex2Bytes("0d27dfc201d995c2323b792860dbca087da7cc56d1698c39b7c4b9277729c5ca"), + common.Hex2Bytes("f6d2be168d9c17643c9ea80c29322b364604cdfd36eef40123d83fad364e43fa"), + common.Hex2Bytes("004bf1c30a5730f464de1a0ba4ac5b5618df66d6106073d08742166e33a7eeb5"), + common.Hex2Bytes("7298d019a57a1b04ac31ed874d654ba0d3c249704c5d9efa1d08959fc89e0779"), + common.Hex2Bytes("fb3d50b7af6f839e371ff8ebd0322e94e6b6fb7888416737f88cf55bcf5859ec"), + common.Hex2Bytes("4e7a2618fa1fc560a73c24839657adf7e48d600ecfb12333678115936597a913"), + block3x060eBranchNodeHash, + common.Hex2Bytes("1909706c5db040f54c19f4050659ad484982145b02474653917de379f15ebb36"), + []byte{}, + }) + block3x06BranchNodeHash = crypto.Keccak256(block3x06BranchNode) + + block3x0cBranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("dae48f5b47930c28bb116fbd55e52cd47242c71bf55373b55eb2805ee2e4a929"), + common.Hex2Bytes("0f1f37f337ec800e2e5974e2e7355f10f1a4832b39b846d916c3597a460e0676"), + common.Hex2Bytes("da8f627bb8fbeead17b318e0a8e4f528db310f591bb6ab2deda4a9f7ca902ab5"), + common.Hex2Bytes("971c662648d58295d0d0aa4b8055588da0037619951217c22052802549d94a2f"), + common.Hex2Bytes("ccc701efe4b3413fd6a61a6c9f40e955af774649a8d9fd212d046a5a39ddbb67"), + common.Hex2Bytes("d607cdb32e2bd635ee7f2f9e07bc94ddbd09b10ec0901b66628e15667aec570b"), + common.Hex2Bytes("5b89203dc940e6fa70ec19ad4e01d01849d3a5baa0a8f9c0525256ed490b159f"), + common.Hex2Bytes("b84227d48df68aecc772939a59afa9e1a4ab578f7b698bdb1289e29b6044668e"), + common.Hex2Bytes("fd1c992070b94ace57e48cbf6511a16aa770c645f9f5efba87bbe59d0a042913"), + common.Hex2Bytes("e16a7ccea6748ae90de92f8aef3b3dc248a557b9ac4e296934313f24f7fced5f"), + common.Hex2Bytes("42373cf4a00630d94de90d0a23b8f38ced6b0f7cb818b8925fee8f0c2a28a25a"), + common.Hex2Bytes("5f89d2161c1741ff428864f7889866484cef622de5023a46e795dfdec336319f"), + common.Hex2Bytes("7597a017664526c8c795ce1da27b8b72455c49657113e0455552dbc068c5ba31"), + common.Hex2Bytes("d5be9089012fda2c585a1b961e988ea5efcd3a06988e150a8682091f694b37c5"), + block3x0c0eBranchNodeHash, + common.Hex2Bytes("49bf6e8df0acafd0eff86defeeb305568e44d52d2235cf340ae15c6034e2b241"), + []byte{}, + }) + block3x0cBranchNodeHash = crypto.Keccak256(block3x0cBranchNode) + + block3RootBranchNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("f646da473c426e79f1c796b00d4873f47de1dbe1c9d19d63993a05eeb8b4041d"), + common.Hex2Bytes("babe369f6b12092f49181ae04ca173fb68d1a5456f18d20fa32cba73954052bd"), + common.Hex2Bytes("473ecf8a7e36a829e75039a3b055e51b8332cbf03324ab4af2066bbd6fbf0021"), + common.Hex2Bytes("bbda34753d7aa6c38e603f360244e8f59611921d9e1f128372fec0d586d4f9e0"), + common.Hex2Bytes("d9cff5d5f2418afd16a4da5c221fdc8bd47520c5927922f69a68177b64da6ac0"), + common.Hex2Bytes("a5f3f2f7542148c973977c8a1e154c4300fec92f755f7846f1b734d3ab1d90e7"), + block3x06BranchNodeHash, + common.Hex2Bytes("f7a00cbe7d4b30b11faea3ae61b7f1f2b315b61d9f6bd68bfe587ad0eeceb721"), + common.Hex2Bytes("7117ef9fc932f1a88e908eaead8565c19b5645dc9e5b1b6e841c5edbdfd71681"), + common.Hex2Bytes("69eb2de283f32c11f859d7bcf93da23990d3e662935ed4d6b39ce3673ec84472"), + common.Hex2Bytes("203d26456312bbc4da5cd293b75b840fc5045e493d6f904d180823ec22bfed8e"), + common.Hex2Bytes("9287b5c21f2254af4e64fca76acc5cd87399c7f1ede818db4326c98ce2dc2208"), + block3x0cBranchNodeHash, + common.Hex2Bytes("7b1c54f15e299bd58bdfef9741538c7828b5d7d11a489f9c20d052b3471df475"), + common.Hex2Bytes("51f9dd3739a927c89e357580a4c97b40234aa01ed3d5e0390dc982a7975880a0"), + common.Hex2Bytes("89d613f26159af43616fd9455bb461f4869bfede26f2130835ed067a8b967bfb"), + []byte{}, + }) +) + +func init() { + if os.Getenv("MODE") != "statediff" { + fmt.Println("Skipping statediff test") + os.Exit(0) + } + db = rawdb.NewMemoryDatabase() + genesisBlock = core.DefaultGenesisBlock().MustCommit(db) + genBy, err := rlp.EncodeToBytes(genesisBlock) + if err != nil { + log.Fatal(err) + } + var block0RLP []byte + block0, block0RLP, err = loadBlockFromRLPFile("./block0_rlp") + if err != nil { + log.Fatal(err) + } + if !bytes.Equal(genBy, block0RLP) { + log.Fatal("mainnet genesis blocks do not match") + } + block1, _, err = loadBlockFromRLPFile("./block1_rlp") + if err != nil { + log.Fatal(err) + } + block1CoinbaseAddr = block1.Coinbase() + block1CoinbaseHash = crypto.Keccak256Hash(block1CoinbaseAddr.Bytes()) + block2, _, err = loadBlockFromRLPFile("./block2_rlp") + if err != nil { + log.Fatal(err) + } + block2CoinbaseAddr = block2.Coinbase() + block2CoinbaseHash = crypto.Keccak256Hash(block2CoinbaseAddr.Bytes()) + block3, _, err = loadBlockFromRLPFile("./block3_rlp") + if err != nil { + log.Fatal(err) + } + block3CoinbaseAddr = block3.Coinbase() + block3CoinbaseHash = crypto.Keccak256Hash(block3CoinbaseAddr.Bytes()) +} + +func loadBlockFromRLPFile(filename string) (*types.Block, []byte, error) { + f, err := os.Open(filename) + if err != nil { + return nil, nil, err + } + defer f.Close() + blockRLP, err := ioutil.ReadAll(f) + if err != nil { + return nil, nil, err + } + block := new(types.Block) + return block, blockRLP, rlp.DecodeBytes(blockRLP, block) +} + +func TestBuilderOnMainnetBlocks(t *testing.T) { + //genesis := core.Genesis{ + // Config: params.MainnetChainConfig, + //} + chain, _ := core.NewBlockChain(db, nil, nil, nil, ethash.NewFaker(), vm.Config{}, nil, nil) + + _, err := chain.InsertChain([]*types.Block{block1, block2, block3}) + if err != nil { + t.Error(err) + } + params := statediff.Params{ + IntermediateStateNodes: true, + } + builder = statediff.NewBuilder(chain.StateCache()) + + var tests = []struct { + name string + startingArguments statediff.Args + expected *sdtypes.StateObject + }{ + // note that block0 (genesis) has over 1000 nodes due to the pre-allocation for the crowd-sale + // it is not feasible to write a unit test of that size at this time + { + "testBlock1", + //10000 transferred from testBankAddress to account1Addr + statediff.Args{ + OldStateRoot: block0.Root(), + NewStateRoot: block1.Root(), + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + }, + &sdtypes.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []sdtypes.StateNode{ + { + Path: []byte{}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block1RootBranchNode, + }, + { + Path: []byte{'\x04'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block1x04BranchNode, + }, + { + Path: []byte{'\x04', '\x0b'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block1x040bBranchNode, + }, + { + Path: []byte{'\x04', '\x0b', '\x0e'}, + NodeType: sdtypes.Leaf, + LeafKey: block1CoinbaseHash.Bytes(), + NodeValue: block1CoinbaseLeafNode, + StorageNodes: emptyStorage, + }, + }, + }, + }, + { + "testBlock2", + // 1000 transferred from testBankAddress to account1Addr + // 1000 transferred from account1Addr to account2Addr + // account1addr creates a new contract + statediff.Args{ + OldStateRoot: block1.Root(), + NewStateRoot: block2.Root(), + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + }, + &sdtypes.StateObject{ + BlockNumber: block2.Number(), + BlockHash: block2.Hash(), + Nodes: []sdtypes.StateNode{ + { + Path: []byte{}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block2RootBranchNode, + }, + { + Path: []byte{'\x00'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block2x00BranchNode, + }, + { + Path: []byte{'\x00', '\x08'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block2x0008BranchNode, + }, + { + Path: []byte{'\x00', '\x08', '\x0d'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block2x00080dBranchNode, + }, + // this new leaf at x00 x08 x0d x00 was "created" when a premine account (leaf) was moved from path x00 x08 x0d + // this occurred because of the creation of the new coinbase receiving account (leaf) at x00 x08 x0d x04 + // which necessitates we create a branch at x00 x08 x0d (as shown in the below UpdateAccounts) + { + Path: []byte{'\x00', '\x08', '\x0d', '\x00'}, + NodeType: sdtypes.Leaf, + StorageNodes: emptyStorage, + LeafKey: common.HexToHash("08d0f2e24db7943eab4415f99e109698863b0fecca1cf9ffc500f38cefbbe29e").Bytes(), + NodeValue: block2MovedPremineLeafNode, + }, + { + Path: []byte{'\x00', '\x08', '\x0d', '\x04'}, + NodeType: sdtypes.Leaf, + StorageNodes: emptyStorage, + LeafKey: block2CoinbaseHash.Bytes(), + NodeValue: block2CoinbaseLeafNode, + }, + }, + }, + }, + { + "testBlock3", + //the contract's storage is changed + //and the block is mined by account 2 + statediff.Args{ + OldStateRoot: block2.Root(), + NewStateRoot: block3.Root(), + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + }, + &sdtypes.StateObject{ + BlockNumber: block3.Number(), + BlockHash: block3.Hash(), + Nodes: []sdtypes.StateNode{ + { + Path: []byte{}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block3RootBranchNode, + }, + { + Path: []byte{'\x06'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block3x06BranchNode, + }, + { + Path: []byte{'\x06', '\x0e'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block3x060eBranchNode, + }, + { + Path: []byte{'\x0c'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block3x0cBranchNode, + }, + { + Path: []byte{'\x0c', '\x0e'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block3x0c0eBranchNode, + }, + { + Path: []byte{'\x0c', '\x0e', '\x05'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block3x0c0e05BranchNode, + }, + { + Path: []byte{'\x0c', '\x0e', '\x05', '\x07'}, + NodeType: sdtypes.Branch, + StorageNodes: emptyStorage, + NodeValue: block3x0c0e0507BranchNode, + }, + { // How was this account created??? + Path: []byte{'\x0c', '\x0e', '\x05', '\x07', '\x03'}, + NodeType: sdtypes.Leaf, + StorageNodes: emptyStorage, + LeafKey: common.HexToHash("ce573ced93917e658d10e2d9009470dad72b63c898d173721194a12f2ae5e190").Bytes(), + NodeValue: block3MovedPremineLeafNode1, + }, + { // This account (leaf) used to be at 0c 0e 05 07, likely moves because of the new account above + Path: []byte{'\x0c', '\x0e', '\x05', '\x07', '\x08'}, + NodeType: sdtypes.Leaf, + StorageNodes: emptyStorage, + LeafKey: common.HexToHash("ce5783bc1e69eedf90f402e11f6862da14ed8e50156635a04d6393bbae154012").Bytes(), + NodeValue: block3MovedPremineLeafNode2, + }, + { // this is the new account created due to the coinbase mining a block, it's creation shouldn't affect 0x 0e 05 07 + Path: []byte{'\x06', '\x0e', '\x0f'}, + NodeType: sdtypes.Leaf, + StorageNodes: emptyStorage, + LeafKey: block3CoinbaseHash.Bytes(), + NodeValue: block3CoinbaseLeafNode, + }, + }, + }, + }, + } + + for _, test := range tests { + diff, err := builder.BuildStateDiffObject(test.startingArguments, params) + if err != nil { + t.Error(err) + } + receivedStateDiffRlp, err := rlp.EncodeToBytes(diff) + if err != nil { + t.Error(err) + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(&test.expected) + if err != nil { + t.Error(err) + } + sort.Slice(receivedStateDiffRlp, func(i, j int) bool { return receivedStateDiffRlp[i] < receivedStateDiffRlp[j] }) + sort.Slice(expectedStateDiffRlp, func(i, j int) bool { return expectedStateDiffRlp[i] < expectedStateDiffRlp[j] }) + if !bytes.Equal(receivedStateDiffRlp, expectedStateDiffRlp) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual state diff: %+v\nexpected state diff: %+v", diff, test.expected) + } + } +} diff --git a/statediff/metrics.go b/statediff/metrics.go new file mode 100644 index 000000000..f3461ca21 --- /dev/null +++ b/statediff/metrics.go @@ -0,0 +1,108 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package statediff + +import ( + "strings" + + "github.com/ethereum/go-ethereum/metrics" +) + +const ( + namespace = "statediff" +) + +var defaultStatediffMetrics = RegisterStatediffMetrics(metrics.DefaultRegistry) + +// Build a fully qualified metric name +func metricName(subsystem, name string) string { + if name == "" { + return "" + } + parts := []string{namespace, name} + if subsystem != "" { + parts = []string{namespace, subsystem, name} + } + // Prometheus uses _ but geth metrics uses / and replaces + return strings.Join(parts, "/") +} + +type statediffMetricsHandles struct { + // Height of latest synced by core.BlockChain + // FIXME + lastSyncHeight metrics.Gauge + // Height of the latest block received from chainEvent channel + lastEventHeight metrics.Gauge + // Height of latest state diff + lastStatediffHeight metrics.Gauge + // Current length of chainEvent channels + serviceLoopChannelLen metrics.Gauge + writeLoopChannelLen metrics.Gauge + // The start block of the known gap + knownGapStart metrics.Gauge + // The end block of the known gap + knownGapEnd metrics.Gauge + // A known gaps start block which had an error being written to the DB + knownGapErrorStart metrics.Gauge + // A known gaps end block which had an error being written to the DB + knownGapErrorEnd metrics.Gauge + + apiRequests metrics.Counter + apiRequestsUnderway metrics.Counter + + failed metrics.Counter + succeeded metrics.Counter + underway metrics.Counter + totalProcessingTime metrics.Gauge +} + +func RegisterStatediffMetrics(reg metrics.Registry) statediffMetricsHandles { + ctx := statediffMetricsHandles{ + lastSyncHeight: metrics.NewGauge(), + lastEventHeight: metrics.NewGauge(), + lastStatediffHeight: metrics.NewGauge(), + serviceLoopChannelLen: metrics.NewGauge(), + writeLoopChannelLen: metrics.NewGauge(), + knownGapStart: metrics.NewGauge(), + knownGapEnd: metrics.NewGauge(), + knownGapErrorStart: metrics.NewGauge(), + knownGapErrorEnd: metrics.NewGauge(), + apiRequests: metrics.NewCounter(), + apiRequestsUnderway: metrics.NewCounter(), + failed: metrics.NewCounter(), + succeeded: metrics.NewCounter(), + underway: metrics.NewCounter(), + totalProcessingTime: metrics.NewGauge(), + } + subsys := "service" + reg.Register(metricName(subsys, "last_sync_height"), ctx.lastSyncHeight) + reg.Register(metricName(subsys, "last_event_height"), ctx.lastEventHeight) + reg.Register(metricName(subsys, "last_statediff_height"), ctx.lastStatediffHeight) + reg.Register(metricName(subsys, "service_loop_channel_len"), ctx.serviceLoopChannelLen) + reg.Register(metricName(subsys, "write_loop_channel_len"), ctx.writeLoopChannelLen) + reg.Register(metricName(subsys, "known_gaps_start"), ctx.knownGapStart) + reg.Register(metricName(subsys, "known_gaps_end"), ctx.knownGapEnd) + reg.Register(metricName(subsys, "known_gaps_error_start"), ctx.knownGapErrorStart) + reg.Register(metricName(subsys, "known_gaps_error_end"), ctx.knownGapErrorEnd) + reg.Register(metricName(subsys, "api_requests"), ctx.apiRequests) + reg.Register(metricName(subsys, "api_requests_underway"), ctx.apiRequestsUnderway) + reg.Register(metricName(subsys, "failed"), ctx.failed) + reg.Register(metricName(subsys, "succeeded"), ctx.succeeded) + reg.Register(metricName(subsys, "underway"), ctx.underway) + reg.Register(metricName(subsys, "total_processing_time"), ctx.totalProcessingTime) + return ctx +} diff --git a/statediff/metrics_helpers.go b/statediff/metrics_helpers.go new file mode 100644 index 000000000..2bebfe253 --- /dev/null +++ b/statediff/metrics_helpers.go @@ -0,0 +1,89 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package statediff + +import ( + "fmt" + "time" + + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +func countStateDiffBegin(block *types.Block) (time.Time, log.Logger) { + start := time.Now() + logger := log.New("hash", block.Hash().Hex(), "number", block.NumberU64()) + + defaultStatediffMetrics.underway.Inc(1) + logger.Debug(fmt.Sprintf("writeStateDiff BEGIN [underway=%d, succeeded=%d, failed=%d, total_time=%dms]", + defaultStatediffMetrics.underway.Count(), + defaultStatediffMetrics.succeeded.Count(), + defaultStatediffMetrics.failed.Count(), + defaultStatediffMetrics.totalProcessingTime.Value(), + )) + + return start, logger +} + +func countStateDiffEnd(start time.Time, logger log.Logger, err error) time.Duration { + duration := time.Since(start) + defaultStatediffMetrics.underway.Dec(1) + if nil == err { + defaultStatediffMetrics.succeeded.Inc(1) + } else { + defaultStatediffMetrics.failed.Inc(1) + } + defaultStatediffMetrics.totalProcessingTime.Inc(duration.Milliseconds()) + + logger.Debug(fmt.Sprintf("writeStateDiff END (duration=%dms, err=%t) [underway=%d, succeeded=%d, failed=%d, total_time=%dms]", + duration.Milliseconds(), nil != err, + defaultStatediffMetrics.underway.Count(), + defaultStatediffMetrics.succeeded.Count(), + defaultStatediffMetrics.failed.Count(), + defaultStatediffMetrics.totalProcessingTime.Value(), + )) + + return duration +} + +func countApiRequestBegin(methodName string, blockHashOrNumber interface{}) (time.Time, log.Logger) { + start := time.Now() + logger := log.New(methodName, blockHashOrNumber) + + defaultStatediffMetrics.apiRequests.Inc(1) + defaultStatediffMetrics.apiRequestsUnderway.Inc(1) + + logger.Debug(fmt.Sprintf("statediff API BEGIN [underway=%d, requests=%d])", + defaultStatediffMetrics.apiRequestsUnderway.Count(), + defaultStatediffMetrics.apiRequests.Count(), + )) + + return start, logger +} + +func countApiRequestEnd(start time.Time, logger log.Logger, err error) time.Duration { + duration := time.Since(start) + defaultStatediffMetrics.apiRequestsUnderway.Dec(1) + + logger.Debug(fmt.Sprintf("statediff API END (duration=%dms, err=%t) [underway=%d, requests=%d]", + duration.Milliseconds(), nil != err, + defaultStatediffMetrics.apiRequestsUnderway.Count(), + defaultStatediffMetrics.apiRequests.Count(), + )) + + return duration +} diff --git a/statediff/payload.go b/statediff/payload.go new file mode 100644 index 000000000..233141278 --- /dev/null +++ b/statediff/payload.go @@ -0,0 +1,57 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package statediff + +import ( + "encoding/json" + "math/big" +) + +// Payload packages the data to send to statediff subscriptions +type Payload struct { + BlockRlp []byte `json:"blockRlp"` + TotalDifficulty *big.Int `json:"totalDifficulty"` + ReceiptsRlp []byte `json:"receiptsRlp"` + StateObjectRlp []byte `json:"stateObjectRlp" gencodec:"required"` + + encoded []byte + err error +} + +func (sd *Payload) ensureEncoded() { + if sd.encoded == nil && sd.err == nil { + sd.encoded, sd.err = json.Marshal(sd) + } +} + +// Length to implement Encoder interface for Payload +func (sd *Payload) Length() int { + sd.ensureEncoded() + return len(sd.encoded) +} + +// Encode to implement Encoder interface for Payload +func (sd *Payload) Encode() ([]byte, error) { + sd.ensureEncoded() + return sd.encoded, sd.err +} + +// Subscription struct holds our subscription channels +type Subscription struct { + PayloadChan chan<- Payload + QuitChan chan<- bool +} diff --git a/statediff/service.go b/statediff/service.go new file mode 100644 index 000000000..5dce68695 --- /dev/null +++ b/statediff/service.go @@ -0,0 +1,1067 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package statediff + +import ( + "bytes" + "fmt" + "math/big" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/node" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + ind "github.com/ethereum/go-ethereum/statediff/indexer" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + nodeinfo "github.com/ethereum/go-ethereum/statediff/indexer/node" + types2 "github.com/ethereum/go-ethereum/statediff/types" + "github.com/ethereum/go-ethereum/trie" + "github.com/thoas/go-funk" +) + +const ( + chainEventChanSize = 20000 + genesisBlockNumber = 0 + defaultRetryLimit = 3 // default retry limit once deadlock is detected. + deadlockDetected = "deadlock detected" // 40P01 https://www.postgresql.org/docs/current/errcodes-appendix.html + typeAssertionFailed = "type assertion failed" + unexpectedOperation = "unexpected operation" +) + +var writeLoopParams = ParamsWithMutex{ + Params: Params{ + IntermediateStateNodes: true, + IntermediateStorageNodes: true, + IncludeBlock: true, + IncludeReceipts: true, + IncludeTD: true, + IncludeCode: true, + }, +} + +type blockChain interface { + SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription + CurrentBlock() *types.Block + GetBlockByHash(hash common.Hash) *types.Block + GetBlockByNumber(number uint64) *types.Block + GetReceiptsByHash(hash common.Hash) types.Receipts + GetTd(hash common.Hash, number uint64) *big.Int + UnlockTrie(root common.Hash) + StateCache() state.Database +} + +// IService is the state-diffing service interface +type IService interface { + // Lifecycle Start() and Stop() methods + node.Lifecycle + // APIs method for getting API(s) for this service + APIs() []rpc.API + // Loop is the main event loop for processing state diffs + Loop(chainEventCh chan core.ChainEvent) + // Subscribe method to subscribe to receive state diff processing output + Subscribe(id rpc.ID, sub chan<- Payload, quitChan chan<- bool, params Params) + // Unsubscribe method to unsubscribe from state diff processing + Unsubscribe(id rpc.ID) error + // StateDiffAt method to get state diff object at specific block + StateDiffAt(blockNumber uint64, params Params) (*Payload, error) + // StateDiffFor method to get state diff object at specific block + StateDiffFor(blockHash common.Hash, params Params) (*Payload, error) + // StateTrieAt method to get state trie object at specific block + StateTrieAt(blockNumber uint64, params Params) (*Payload, error) + // StreamCodeAndCodeHash method to stream out all code and codehash pairs + StreamCodeAndCodeHash(blockNumber uint64, outChan chan<- types2.CodeAndCodeHash, quitChan chan<- bool) + // WriteStateDiffAt method to write state diff object directly to DB + WriteStateDiffAt(blockNumber uint64, params Params) JobID + // WriteStateDiffFor method to write state diff object directly to DB + WriteStateDiffFor(blockHash common.Hash, params Params) error + // WriteLoop event loop for progressively processing and writing diffs directly to DB + WriteLoop(chainEventCh chan core.ChainEvent) + // Method to change the addresses being watched in write loop params + WatchAddress(operation types2.OperationType, args []types2.WatchAddressArg) error + + // SubscribeWriteStatus method to subscribe to receive state diff processing output + SubscribeWriteStatus(id rpc.ID, sub chan<- JobStatus, quitChan chan<- bool) + // UnsubscribeWriteStatus method to unsubscribe from state diff processing + UnsubscribeWriteStatus(id rpc.ID) error +} + +// Service is the underlying struct for the state diffing service +type Service struct { + // Used to sync access to the Subscriptions + sync.Mutex + // Used to build the state diff objects + Builder Builder + // Used to subscribe to chain events (blocks) + BlockChain blockChain + // Used to signal shutdown of the service + QuitChan chan bool + // A mapping of rpc.IDs to their subscription channels, mapped to their subscription type (hash of the Params rlp) + Subscriptions map[common.Hash]map[rpc.ID]Subscription + // A mapping of subscription params rlp hash to the corresponding subscription params + SubscriptionTypes map[common.Hash]Params + // Cache the last block so that we can avoid having to lookup the next block's parent + BlockCache BlockCache + // The publicBackendAPI which provides useful information about the current state + BackendAPI ethapi.Backend + // Should the statediff service wait for geth to sync to head? + WaitForSync bool + // Whether we have any subscribers + subscribers int32 + // Interface for publishing statediffs as PG-IPLD objects + indexer interfaces.StateDiffIndexer + // Whether to enable writing state diffs directly to track blockchain head. + enableWriteLoop bool + // Size of the worker pool + numWorkers uint + // Number of retry for aborted transactions due to deadlock. + maxRetry uint + // Write job status subscriptions + jobStatusSubs map[rpc.ID]statusSubscription + // Job ID ticker + lastJobID uint64 + // In flight jobs (for WriteStateDiffAt) + currentJobs map[uint64]JobID + currentJobsMutex sync.Mutex +} + +// IDs used for tracking in-progress jobs (0 for invalid) +type JobID uint64 + +// JobStatus represents the status of a completed job +type JobStatus struct { + id JobID + err error +} + +type statusSubscription struct { + statusChan chan<- JobStatus + quitChan chan<- bool +} + +// BlockCache caches the last block for safe access from different service loops +type BlockCache struct { + sync.Mutex + blocks map[common.Hash]*types.Block + maxSize uint +} + +func NewBlockCache(max uint) BlockCache { + return BlockCache{ + blocks: make(map[common.Hash]*types.Block), + maxSize: max, + } +} + +// New creates a new statediff.Service +// func New(stack *node.Node, ethServ *eth.Ethereum, dbParams *DBParams, enableWriteLoop bool) error { +func New(stack *node.Node, ethServ *eth.Ethereum, cfg *ethconfig.Config, params Config, backend ethapi.Backend) error { + blockChain := ethServ.BlockChain() + var indexer interfaces.StateDiffIndexer + var err error + quitCh := make(chan bool) + indexerConfigAvailable := params.IndexerConfig != nil + if indexerConfigAvailable { + info := nodeinfo.Info{ + GenesisBlock: blockChain.Genesis().Hash().Hex(), + NetworkID: strconv.FormatUint(cfg.NetworkId, 10), + ChainID: blockChain.Config().ChainID.Uint64(), + ID: params.ID, + ClientName: params.ClientName, + } + var err error + _, indexer, err = ind.NewStateDiffIndexer(params.Context, blockChain.Config(), info, params.IndexerConfig) + if err != nil { + return err + } + indexer.ReportDBMetrics(10*time.Second, quitCh) + } + + workers := params.NumWorkers + if workers == 0 { + workers = 1 + } + + sds := &Service{ + Mutex: sync.Mutex{}, + BlockChain: blockChain, + Builder: NewBuilder(blockChain.StateCache()), + QuitChan: quitCh, + Subscriptions: make(map[common.Hash]map[rpc.ID]Subscription), + SubscriptionTypes: make(map[common.Hash]Params), + BlockCache: NewBlockCache(workers), + BackendAPI: backend, + WaitForSync: params.WaitForSync, + indexer: indexer, + enableWriteLoop: params.EnableWriteLoop, + numWorkers: workers, + maxRetry: defaultRetryLimit, + } + stack.RegisterLifecycle(sds) + stack.RegisterAPIs(sds.APIs()) + + if indexerConfigAvailable { + err = loadWatchedAddresses(indexer) + if err != nil { + return err + } + } + + return nil +} + +// Protocols exports the services p2p protocols, this service has none +func (sds *Service) Protocols() []p2p.Protocol { + return []p2p.Protocol{} +} + +// APIs returns the RPC descriptors the statediff.Service offers +func (sds *Service) APIs() []rpc.API { + return []rpc.API{ + { + Namespace: APIName, + Version: APIVersion, + Service: NewPublicStateDiffAPI(sds), + Public: true, + }, + } +} + +// Return the parent block of currentBlock, using the cached block if available; +// and cache the passed block +func (lbc *BlockCache) getParentBlock(currentBlock *types.Block, bc blockChain) *types.Block { + lbc.Lock() + parentHash := currentBlock.ParentHash() + var parentBlock *types.Block + if block, ok := lbc.blocks[parentHash]; ok { + parentBlock = block + if len(lbc.blocks) > int(lbc.maxSize) { + delete(lbc.blocks, parentHash) + } + } else { + parentBlock = bc.GetBlockByHash(parentHash) + } + lbc.blocks[currentBlock.Hash()] = currentBlock + lbc.Unlock() + return parentBlock +} + +type workerParams struct { + chainEventCh <-chan core.ChainEvent + wg *sync.WaitGroup + id uint +} + +func (sds *Service) WriteLoop(chainEventCh chan core.ChainEvent) { + chainEventSub := sds.BlockChain.SubscribeChainEvent(chainEventCh) + defer chainEventSub.Unsubscribe() + errCh := chainEventSub.Err() + var wg sync.WaitGroup + // Process metrics for chain events, then forward to workers + chainEventFwd := make(chan core.ChainEvent, chainEventChanSize) + wg.Add(1) + go func() { + defer wg.Done() + for { + select { + case chainEvent := <-chainEventCh: + lastHeight := defaultStatediffMetrics.lastEventHeight.Value() + nextHeight := int64(chainEvent.Block.Number().Uint64()) + if nextHeight-lastHeight != 1 { + log.Warn("Statediffing service received block out-of-order", "next height", nextHeight, "last height", lastHeight) + } + defaultStatediffMetrics.lastEventHeight.Update(nextHeight) + defaultStatediffMetrics.writeLoopChannelLen.Update(int64(len(chainEventCh))) + chainEventFwd <- chainEvent + case err := <-errCh: + log.Error("Error from chain event subscription", "error", err) + close(sds.QuitChan) + log.Info("Quitting the statediffing writing loop") + if err := sds.indexer.Close(); err != nil { + log.Error("Error closing indexer", "err", err) + } + return + case <-sds.QuitChan: + log.Info("Quitting the statediffing writing loop") + if err := sds.indexer.Close(); err != nil { + log.Error("Error closing indexer", "err", err) + } + return + } + } + }() + wg.Add(int(sds.numWorkers)) + for worker := uint(0); worker < sds.numWorkers; worker++ { + params := workerParams{chainEventCh: chainEventFwd, wg: &wg, id: worker} + go sds.writeLoopWorker(params) + } + wg.Wait() +} + +func (sds *Service) writeGenesisStateDiff(currBlock *types.Block, workerId uint) { + // For genesis block we need to return the entire state trie hence we diff it with an empty trie. + log.Info("Writing state diff", "block height", genesisBlockNumber, "worker", workerId) + writeLoopParams.RLock() + err := sds.writeStateDiffWithRetry(currBlock, common.Hash{}, writeLoopParams.Params) + writeLoopParams.RUnlock() + if err != nil { + log.Error("statediff.Service.WriteLoop: processing error", "block height", + genesisBlockNumber, "error", err.Error(), "worker", workerId) + return + } + defaultStatediffMetrics.lastStatediffHeight.Update(genesisBlockNumber) +} + +func (sds *Service) writeLoopWorker(params workerParams) { + defer params.wg.Done() + for { + select { + //Notify chain event channel of events + case chainEvent := <-params.chainEventCh: + log.Debug("WriteLoop(): chain event received", "event", chainEvent) + currentBlock := chainEvent.Block + parentBlock := sds.BlockCache.getParentBlock(currentBlock, sds.BlockChain) + if parentBlock == nil { + log.Error("Parent block is nil, skipping this block", "block height", currentBlock.Number()) + continue + } + + // chainEvent streams block from block 1, but we also need to include data from the genesis block. + if parentBlock.Number().Uint64() == genesisBlockNumber { + sds.writeGenesisStateDiff(parentBlock, params.id) + } + + log.Info("Writing state diff", "block height", currentBlock.Number().Uint64(), "worker", params.id) + writeLoopParams.RLock() + err := sds.writeStateDiffWithRetry(currentBlock, parentBlock.Root(), writeLoopParams.Params) + writeLoopParams.RUnlock() + if err != nil { + log.Error("statediff.Service.WriteLoop: processing error", + "block height", currentBlock.Number().Uint64(), + "block hash", currentBlock.Hash().Hex(), + "error", err.Error(), + "worker", params.id) + continue + } + + // TODO: how to handle with concurrent workers + defaultStatediffMetrics.lastStatediffHeight.Update(int64(currentBlock.Number().Uint64())) + case <-sds.QuitChan: + log.Info("Quitting the statediff writing process", "worker", params.id) + return + } + } +} + +// Loop is the main processing method +func (sds *Service) Loop(chainEventCh chan core.ChainEvent) { + log.Info("Starting statediff listening loop") + chainEventSub := sds.BlockChain.SubscribeChainEvent(chainEventCh) + defer chainEventSub.Unsubscribe() + errCh := chainEventSub.Err() + for { + select { + //Notify chain event channel of events + case chainEvent := <-chainEventCh: + defaultStatediffMetrics.serviceLoopChannelLen.Update(int64(len(chainEventCh))) + log.Debug("Loop(): chain event received", "event", chainEvent) + // if we don't have any subscribers, do not process a statediff + if atomic.LoadInt32(&sds.subscribers) == 0 { + log.Debug("Currently no subscribers to the statediffing service; processing is halted") + continue + } + currentBlock := chainEvent.Block + parentBlock := sds.BlockCache.getParentBlock(currentBlock, sds.BlockChain) + + if parentBlock == nil { + log.Error("Parent block is nil, skipping this block", "block height", currentBlock.Number()) + continue + } + + // chainEvent streams block from block 1, but we also need to include data from the genesis block. + if parentBlock.Number().Uint64() == genesisBlockNumber { + // For genesis block we need to return the entire state trie hence we diff it with an empty trie. + sds.streamStateDiff(parentBlock, common.Hash{}) + } + + sds.streamStateDiff(currentBlock, parentBlock.Root()) + case err := <-errCh: + log.Error("Error from chain event subscription", "error", err) + close(sds.QuitChan) + log.Info("Quitting the statediffing listening loop") + sds.close() + return + case <-sds.QuitChan: + log.Info("Quitting the statediffing listening loop") + sds.close() + return + } + } +} + +// streamStateDiff method builds the state diff payload for each subscription according to their subscription type and sends them the result +func (sds *Service) streamStateDiff(currentBlock *types.Block, parentRoot common.Hash) { + sds.Lock() + for ty, subs := range sds.Subscriptions { + params, ok := sds.SubscriptionTypes[ty] + if !ok { + log.Error("no parameter set associated with this subscription", "subscription type", ty.Hex()) + sds.closeType(ty) + continue + } + // create payload for this subscription type + payload, err := sds.processStateDiff(currentBlock, parentRoot, params) + if err != nil { + log.Error("statediff processing error", "block height", currentBlock.Number().Uint64(), "parameters", params, "error", err.Error()) + continue + } + for id, sub := range subs { + select { + case sub.PayloadChan <- *payload: + log.Debug("sending statediff payload at head", "height", currentBlock.Number(), "subscription id", id) + default: + log.Info("unable to send statediff payload; channel has no receiver", "subscription id", id) + } + } + } + sds.Unlock() +} + +// StateDiffAt returns a state diff object payload at the specific blockheight +// This operation cannot be performed back past the point of db pruning; it requires an archival node for historical data +func (sds *Service) StateDiffAt(blockNumber uint64, params Params) (*Payload, error) { + currentBlock := sds.BlockChain.GetBlockByNumber(blockNumber) + log.Info("sending state diff", "block height", blockNumber) + + // use watched addresses from statediffing write loop if not provided + if params.WatchedAddresses == nil && writeLoopParams.WatchedAddresses != nil { + writeLoopParams.RLock() + params.WatchedAddresses = make([]common.Address, len(writeLoopParams.WatchedAddresses)) + copy(params.WatchedAddresses, writeLoopParams.WatchedAddresses) + writeLoopParams.RUnlock() + } + // compute leaf paths of watched addresses in the params + params.ComputeWatchedAddressesLeafPaths() + + if blockNumber == 0 { + return sds.processStateDiff(currentBlock, common.Hash{}, params) + } + parentBlock := sds.BlockChain.GetBlockByHash(currentBlock.ParentHash()) + return sds.processStateDiff(currentBlock, parentBlock.Root(), params) +} + +// StateDiffFor returns a state diff object payload for the specific blockhash +// This operation cannot be performed back past the point of db pruning; it requires an archival node for historical data +func (sds *Service) StateDiffFor(blockHash common.Hash, params Params) (*Payload, error) { + currentBlock := sds.BlockChain.GetBlockByHash(blockHash) + log.Info("sending state diff", "block hash", blockHash) + + // use watched addresses from statediffing write loop if not provided + if params.WatchedAddresses == nil && writeLoopParams.WatchedAddresses != nil { + writeLoopParams.RLock() + params.WatchedAddresses = make([]common.Address, len(writeLoopParams.WatchedAddresses)) + copy(params.WatchedAddresses, writeLoopParams.WatchedAddresses) + writeLoopParams.RUnlock() + } + // compute leaf paths of watched addresses in the params + params.ComputeWatchedAddressesLeafPaths() + + if currentBlock.NumberU64() == 0 { + return sds.processStateDiff(currentBlock, common.Hash{}, params) + } + parentBlock := sds.BlockChain.GetBlockByHash(currentBlock.ParentHash()) + return sds.processStateDiff(currentBlock, parentBlock.Root(), params) +} + +// processStateDiff method builds the state diff payload from the current block, parent state root, and provided params +func (sds *Service) processStateDiff(currentBlock *types.Block, parentRoot common.Hash, params Params) (*Payload, error) { + stateDiff, err := sds.Builder.BuildStateDiffObject(Args{ + NewStateRoot: currentBlock.Root(), + OldStateRoot: parentRoot, + BlockHash: currentBlock.Hash(), + BlockNumber: currentBlock.Number(), + }, params) + // allow dereferencing of parent, keep current locked as it should be the next parent + sds.BlockChain.UnlockTrie(parentRoot) + if err != nil { + return nil, err + } + stateDiffRlp, err := rlp.EncodeToBytes(&stateDiff) + if err != nil { + return nil, err + } + log.Info("state diff size", "at block height", currentBlock.Number().Uint64(), "rlp byte size", len(stateDiffRlp)) + return sds.newPayload(stateDiffRlp, currentBlock, params) +} + +func (sds *Service) newPayload(stateObject []byte, block *types.Block, params Params) (*Payload, error) { + payload := &Payload{ + StateObjectRlp: stateObject, + } + if params.IncludeBlock { + blockBuff := new(bytes.Buffer) + if err := block.EncodeRLP(blockBuff); err != nil { + return nil, err + } + payload.BlockRlp = blockBuff.Bytes() + } + if params.IncludeTD { + payload.TotalDifficulty = sds.BlockChain.GetTd(block.Hash(), block.NumberU64()) + } + if params.IncludeReceipts { + receiptBuff := new(bytes.Buffer) + receipts := sds.BlockChain.GetReceiptsByHash(block.Hash()) + if err := rlp.Encode(receiptBuff, receipts); err != nil { + return nil, err + } + payload.ReceiptsRlp = receiptBuff.Bytes() + } + return payload, nil +} + +// StateTrieAt returns a state trie object payload at the specified blockheight +// This operation cannot be performed back past the point of db pruning; it requires an archival node for historical data +func (sds *Service) StateTrieAt(blockNumber uint64, params Params) (*Payload, error) { + currentBlock := sds.BlockChain.GetBlockByNumber(blockNumber) + log.Info("sending state trie", "block height", blockNumber) + + // compute leaf paths of watched addresses in the params + params.ComputeWatchedAddressesLeafPaths() + + return sds.processStateTrie(currentBlock, params) +} + +func (sds *Service) processStateTrie(block *types.Block, params Params) (*Payload, error) { + stateNodes, err := sds.Builder.BuildStateTrieObject(block) + if err != nil { + return nil, err + } + stateTrieRlp, err := rlp.EncodeToBytes(&stateNodes) + if err != nil { + return nil, err + } + log.Info("state trie size", "at block height", block.Number().Uint64(), "rlp byte size", len(stateTrieRlp)) + return sds.newPayload(stateTrieRlp, block, params) +} + +// Subscribe is used by the API to subscribe to the service loop +func (sds *Service) Subscribe(id rpc.ID, sub chan<- Payload, quitChan chan<- bool, params Params) { + log.Info("Subscribing to the statediff service") + if atomic.CompareAndSwapInt32(&sds.subscribers, 0, 1) { + log.Info("State diffing subscription received; beginning statediff processing") + } + + // compute leaf paths of watched addresses in the params + params.ComputeWatchedAddressesLeafPaths() + + // Subscription type is defined as the hash of the rlp-serialized subscription params + by, err := rlp.EncodeToBytes(¶ms) + if err != nil { + log.Error("State diffing params need to be rlp-serializable") + return + } + subscriptionType := crypto.Keccak256Hash(by) + // Add subscriber + sds.Lock() + if sds.Subscriptions[subscriptionType] == nil { + sds.Subscriptions[subscriptionType] = make(map[rpc.ID]Subscription) + } + sds.Subscriptions[subscriptionType][id] = Subscription{ + PayloadChan: sub, + QuitChan: quitChan, + } + sds.SubscriptionTypes[subscriptionType] = params + sds.Unlock() +} + +// Unsubscribe is used to unsubscribe from the service loop +func (sds *Service) Unsubscribe(id rpc.ID) error { + log.Info("Unsubscribing from the statediff service", "subscription id", id) + sds.Lock() + for ty := range sds.Subscriptions { + delete(sds.Subscriptions[ty], id) + if len(sds.Subscriptions[ty]) == 0 { + // If we removed the last subscription of this type, remove the subscription type outright + delete(sds.Subscriptions, ty) + delete(sds.SubscriptionTypes, ty) + } + } + if len(sds.Subscriptions) == 0 { + if atomic.CompareAndSwapInt32(&sds.subscribers, 1, 0) { + log.Info("No more subscriptions; halting statediff processing") + } + } + sds.Unlock() + return nil +} + +// GetSyncStatus will check the status of geth syncing. +// It will return false if geth has finished syncing. +// It will return a true Geth is still syncing. +func (sds *Service) GetSyncStatus(pubEthAPI *ethapi.EthereumAPI) (bool, error) { + syncStatus, err := pubEthAPI.Syncing() + if err != nil { + return true, err + } + + if syncStatus != false { + return true, err + } + return false, err +} + +// WaitingForSync calls GetSyncStatus to check if we have caught up to head. +// It will keep looking and checking if we have caught up to head. +// It will only complete if we catch up to head, otherwise it will keep looping forever. +func (sds *Service) WaitingForSync() error { + log.Info("We are going to wait for geth to sync to head!") + + // Has the geth node synced to head? + Synced := false + pubEthAPI := ethapi.NewEthereumAPI(sds.BackendAPI) + for !Synced { + syncStatus, err := sds.GetSyncStatus(pubEthAPI) + if err != nil { + return err + } + if !syncStatus { + log.Info("Geth has caught up to the head of the chain") + Synced = true + } else { + time.Sleep(1 * time.Second) + } + } + return nil +} + +// Start is used to begin the service +func (sds *Service) Start() error { + log.Info("Starting statediff service") + + if sds.WaitForSync { + log.Info("Statediff service will wait until geth has caught up to the head of the chain.") + err := sds.WaitingForSync() + if err != nil { + return err + } + log.Info("Continuing with startdiff start process") + } + chainEventCh := make(chan core.ChainEvent, chainEventChanSize) + go sds.Loop(chainEventCh) + + if sds.enableWriteLoop { + log.Info("Starting statediff DB write loop", "params", writeLoopParams.Params) + chainEventCh := make(chan core.ChainEvent, chainEventChanSize) + go sds.WriteLoop(chainEventCh) + } + + return nil +} + +// Stop is used to close down the service +func (sds *Service) Stop() error { + log.Info("Stopping statediff service") + close(sds.QuitChan) + return nil +} + +// close is used to close all listening subscriptions +func (sds *Service) close() { + sds.Lock() + for ty, subs := range sds.Subscriptions { + for id, sub := range subs { + select { + case sub.QuitChan <- true: + log.Info("closing subscription", "id", id) + default: + log.Info("unable to close subscription; channel has no receiver", "subscription id", id) + } + delete(sds.Subscriptions[ty], id) + } + delete(sds.Subscriptions, ty) + delete(sds.SubscriptionTypes, ty) + } + sds.Unlock() +} + +// closeType is used to close all subscriptions of given type +// closeType needs to be called with subscription access locked +func (sds *Service) closeType(subType common.Hash) { + subs := sds.Subscriptions[subType] + for id, sub := range subs { + sendNonBlockingQuit(id, sub) + } + delete(sds.Subscriptions, subType) + delete(sds.SubscriptionTypes, subType) +} + +func sendNonBlockingQuit(id rpc.ID, sub Subscription) { + select { + case sub.QuitChan <- true: + log.Info("closing subscription", "id", id) + default: + log.Info("unable to close subscription; channel has no receiver", "subscription id", id) + } +} + +// StreamCodeAndCodeHash subscription method for extracting all the codehash=>code mappings that exist in the trie at the provided height +func (sds *Service) StreamCodeAndCodeHash(blockNumber uint64, outChan chan<- types2.CodeAndCodeHash, quitChan chan<- bool) { + current := sds.BlockChain.GetBlockByNumber(blockNumber) + log.Info("sending code and codehash", "block height", blockNumber) + currentTrie, err := sds.BlockChain.StateCache().OpenTrie(current.Root()) + if err != nil { + log.Error("error creating trie for block", "block height", current.Number(), "err", err) + close(quitChan) + return + } + it := currentTrie.NodeIterator([]byte{}) + leafIt := trie.NewIterator(it) + go func() { + defer close(quitChan) + for leafIt.Next() { + select { + case <-sds.QuitChan: + return + default: + } + account := new(types.StateAccount) + if err := rlp.DecodeBytes(leafIt.Value, account); err != nil { + log.Error("error decoding state account", "err", err) + return + } + codeHash := common.BytesToHash(account.CodeHash) + code, err := sds.BlockChain.StateCache().ContractCode(common.Hash{}, codeHash) + if err != nil { + log.Error("error collecting contract code", "err", err) + return + } + outChan <- types2.CodeAndCodeHash{ + Hash: codeHash, + Code: code, + } + } + }() +} + +// WriteStateDiffAt writes a state diff at the specific blockheight directly to the database +// This operation cannot be performed back past the point of db pruning; it requires an archival node +// for historical data +func (sds *Service) WriteStateDiffAt(blockNumber uint64, params Params) JobID { + sds.currentJobsMutex.Lock() + defer sds.currentJobsMutex.Unlock() + if id, has := sds.currentJobs[blockNumber]; has { + return id + } + id := JobID(atomic.AddUint64(&sds.lastJobID, 1)) + sds.currentJobs[blockNumber] = id + go func() { + err := sds.writeStateDiffAt(blockNumber, params) + sds.currentJobsMutex.Lock() + delete(sds.currentJobs, blockNumber) + sds.currentJobsMutex.Unlock() + for _, sub := range sds.jobStatusSubs { + sub.statusChan <- JobStatus{id, err} + } + }() + return id +} + +func (sds *Service) writeStateDiffAt(blockNumber uint64, params Params) error { + log.Info("writing state diff at", "block height", blockNumber) + + // use watched addresses from statediffing write loop if not provided + if params.WatchedAddresses == nil && writeLoopParams.WatchedAddresses != nil { + writeLoopParams.RLock() + params.WatchedAddresses = make([]common.Address, len(writeLoopParams.WatchedAddresses)) + copy(params.WatchedAddresses, writeLoopParams.WatchedAddresses) + writeLoopParams.RUnlock() + } + // compute leaf paths of watched addresses in the params + params.ComputeWatchedAddressesLeafPaths() + + currentBlock := sds.BlockChain.GetBlockByNumber(blockNumber) + parentRoot := common.Hash{} + if blockNumber != 0 { + parentBlock := sds.BlockChain.GetBlockByHash(currentBlock.ParentHash()) + parentRoot = parentBlock.Root() + } + return sds.writeStateDiffWithRetry(currentBlock, parentRoot, params) +} + +// WriteStateDiffFor writes a state diff for the specific blockhash directly to the database +// This operation cannot be performed back past the point of db pruning; it requires an archival node +// for historical data +func (sds *Service) WriteStateDiffFor(blockHash common.Hash, params Params) error { + log.Info("writing state diff for", "block hash", blockHash) + + // use watched addresses from statediffing write loop if not provided + if params.WatchedAddresses == nil && writeLoopParams.WatchedAddresses != nil { + writeLoopParams.RLock() + params.WatchedAddresses = make([]common.Address, len(writeLoopParams.WatchedAddresses)) + copy(params.WatchedAddresses, writeLoopParams.WatchedAddresses) + writeLoopParams.RUnlock() + } + // compute leaf paths of watched addresses in the params + params.ComputeWatchedAddressesLeafPaths() + + currentBlock := sds.BlockChain.GetBlockByHash(blockHash) + parentRoot := common.Hash{} + if currentBlock.NumberU64() != 0 { + parentBlock := sds.BlockChain.GetBlockByHash(currentBlock.ParentHash()) + parentRoot = parentBlock.Root() + } + return sds.writeStateDiffWithRetry(currentBlock, parentRoot, params) +} + +// Writes a state diff from the current block, parent state root, and provided params +func (sds *Service) writeStateDiff(block *types.Block, parentRoot common.Hash, params Params) error { + var totalDifficulty *big.Int + var receipts types.Receipts + var err error + var tx interfaces.Batch + start, logger := countStateDiffBegin(block) + defer countStateDiffEnd(start, logger, err) + if params.IncludeTD { + totalDifficulty = sds.BlockChain.GetTd(block.Hash(), block.NumberU64()) + } + if params.IncludeReceipts { + receipts = sds.BlockChain.GetReceiptsByHash(block.Hash()) + } + tx, err = sds.indexer.PushBlock(block, receipts, totalDifficulty) + if err != nil { + return err + } + + output := func(node types2.StateNode) error { + defer func() { + // This is very noisy so we log at Trace. + since := metrics.UpdateDuration(time.Now(), metrics.IndexerMetrics.OutputTimer) + logger.Trace(fmt.Sprintf("statediff output duration=%dms", since.Milliseconds())) + }() + return sds.indexer.PushStateNode(tx, node, block.Hash().String()) + } + codeOutput := func(c types2.CodeAndCodeHash) error { + defer metrics.ReportAndUpdateDuration("statediff codeOutput", time.Now(), logger, metrics.IndexerMetrics.CodeOutputTimer) + return sds.indexer.PushCodeAndCodeHash(tx, c) + } + + err = sds.Builder.WriteStateDiffObject(Args{ + NewStateRoot: block.Root(), + OldStateRoot: parentRoot, + BlockHash: block.Hash(), + BlockNumber: block.Number(), + }, params, output, codeOutput) + // TODO this anti-pattern needs to be sorted out eventually + if err := tx.Submit(err); err != nil { + return fmt.Errorf("batch transaction submission failed: %s", err.Error()) + } + + // allow dereferencing of parent, keep current locked as it should be the next parent + sds.BlockChain.UnlockTrie(parentRoot) + return nil +} + +// Wrapper function on writeStateDiff to retry when the deadlock is detected. +func (sds *Service) writeStateDiffWithRetry(block *types.Block, parentRoot common.Hash, params Params) error { + var err error + for i := uint(0); i < sds.maxRetry; i++ { + err = sds.writeStateDiff(block, parentRoot, params) + if err != nil && strings.Contains(err.Error(), deadlockDetected) { + // Retry only when the deadlock is detected. + if i+1 < sds.maxRetry { + log.Warn("dead lock detected while writing statediff", "err", err, "retry number", i) + } + continue + } + break + } + return err +} + +// SubscribeWriteStatus is used by the API to subscribe to the job status updates +func (sds *Service) SubscribeWriteStatus(id rpc.ID, sub chan<- JobStatus, quitChan chan<- bool) { + log.Info("Subscribing to job status updates", "subscription id", id) + sds.Lock() + if sds.jobStatusSubs == nil { + sds.jobStatusSubs = map[rpc.ID]statusSubscription{} + } + sds.jobStatusSubs[id] = statusSubscription{ + statusChan: sub, + quitChan: quitChan, + } + sds.Unlock() +} + +// UnsubscribeWriteStatus is used to unsubscribe from job status updates +func (sds *Service) UnsubscribeWriteStatus(id rpc.ID) error { + log.Info("Unsubscribing from job status updates", "subscription id", id) + sds.Lock() + close(sds.jobStatusSubs[id].quitChan) + delete(sds.jobStatusSubs, id) + if len(sds.jobStatusSubs) == 0 { + sds.jobStatusSubs = nil + } + sds.Unlock() + return nil +} + +// WatchAddress performs one of following operations on the watched addresses in writeLoopParams and the db: +// add | remove | set | clear +func (sds *Service) WatchAddress(operation types2.OperationType, args []types2.WatchAddressArg) error { + // lock writeLoopParams for a write + writeLoopParams.Lock() + defer writeLoopParams.Unlock() + + // get the current block number + currentBlockNumber := sds.BlockChain.CurrentBlock().Number() + + switch operation { + case types2.Add: + // filter out args having an already watched address with a warning + filteredArgs, ok := funk.Filter(args, func(arg types2.WatchAddressArg) bool { + if funk.Contains(writeLoopParams.WatchedAddresses, common.HexToAddress(arg.Address)) { + log.Warn("Address already being watched", "address", arg.Address) + return false + } + return true + }).([]types2.WatchAddressArg) + if !ok { + return fmt.Errorf("add: filtered args %s", typeAssertionFailed) + } + + // get addresses from the filtered args + filteredAddresses, err := MapWatchAddressArgsToAddresses(filteredArgs) + if err != nil { + return fmt.Errorf("add: filtered addresses %s", err.Error()) + } + + // update the db + if sds.indexer != nil { + err = sds.indexer.InsertWatchedAddresses(filteredArgs, currentBlockNumber) + if err != nil { + return err + } + } + + // update in-memory params + writeLoopParams.WatchedAddresses = append(writeLoopParams.WatchedAddresses, filteredAddresses...) + writeLoopParams.ComputeWatchedAddressesLeafPaths() + case types2.Remove: + // get addresses from args + argAddresses, err := MapWatchAddressArgsToAddresses(args) + if err != nil { + return fmt.Errorf("remove: mapped addresses %s", err.Error()) + } + + // remove the provided addresses from currently watched addresses + addresses, ok := funk.Subtract(writeLoopParams.WatchedAddresses, argAddresses).([]common.Address) + if !ok { + return fmt.Errorf("remove: filtered addresses %s", typeAssertionFailed) + } + + // update the db + if sds.indexer != nil { + err = sds.indexer.RemoveWatchedAddresses(args) + if err != nil { + return err + } + } + + // update in-memory params + writeLoopParams.WatchedAddresses = addresses + writeLoopParams.ComputeWatchedAddressesLeafPaths() + case types2.Set: + // get addresses from args + argAddresses, err := MapWatchAddressArgsToAddresses(args) + if err != nil { + return fmt.Errorf("set: mapped addresses %s", err.Error()) + } + + // update the db + if sds.indexer != nil { + err = sds.indexer.SetWatchedAddresses(args, currentBlockNumber) + if err != nil { + return err + } + } + + // update in-memory params + writeLoopParams.WatchedAddresses = argAddresses + writeLoopParams.ComputeWatchedAddressesLeafPaths() + case types2.Clear: + // update the db + if sds.indexer != nil { + err := sds.indexer.ClearWatchedAddresses() + if err != nil { + return err + } + } + + // update in-memory params + writeLoopParams.WatchedAddresses = []common.Address{} + writeLoopParams.ComputeWatchedAddressesLeafPaths() + + default: + return fmt.Errorf("%s %s", unexpectedOperation, operation) + } + + return nil +} + +// loadWatchedAddresses loads watched addresses to in-memory write loop params +func loadWatchedAddresses(indexer interfaces.StateDiffIndexer) error { + watchedAddresses, err := indexer.LoadWatchedAddresses() + if err != nil { + return err + } + + writeLoopParams.Lock() + defer writeLoopParams.Unlock() + + writeLoopParams.WatchedAddresses = watchedAddresses + writeLoopParams.ComputeWatchedAddressesLeafPaths() + + return nil +} + +// MapWatchAddressArgsToAddresses maps []WatchAddressArg to corresponding []common.Address +func MapWatchAddressArgsToAddresses(args []types2.WatchAddressArg) ([]common.Address, error) { + addresses, ok := funk.Map(args, func(arg types2.WatchAddressArg) common.Address { + return common.HexToAddress(arg.Address) + }).([]common.Address) + if !ok { + return nil, fmt.Errorf(typeAssertionFailed) + } + + return addresses, nil +} diff --git a/statediff/service_test.go b/statediff/service_test.go new file mode 100644 index 000000000..1df068608 --- /dev/null +++ b/statediff/service_test.go @@ -0,0 +1,439 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package statediff_test + +import ( + "bytes" + "math/big" + "math/rand" + "reflect" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/internal/ethapi" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + statediff "github.com/ethereum/go-ethereum/statediff" + "github.com/ethereum/go-ethereum/statediff/test_helpers/mocks" + types2 "github.com/ethereum/go-ethereum/statediff/types" + "github.com/ethereum/go-ethereum/trie" +) + +func TestServiceLoop(t *testing.T) { + testErrorInChainEventLoop(t) + testErrorInBlockLoop(t) +} + +var ( + eventsChannel = make(chan core.ChainEvent, 1) + + parentRoot1 = common.HexToHash("0x01") + parentRoot2 = common.HexToHash("0x02") + parentHeader1 = types.Header{Number: big.NewInt(rand.Int63()), Root: parentRoot1} + parentHeader2 = types.Header{Number: big.NewInt(rand.Int63()), Root: parentRoot2} + + parentBlock1 = types.NewBlock(&parentHeader1, nil, nil, nil, new(trie.Trie)) + parentBlock2 = types.NewBlock(&parentHeader2, nil, nil, nil, new(trie.Trie)) + + parentHash1 = parentBlock1.Hash() + parentHash2 = parentBlock2.Hash() + + testRoot1 = common.HexToHash("0x03") + testRoot2 = common.HexToHash("0x04") + testRoot3 = common.HexToHash("0x04") + header1 = types.Header{ParentHash: parentHash1, Root: testRoot1, Number: big.NewInt(1)} + header2 = types.Header{ParentHash: parentHash2, Root: testRoot2, Number: big.NewInt(2)} + header3 = types.Header{ParentHash: common.HexToHash("parent hash"), Root: testRoot3, Number: big.NewInt(3)} + + testBlock1 = types.NewBlock(&header1, nil, nil, nil, new(trie.Trie)) + testBlock2 = types.NewBlock(&header2, nil, nil, nil, new(trie.Trie)) + testBlock3 = types.NewBlock(&header3, nil, nil, nil, new(trie.Trie)) + + receiptRoot1 = common.HexToHash("0x05") + receiptRoot2 = common.HexToHash("0x06") + receiptRoot3 = common.HexToHash("0x07") + testReceipts1 = []*types.Receipt{types.NewReceipt(receiptRoot1.Bytes(), false, 1000), types.NewReceipt(receiptRoot2.Bytes(), false, 2000)} + testReceipts2 = []*types.Receipt{types.NewReceipt(receiptRoot3.Bytes(), false, 3000)} + + event1 = core.ChainEvent{Block: testBlock1} + event2 = core.ChainEvent{Block: testBlock2} + event3 = core.ChainEvent{Block: testBlock3} + + defaultParams = statediff.Params{ + IncludeBlock: true, + IncludeReceipts: true, + IncludeTD: true, + WatchedAddresses: []common.Address{}, + } +) + +func testErrorInChainEventLoop(t *testing.T) { + //the first chain event causes and error (in blockchain mock) + builder := mocks.Builder{} + blockChain := mocks.BlockChain{} + serviceQuit := make(chan bool) + service := statediff.Service{ + Mutex: sync.Mutex{}, + Builder: &builder, + BlockChain: &blockChain, + QuitChan: serviceQuit, + Subscriptions: make(map[common.Hash]map[rpc.ID]statediff.Subscription), + SubscriptionTypes: make(map[common.Hash]statediff.Params), + BlockCache: statediff.NewBlockCache(1), + } + payloadChan := make(chan statediff.Payload, 2) + quitChan := make(chan bool) + service.Subscribe(rpc.NewID(), payloadChan, quitChan, defaultParams) + testRoot2 = common.HexToHash("0xTestRoot2") + blockMapping := make(map[common.Hash]*types.Block) + blockMapping[parentBlock1.Hash()] = parentBlock1 + blockMapping[parentBlock2.Hash()] = parentBlock2 + blockChain.SetBlocksForHashes(blockMapping) + blockChain.SetChainEvents([]core.ChainEvent{event1, event2, event3}) + blockChain.SetReceiptsForHash(testBlock1.Hash(), testReceipts1) + blockChain.SetReceiptsForHash(testBlock2.Hash(), testReceipts2) + + payloads := make([]statediff.Payload, 0, 2) + wg := new(sync.WaitGroup) + wg.Add(1) + go func() { + for i := 0; i < 2; i++ { + select { + case payload := <-payloadChan: + payloads = append(payloads, payload) + case <-quitChan: + } + } + wg.Done() + }() + service.Loop(eventsChannel) + wg.Wait() + if len(payloads) != 2 { + t.Error("Test failure:", t.Name()) + t.Logf("Actual number of payloads does not equal expected.\nactual: %+v\nexpected: 3", len(payloads)) + } + + testReceipts1Rlp, err := rlp.EncodeToBytes(&testReceipts1) + if err != nil { + t.Error(err) + } + testReceipts2Rlp, err := rlp.EncodeToBytes(&testReceipts2) + if err != nil { + t.Error(err) + } + expectedReceiptsRlp := [][]byte{testReceipts1Rlp, testReceipts2Rlp, nil} + for i, payload := range payloads { + if !bytes.Equal(payload.ReceiptsRlp, expectedReceiptsRlp[i]) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual receipt rlp for payload %d does not equal expected.\nactual: %+v\nexpected: %+v", i, payload.ReceiptsRlp, expectedReceiptsRlp[i]) + } + } + + defaultParams.ComputeWatchedAddressesLeafPaths() + if !reflect.DeepEqual(builder.Params, defaultParams) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual params does not equal expected.\nactual:%+v\nexpected: %+v", builder.Params, defaultParams) + } + if !bytes.Equal(builder.Args.BlockHash.Bytes(), testBlock2.Hash().Bytes()) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual blockhash does not equal expected.\nactual:%x\nexpected: %x", builder.Args.BlockHash.Bytes(), testBlock2.Hash().Bytes()) + } + if !bytes.Equal(builder.Args.OldStateRoot.Bytes(), parentBlock2.Root().Bytes()) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual root does not equal expected.\nactual:%x\nexpected: %x", builder.Args.OldStateRoot.Bytes(), parentBlock2.Root().Bytes()) + } + if !bytes.Equal(builder.Args.NewStateRoot.Bytes(), testBlock2.Root().Bytes()) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual root does not equal expected.\nactual:%x\nexpected: %x", builder.Args.NewStateRoot.Bytes(), testBlock2.Root().Bytes()) + } + //look up the parent block from its hash + expectedHashes := []common.Hash{testBlock1.ParentHash(), testBlock2.ParentHash()} + if !reflect.DeepEqual(blockChain.HashesLookedUp, expectedHashes) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual looked up parent hashes does not equal expected.\nactual:%+v\nexpected: %+v", blockChain.HashesLookedUp, expectedHashes) + } +} + +func testErrorInBlockLoop(t *testing.T) { + //second block's parent block can't be found + builder := mocks.Builder{} + blockChain := mocks.BlockChain{} + service := statediff.Service{ + Builder: &builder, + BlockChain: &blockChain, + QuitChan: make(chan bool), + Subscriptions: make(map[common.Hash]map[rpc.ID]statediff.Subscription), + SubscriptionTypes: make(map[common.Hash]statediff.Params), + BlockCache: statediff.NewBlockCache(1), + } + payloadChan := make(chan statediff.Payload) + quitChan := make(chan bool) + service.Subscribe(rpc.NewID(), payloadChan, quitChan, defaultParams) + blockMapping := make(map[common.Hash]*types.Block) + blockMapping[parentBlock1.Hash()] = parentBlock1 + blockChain.SetBlocksForHashes(blockMapping) + blockChain.SetChainEvents([]core.ChainEvent{event1, event2}) + // Need to have listeners on the channels or the subscription will be closed and the processing halted + go func() { + select { + case <-payloadChan: + case <-quitChan: + } + }() + service.Loop(eventsChannel) + + defaultParams.ComputeWatchedAddressesLeafPaths() + if !reflect.DeepEqual(builder.Params, defaultParams) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual params does not equal expected.\nactual:%+v\nexpected: %+v", builder.Params, defaultParams) + } + if !bytes.Equal(builder.Args.BlockHash.Bytes(), testBlock1.Hash().Bytes()) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual blockhash does not equal expected.\nactual:%+v\nexpected: %x", builder.Args.BlockHash.Bytes(), testBlock1.Hash().Bytes()) + } + if !bytes.Equal(builder.Args.OldStateRoot.Bytes(), parentBlock1.Root().Bytes()) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual old state root does not equal expected.\nactual:%+v\nexpected: %x", builder.Args.OldStateRoot.Bytes(), parentBlock1.Root().Bytes()) + } + if !bytes.Equal(builder.Args.NewStateRoot.Bytes(), testBlock1.Root().Bytes()) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual new state root does not equal expected.\nactual:%+v\nexpected: %x", builder.Args.NewStateRoot.Bytes(), testBlock1.Root().Bytes()) + } +} + +func TestGetStateDiffAt(t *testing.T) { + testErrorInStateDiffAt(t) +} + +func testErrorInStateDiffAt(t *testing.T) { + mockStateDiff := types2.StateObject{ + BlockNumber: testBlock1.Number(), + BlockHash: testBlock1.Hash(), + } + expectedStateDiffRlp, err := rlp.EncodeToBytes(&mockStateDiff) + if err != nil { + t.Error(err) + } + expectedReceiptsRlp, err := rlp.EncodeToBytes(&testReceipts1) + if err != nil { + t.Error(err) + } + expectedBlockRlp, err := rlp.EncodeToBytes(testBlock1) + if err != nil { + t.Error(err) + } + expectedStateDiffPayload := statediff.Payload{ + StateObjectRlp: expectedStateDiffRlp, + ReceiptsRlp: expectedReceiptsRlp, + BlockRlp: expectedBlockRlp, + } + expectedStateDiffPayloadRlp, err := rlp.EncodeToBytes(&expectedStateDiffPayload) + if err != nil { + t.Error(err) + } + builder := mocks.Builder{} + builder.SetStateDiffToBuild(mockStateDiff) + blockChain := mocks.BlockChain{} + blockMapping := make(map[common.Hash]*types.Block) + blockMapping[parentBlock1.Hash()] = parentBlock1 + blockChain.SetBlocksForHashes(blockMapping) + blockChain.SetBlockForNumber(testBlock1, testBlock1.NumberU64()) + blockChain.SetReceiptsForHash(testBlock1.Hash(), testReceipts1) + service := statediff.Service{ + Mutex: sync.Mutex{}, + Builder: &builder, + BlockChain: &blockChain, + QuitChan: make(chan bool), + Subscriptions: make(map[common.Hash]map[rpc.ID]statediff.Subscription), + SubscriptionTypes: make(map[common.Hash]statediff.Params), + BlockCache: statediff.NewBlockCache(1), + } + stateDiffPayload, err := service.StateDiffAt(testBlock1.NumberU64(), defaultParams) + if err != nil { + t.Error(err) + } + stateDiffPayloadRlp, err := rlp.EncodeToBytes(stateDiffPayload) + if err != nil { + t.Error(err) + } + + defaultParams.ComputeWatchedAddressesLeafPaths() + if !reflect.DeepEqual(builder.Params, defaultParams) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual params does not equal expected.\nactual:%+v\nexpected: %+v", builder.Params, defaultParams) + } + if !bytes.Equal(builder.Args.BlockHash.Bytes(), testBlock1.Hash().Bytes()) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual blockhash does not equal expected.\nactual:%+v\nexpected: %x", builder.Args.BlockHash.Bytes(), testBlock1.Hash().Bytes()) + } + if !bytes.Equal(builder.Args.OldStateRoot.Bytes(), parentBlock1.Root().Bytes()) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual old state root does not equal expected.\nactual:%+v\nexpected: %x", builder.Args.OldStateRoot.Bytes(), parentBlock1.Root().Bytes()) + } + if !bytes.Equal(builder.Args.NewStateRoot.Bytes(), testBlock1.Root().Bytes()) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual new state root does not equal expected.\nactual:%+v\nexpected: %x", builder.Args.NewStateRoot.Bytes(), testBlock1.Root().Bytes()) + } + if !bytes.Equal(expectedStateDiffPayloadRlp, stateDiffPayloadRlp) { + t.Error("Test failure:", t.Name()) + t.Logf("Actual state diff payload does not equal expected.\nactual:%+v\nexpected: %+v", expectedStateDiffPayload, stateDiffPayload) + } +} + +func TestWaitForSync(t *testing.T) { + testWaitForSync(t) + testGetSyncStatus(t) +} + +// This function will create a backend and service object which includes a generic Backend +func createServiceWithMockBackend(curBlock uint64, highestBlock uint64) (*mocks.Backend, *statediff.Service) { + builder := mocks.Builder{} + blockChain := mocks.BlockChain{} + backend := mocks.Backend{ + StartingBlock: 1, + CurrBlock: curBlock, + HighestBlock: highestBlock, + SyncedAccounts: 5, + SyncedAccountBytes: 5, + SyncedBytecodes: 5, + SyncedBytecodeBytes: 5, + SyncedStorage: 5, + SyncedStorageBytes: 5, + HealedTrienodes: 5, + HealedTrienodeBytes: 5, + HealedBytecodes: 5, + HealedBytecodeBytes: 5, + HealingTrienodes: 5, + HealingBytecode: 5, + } + + service := &statediff.Service{ + Mutex: sync.Mutex{}, + Builder: &builder, + BlockChain: &blockChain, + QuitChan: make(chan bool), + Subscriptions: make(map[common.Hash]map[rpc.ID]statediff.Subscription), + SubscriptionTypes: make(map[common.Hash]statediff.Params), + BlockCache: statediff.NewBlockCache(1), + BackendAPI: &backend, + WaitForSync: true, + } + return &backend, service +} + +// This function will test to make sure that the state diff waits +// until the blockchain has caught up to head! +func testWaitForSync(t *testing.T) { + t.Log("Starting Sync") + _, service := createServiceWithMockBackend(10, 10) + err := service.WaitingForSync() + if err != nil { + t.Fatal("Sync Failed") + } + t.Log("Sync Complete") +} + +// This test will run the WaitForSync() at the start of the execusion +// It will then incrementally increase the currentBlock to match the highestBlock +// At each interval it will run the GetSyncStatus to ensure that the return value is not false. +// It will also check to make sure that the WaitForSync() function has not completed! +func testGetSyncStatus(t *testing.T) { + t.Log("Starting Get Sync Status Test") + var highestBlock uint64 = 5 + // Create a backend and a service + // the backend is lagging behind the sync. + backend, service := createServiceWithMockBackend(0, highestBlock) + + checkSyncComplete := make(chan int, 1) + + go func() { + // Start the sync function which will wait for the sync + // Once the sync is complete add a value to the checkSyncComplet channel + t.Log("Starting Sync") + err := service.WaitingForSync() + if err != nil { + t.Error("Sync Failed") + checkSyncComplete <- 1 + } + t.Log("We have finally synced!") + checkSyncComplete <- 0 + }() + + tables := []struct { + currentBlock uint64 + highestBlock uint64 + }{ + {1, highestBlock}, + {2, highestBlock}, + {3, highestBlock}, + {4, highestBlock}, + {5, highestBlock}, + } + + time.Sleep(2 * time.Second) + for _, table := range tables { + // Iterate over each block + // Once the highest block reaches the current block the sync should complete + + // Update the backend current block value + t.Log("Updating Current Block to: ", table.currentBlock) + backend.CurrBlock = table.currentBlock + pubEthAPI := ethapi.NewEthereumAPI(service.BackendAPI) + syncStatus, err := service.GetSyncStatus(pubEthAPI) + + if err != nil { + t.Fatal("Sync Failed") + } + + time.Sleep(2 * time.Second) + + // Make sure if syncStatus is false that WaitForSync has completed! + if !syncStatus && len(checkSyncComplete) == 0 { + t.Error("Sync is complete but WaitForSync is not") + } + + if syncStatus && len(checkSyncComplete) == 1 { + t.Error("Sync is not complete but WaitForSync is") + } + + // Make sure sync hasn't completed and that the checkSyncComplete channel is empty + if syncStatus && len(checkSyncComplete) == 0 { + continue + } + + // This code will only be run if the sync is complete and the WaitForSync function is complete + + // If syncstatus is complete, make sure that the blocks match + if !syncStatus && table.currentBlock != table.highestBlock { + t.Errorf("syncStatus indicated sync was complete even when current block, %d, and highest block %d aren't equal", + table.currentBlock, table.highestBlock) + } + + // Make sure that WaitForSync completed once the current block caught up to head! + checkSyncCompleteVal := <-checkSyncComplete + if checkSyncCompleteVal != 0 { + t.Errorf("syncStatus indicated sync was complete but the checkSyncComplete has a value of %d", + checkSyncCompleteVal) + } else { + t.Log("Test Passed!") + } + } +} diff --git a/statediff/test_helpers/constant.go b/statediff/test_helpers/constant.go new file mode 100644 index 000000000..ba591ebb4 --- /dev/null +++ b/statediff/test_helpers/constant.go @@ -0,0 +1,33 @@ +// VulcanizeDB +// Copyright © 2021 Vulcanize + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. + +// This program 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 Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +package test_helpers + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/params" +) + +var ( + BalanceChange1000 = int64(1000) + BalanceChange10000 = int64(10000) + BalanceChange1Ether = int64(params.Ether) + Block1Account1Balance = big.NewInt(BalanceChange10000) + Block2Account2Balance = big.NewInt(21000000000000) + GasFees = int64(params.GWei) * int64(params.TxGas) + ContractGasLimit = uint64(1000000) +) diff --git a/statediff/test_helpers/helpers.go b/statediff/test_helpers/helpers.go new file mode 100644 index 000000000..e791b0bfd --- /dev/null +++ b/statediff/test_helpers/helpers.go @@ -0,0 +1,142 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package test_helpers + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/params" +) + +func GenesisBlockForTesting(db ethdb.Database, addr common.Address, balance *big.Int) *types.Block { + g := core.Genesis{ + Alloc: core.GenesisAlloc{addr: {Balance: balance}}, + BaseFee: big.NewInt(params.InitialBaseFee), + } + return g.MustCommit(db) +} + +// MakeChain creates a chain of n blocks starting at and including parent. +// the returned hash chain is ordered head->parent. +func MakeChain(n int, parent *types.Block, chainGen func(int, *core.BlockGen)) ([]*types.Block, *core.BlockChain) { + config := params.TestChainConfig + blocks, _ := core.GenerateChain(config, parent, ethash.NewFaker(), Testdb, n, chainGen) + + //genesis := core.Genesis{ + // Config: params.AllEthashProtocolChanges, + //} + blockchain, _ := core.NewBlockChain(Testdb, nil, nil, nil, ethash.NewFaker(), vm.Config{}, nil, nil) + + return blocks, blockchain +} + +func TestSelfDestructChainGen(i int, block *core.BlockGen) { + signer := types.HomesteadSigner{} + switch i { + case 0: + // Block 1 is mined by Account1Addr + // Account1Addr creates a new contract + block.SetCoinbase(TestBankAddress) + tx, _ := types.SignTx(types.NewContractCreation(0, big.NewInt(0), 1000000, big.NewInt(params.GWei), ContractCode), signer, TestBankKey) + ContractAddr = crypto.CreateAddress(TestBankAddress, 0) + block.AddTx(tx) + case 1: + // Block 2 is mined by Account1Addr + // Account1Addr self-destructs the contract + block.SetCoinbase(TestBankAddress) + data := common.Hex2Bytes("43D726D6") + tx, _ := types.SignTx(types.NewTransaction(1, ContractAddr, big.NewInt(0), 100000, big.NewInt(params.GWei), data), signer, TestBankKey) + block.AddTx(tx) + } +} + +func TestChainGen(i int, block *core.BlockGen) { + signer := types.HomesteadSigner{} + switch i { + case 0: + // In block 1, the test bank sends account #1 some ether. + tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, big.NewInt(BalanceChange10000), params.TxGas, big.NewInt(params.GWei), nil), signer, TestBankKey) + block.AddTx(tx) + case 1: + // In block 2, the test bank sends some more ether to account #1. + // Account1Addr passes it on to account #2. + // Account1Addr creates a test contract. + tx1, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), Account1Addr, big.NewInt(BalanceChange1Ether), params.TxGas, big.NewInt(params.GWei), nil), signer, TestBankKey) + nonce := block.TxNonce(Account1Addr) + tx2, _ := types.SignTx(types.NewTransaction(nonce, Account2Addr, big.NewInt(BalanceChange1000), params.TxGas, big.NewInt(params.GWei), nil), signer, Account1Key) + nonce++ + tx3, _ := types.SignTx(types.NewContractCreation(nonce, big.NewInt(0), ContractGasLimit, big.NewInt(params.GWei), ContractCode), signer, Account1Key) + ContractAddr = crypto.CreateAddress(Account1Addr, nonce) + block.AddTx(tx1) + block.AddTx(tx2) + block.AddTx(tx3) + case 2: + // Block 3 has a single tx from the bankAccount to the contract, that transfers no value + // Block 3 is mined by Account2Addr + block.SetCoinbase(Account2Addr) + //put function: c16431b9 + //close function: 43d726d6 + data := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") + tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(TestBankAddress), ContractAddr, big.NewInt(0), params.TxGasContractCreation, big.NewInt(params.GWei), data), signer, TestBankKey) + block.AddTx(tx) + case 3: + // Block 4 has three txs from bankAccount to the contract, that transfer no value + // Two set the two original slot positions to 0 and one sets another position to a new value + // Block 4 is mined by Account2Addr + block.SetCoinbase(Account2Addr) + data1 := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") + data2 := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000") + data3 := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000009") + + nonce := block.TxNonce(TestBankAddress) + tx1, _ := types.SignTx(types.NewTransaction(nonce, ContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data1), signer, TestBankKey) + nonce++ + tx2, _ := types.SignTx(types.NewTransaction(nonce, ContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data2), signer, TestBankKey) + nonce++ + tx3, _ := types.SignTx(types.NewTransaction(nonce, ContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data3), signer, TestBankKey) + block.AddTx(tx1) + block.AddTx(tx2) + block.AddTx(tx3) + case 4: + // Block 5 has one tx from bankAccount to the contract, that transfers no value + // It sets the one storage value to zero and the other to new value. + // Block 5 is mined by Account1Addr + block.SetCoinbase(Account1Addr) + data1 := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000") + data2 := common.Hex2Bytes("C16431B900000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003") + nonce := block.TxNonce(TestBankAddress) + tx1, _ := types.SignTx(types.NewTransaction(nonce, ContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data1), signer, TestBankKey) + nonce++ + tx2, _ := types.SignTx(types.NewTransaction(nonce, ContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data2), signer, TestBankKey) + block.AddTx(tx1) + block.AddTx(tx2) + case 5: + // Block 6 has a tx from Account1Key which self-destructs the contract, it transfers no value + // Block 6 is mined by Account2Addr + block.SetCoinbase(Account2Addr) + data := common.Hex2Bytes("43D726D6") + tx, _ := types.SignTx(types.NewTransaction(block.TxNonce(Account1Addr), ContractAddr, big.NewInt(0), 100000, big.NewInt(params.InitialBaseFee), data), signer, Account1Key) + block.AddTx(tx) + } +} diff --git a/statediff/test_helpers/mocks/backend.go b/statediff/test_helpers/mocks/backend.go new file mode 100644 index 000000000..bdda01381 --- /dev/null +++ b/statediff/test_helpers/mocks/backend.go @@ -0,0 +1,260 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mocks + +import ( + "context" + "math/big" + "time" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/bloombits" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rpc" +) + +// Builder is a mock state diff builder +type Backend struct { + StartingBlock uint64 + CurrBlock uint64 + HighestBlock uint64 + SyncedAccounts uint64 + SyncedAccountBytes uint64 + SyncedBytecodes uint64 + SyncedBytecodeBytes uint64 + SyncedStorage uint64 + SyncedStorageBytes uint64 + HealedTrienodes uint64 + HealedTrienodeBytes uint64 + HealedBytecodes uint64 + HealedBytecodeBytes uint64 + HealingTrienodes uint64 + HealingBytecode uint64 +} + +// General Ethereum API +func (backend *Backend) SyncProgress() ethereum.SyncProgress { + l := ethereum.SyncProgress{ + StartingBlock: backend.StartingBlock, + CurrentBlock: backend.CurrBlock, + HighestBlock: backend.HighestBlock, + SyncedAccounts: backend.SyncedAccounts, + SyncedAccountBytes: backend.SyncedAccountBytes, + SyncedBytecodes: backend.SyncedBytecodes, + SyncedBytecodeBytes: backend.SyncedBytecodeBytes, + SyncedStorage: backend.SyncedStorage, + SyncedStorageBytes: backend.SyncedStorageBytes, + HealedTrienodes: backend.HealedTrienodes, + HealedTrienodeBytes: backend.HealedTrienodeBytes, + HealedBytecodes: backend.HealedBytecodes, + HealedBytecodeBytes: backend.HealedBytecodeBytes, + HealingTrienodes: backend.HealingTrienodes, + HealingBytecode: backend.HealingBytecode, + } + return l +} + +func (backend *Backend) SuggestGasTipCap(ctx context.Context) (*big.Int, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) FeeHistory(ctx context.Context, blockCount int, lastBlock rpc.BlockNumber, rewardPercentiles []float64) (*big.Int, [][]*big.Int, []*big.Int, []float64, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) ChainDb() ethdb.Database { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) AccountManager() *accounts.Manager { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) ExtRPCEnabled() bool { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) RPCGasCap() uint64 { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) RPCEVMTimeout() time.Duration { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) RPCTxFeeCap() float64 { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) UnprotectedAllowed() bool { + panic("not implemented") // TODO: Implement +} + +// Blockchain API +func (backend *Backend) SetHead(number uint64) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) HeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Header, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) CurrentHeader() *types.Header { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) CurrentBlock() *types.Block { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) BlockByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*types.Block, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) StateAndHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*state.StateDB, *types.Header, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) (*state.StateDB, *types.Header, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) GetBody(ctx context.Context, hash common.Hash, number rpc.BlockNumber) (*types.Body, error) { + panic("implement me") +} +func (backend *Backend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) GetTd(ctx context.Context, hash common.Hash) *big.Int { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) GetEVM(ctx context.Context, msg core.Message, state *state.StateDB, header *types.Header, vmConfig *vm.Config) (*vm.EVM, func() error, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) SubscribeChainSideEvent(ch chan<- core.ChainSideEvent) event.Subscription { + panic("not implemented") // TODO: Implement +} + +// Transaction pool API +func (backend *Backend) SendTx(ctx context.Context, signedTx *types.Transaction) error { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) GetTransaction(ctx context.Context, txHash common.Hash) (*types.Transaction, common.Hash, uint64, uint64, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) GetPoolTransactions() (types.Transactions, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) GetPoolTransaction(txHash common.Hash) *types.Transaction { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) GetPoolNonce(ctx context.Context, addr common.Address) (uint64, error) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) Stats() (pending int, queued int) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) TxPoolContent() (map[common.Address]types.Transactions, map[common.Address]types.Transactions) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) TxPoolContentFrom(addr common.Address) (types.Transactions, types.Transactions) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) SubscribeNewTxsEvent(_ chan<- core.NewTxsEvent) event.Subscription { + panic("not implemented") // TODO: Implement +} + +// Filter API +func (backend *Backend) BloomStatus() (uint64, uint64) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) GetLogs(ctx context.Context, blockHash common.Hash, number uint64) ([][]*types.Log, error) { + panic("not implemented") +} + +func (backend *Backend) ServiceFilter(ctx context.Context, session *bloombits.MatcherSession) { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) SubscribePendingLogsEvent(ch chan<- []*types.Log) event.Subscription { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) SubscribeRemovedLogsEvent(ch chan<- core.RemovedLogsEvent) event.Subscription { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) ChainConfig() *params.ChainConfig { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) Engine() consensus.Engine { + panic("not implemented") // TODO: Implement +} + +func (backend *Backend) PendingBlockAndReceipts() (*types.Block, types.Receipts) { + return nil, nil +} diff --git a/statediff/test_helpers/mocks/blockchain.go b/statediff/test_helpers/mocks/blockchain.go new file mode 100644 index 000000000..0c6ff9424 --- /dev/null +++ b/statediff/test_helpers/mocks/blockchain.go @@ -0,0 +1,157 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mocks + +import ( + "errors" + "math/big" + "time" + + "github.com/ethereum/go-ethereum/core/state" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/event" +) + +// BlockChain is a mock blockchain for testing +type BlockChain struct { + HashesLookedUp []common.Hash + blocksToReturnByHash map[common.Hash]*types.Block + blocksToReturnByNumber map[uint64]*types.Block + ChainEvents []core.ChainEvent + Receipts map[common.Hash]types.Receipts + TDByHash map[common.Hash]*big.Int + TDByNum map[uint64]*big.Int + currentBlock *types.Block +} + +// SetBlocksForHashes mock method +func (bc *BlockChain) SetBlocksForHashes(blocks map[common.Hash]*types.Block) { + if bc.blocksToReturnByHash == nil { + bc.blocksToReturnByHash = make(map[common.Hash]*types.Block) + } + bc.blocksToReturnByHash = blocks +} + +// GetBlockByHash mock method +func (bc *BlockChain) GetBlockByHash(hash common.Hash) *types.Block { + bc.HashesLookedUp = append(bc.HashesLookedUp, hash) + + var block *types.Block + if len(bc.blocksToReturnByHash) > 0 { + block = bc.blocksToReturnByHash[hash] + } + + return block +} + +// SetChainEvents mock method +func (bc *BlockChain) SetChainEvents(chainEvents []core.ChainEvent) { + bc.ChainEvents = chainEvents +} + +// SubscribeChainEvent mock method +func (bc *BlockChain) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { + subErr := errors.New("subscription error") + + var eventCounter int + subscription := event.NewSubscription(func(quit <-chan struct{}) error { + for _, chainEvent := range bc.ChainEvents { + if eventCounter > 1 { + time.Sleep(250 * time.Millisecond) + return subErr + } + select { + case ch <- chainEvent: + case <-quit: + return nil + } + eventCounter++ + } + return nil + }) + + return subscription +} + +// SetReceiptsForHash test method +func (bc *BlockChain) SetReceiptsForHash(hash common.Hash, receipts types.Receipts) { + if bc.Receipts == nil { + bc.Receipts = make(map[common.Hash]types.Receipts) + } + bc.Receipts[hash] = receipts +} + +// GetReceiptsByHash mock method +func (bc *BlockChain) GetReceiptsByHash(hash common.Hash) types.Receipts { + return bc.Receipts[hash] +} + +// SetBlockForNumber test method +func (bc *BlockChain) SetBlockForNumber(block *types.Block, number uint64) { + if bc.blocksToReturnByNumber == nil { + bc.blocksToReturnByNumber = make(map[uint64]*types.Block) + } + bc.blocksToReturnByNumber[number] = block +} + +// GetBlockByNumber mock method +func (bc *BlockChain) GetBlockByNumber(number uint64) *types.Block { + return bc.blocksToReturnByNumber[number] +} + +// GetTd mock method +func (bc *BlockChain) GetTd(hash common.Hash, blockNum uint64) *big.Int { + if td, ok := bc.TDByHash[hash]; ok { + return td + } + + if td, ok := bc.TDByNum[blockNum]; ok { + return td + } + return nil +} + +// SetCurrentBlock test method +func (bc *BlockChain) SetCurrentBlock(block *types.Block) { + bc.currentBlock = block +} + +// CurrentBlock mock method +func (bc *BlockChain) CurrentBlock() *types.Block { + return bc.currentBlock +} + +func (bc *BlockChain) SetTd(hash common.Hash, blockNum uint64, td *big.Int) { + if bc.TDByHash == nil { + bc.TDByHash = make(map[common.Hash]*big.Int) + } + bc.TDByHash[hash] = td + + if bc.TDByNum == nil { + bc.TDByNum = make(map[uint64]*big.Int) + } + bc.TDByNum[blockNum] = td +} + +func (bc *BlockChain) UnlockTrie(root common.Hash) {} + +func (bc *BlockChain) StateCache() state.Database { + return nil +} diff --git a/statediff/test_helpers/mocks/builder.go b/statediff/test_helpers/mocks/builder.go new file mode 100644 index 000000000..ba0b154cf --- /dev/null +++ b/statediff/test_helpers/mocks/builder.go @@ -0,0 +1,67 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mocks + +import ( + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/statediff" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +// Builder is a mock state diff builder +type Builder struct { + Args statediff.Args + Params statediff.Params + StateRoots sdtypes.StateRoots + stateDiff sdtypes.StateObject + block *types.Block + stateTrie sdtypes.StateObject + builderError error +} + +// BuildStateDiffObject mock method +func (builder *Builder) BuildStateDiffObject(args statediff.Args, params statediff.Params) (sdtypes.StateObject, error) { + builder.Args = args + builder.Params = params + + return builder.stateDiff, builder.builderError +} + +// BuildStateDiffObject mock method +func (builder *Builder) WriteStateDiffObject(args statediff.Args, params statediff.Params, output sdtypes.StateNodeSink, codeOutput sdtypes.CodeSink) error { + builder.StateRoots = sdtypes.StateRoots{OldStateRoot: args.OldStateRoot, NewStateRoot: args.NewStateRoot} + builder.Params = params + + return builder.builderError +} + +// BuildStateTrieObject mock method +func (builder *Builder) BuildStateTrieObject(block *types.Block) (sdtypes.StateObject, error) { + builder.block = block + + return builder.stateTrie, builder.builderError +} + +// SetStateDiffToBuild mock method +func (builder *Builder) SetStateDiffToBuild(stateDiff sdtypes.StateObject) { + builder.stateDiff = stateDiff +} + +// SetBuilderError mock method +func (builder *Builder) SetBuilderError(err error) { + builder.builderError = err +} diff --git a/statediff/test_helpers/mocks/indexer.go b/statediff/test_helpers/mocks/indexer.go new file mode 100644 index 000000000..92005a8b4 --- /dev/null +++ b/statediff/test_helpers/mocks/indexer.go @@ -0,0 +1,70 @@ +// Copyright 2022 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mocks + +import ( + "math/big" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +var _ interfaces.StateDiffIndexer = &StateDiffIndexer{} + +// StateDiffIndexer is a mock state diff indexer +type StateDiffIndexer struct{} + +func (sdi *StateDiffIndexer) PushBlock(block *types.Block, receipts types.Receipts, totalDifficulty *big.Int) (interfaces.Batch, error) { + return nil, nil +} + +func (sdi *StateDiffIndexer) PushStateNode(tx interfaces.Batch, stateNode sdtypes.StateNode, headerID string) error { + return nil +} + +func (sdi *StateDiffIndexer) PushCodeAndCodeHash(tx interfaces.Batch, codeAndCodeHash sdtypes.CodeAndCodeHash) error { + return nil +} + +func (sdi *StateDiffIndexer) ReportDBMetrics(delay time.Duration, quit <-chan bool) {} + +func (sdi *StateDiffIndexer) LoadWatchedAddresses() ([]common.Address, error) { + return nil, nil +} + +func (sdi *StateDiffIndexer) InsertWatchedAddresses(addresses []sdtypes.WatchAddressArg, currentBlock *big.Int) error { + return nil +} + +func (sdi *StateDiffIndexer) RemoveWatchedAddresses(addresses []sdtypes.WatchAddressArg) error { + return nil +} + +func (sdi *StateDiffIndexer) SetWatchedAddresses(args []sdtypes.WatchAddressArg, currentBlockNumber *big.Int) error { + return nil +} + +func (sdi *StateDiffIndexer) ClearWatchedAddresses() error { + return nil +} + +func (sdi *StateDiffIndexer) Close() error { + return nil +} diff --git a/statediff/test_helpers/mocks/service.go b/statediff/test_helpers/mocks/service.go new file mode 100644 index 000000000..1ecd80ec8 --- /dev/null +++ b/statediff/test_helpers/mocks/service.go @@ -0,0 +1,449 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mocks + +import ( + "bytes" + "errors" + "fmt" + "sync" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" + "github.com/thoas/go-funk" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/statediff" + "github.com/ethereum/go-ethereum/statediff/indexer/interfaces" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +var ( + typeAssertionFailed = "type assertion failed" + unexpectedOperation = "unexpected operation" +) + +// MockStateDiffService is a mock state diff service +type MockStateDiffService struct { + sync.Mutex + Builder statediff.Builder + BlockChain *BlockChain + ReturnProtocol []p2p.Protocol + ReturnAPIs []rpc.API + BlockChan chan *types.Block + ParentBlockChan chan *types.Block + QuitChan chan bool + Subscriptions map[common.Hash]map[rpc.ID]statediff.Subscription + SubscriptionTypes map[common.Hash]statediff.Params + Indexer interfaces.StateDiffIndexer + writeLoopParams statediff.ParamsWithMutex +} + +// Protocols mock method +func (sds *MockStateDiffService) Protocols() []p2p.Protocol { + return []p2p.Protocol{} +} + +// APIs mock method +func (sds *MockStateDiffService) APIs() []rpc.API { + return []rpc.API{ + { + Namespace: statediff.APIName, + Version: statediff.APIVersion, + Service: statediff.NewPublicStateDiffAPI(sds), + Public: true, + }, + } +} + +// Loop mock method +func (sds *MockStateDiffService) Loop(chan core.ChainEvent) { + //loop through chain events until no more + for { + select { + case block := <-sds.BlockChan: + currentBlock := block + parentBlock := <-sds.ParentBlockChan + parentHash := parentBlock.Hash() + if parentBlock == nil { + log.Error("Parent block is nil, skipping this block", + "parent block hash", parentHash.String(), + "current block number", currentBlock.Number()) + continue + } + sds.streamStateDiff(currentBlock, parentBlock.Root()) + case <-sds.QuitChan: + log.Debug("Quitting the statediff block channel") + sds.close() + return + } + } +} + +// streamStateDiff method builds the state diff payload for each subscription according to their subscription type and sends them the result +func (sds *MockStateDiffService) streamStateDiff(currentBlock *types.Block, parentRoot common.Hash) { + sds.Lock() + for ty, subs := range sds.Subscriptions { + params, ok := sds.SubscriptionTypes[ty] + if !ok { + log.Error(fmt.Sprintf("subscriptions type %s do not have a parameter set associated with them", ty.Hex())) + sds.closeType(ty) + continue + } + // create payload for this subscription type + payload, err := sds.processStateDiff(currentBlock, parentRoot, params) + if err != nil { + log.Error(fmt.Sprintf("statediff processing error for subscriptions with parameters: %+v", params)) + sds.closeType(ty) + continue + } + for id, sub := range subs { + select { + case sub.PayloadChan <- *payload: + log.Debug(fmt.Sprintf("sending statediff payload to subscription %s", id)) + default: + log.Info(fmt.Sprintf("unable to send statediff payload to subscription %s; channel has no receiver", id)) + } + } + } + sds.Unlock() +} + +// StateDiffAt mock method +func (sds *MockStateDiffService) StateDiffAt(blockNumber uint64, params statediff.Params) (*statediff.Payload, error) { + currentBlock := sds.BlockChain.GetBlockByNumber(blockNumber) + log.Info(fmt.Sprintf("sending state diff at %d", blockNumber)) + if blockNumber == 0 { + return sds.processStateDiff(currentBlock, common.Hash{}, params) + } + parentBlock := sds.BlockChain.GetBlockByHash(currentBlock.ParentHash()) + return sds.processStateDiff(currentBlock, parentBlock.Root(), params) +} + +// StateDiffFor mock method +func (sds *MockStateDiffService) StateDiffFor(blockHash common.Hash, params statediff.Params) (*statediff.Payload, error) { + // TODO: something useful here + return nil, nil +} + +// processStateDiff method builds the state diff payload from the current block, parent state root, and provided params +func (sds *MockStateDiffService) processStateDiff(currentBlock *types.Block, parentRoot common.Hash, params statediff.Params) (*statediff.Payload, error) { + stateDiff, err := sds.Builder.BuildStateDiffObject(statediff.Args{ + NewStateRoot: currentBlock.Root(), + OldStateRoot: parentRoot, + BlockHash: currentBlock.Hash(), + BlockNumber: currentBlock.Number(), + }, params) + if err != nil { + return nil, err + } + stateDiffRlp, err := rlp.EncodeToBytes(&stateDiff) + if err != nil { + return nil, err + } + return sds.newPayload(stateDiffRlp, currentBlock, params) +} + +func (sds *MockStateDiffService) newPayload(stateObject []byte, block *types.Block, params statediff.Params) (*statediff.Payload, error) { + payload := &statediff.Payload{ + StateObjectRlp: stateObject, + } + if params.IncludeBlock { + blockBuff := new(bytes.Buffer) + if err := block.EncodeRLP(blockBuff); err != nil { + return nil, err + } + payload.BlockRlp = blockBuff.Bytes() + } + if params.IncludeTD { + payload.TotalDifficulty = sds.BlockChain.GetTd(block.Hash(), block.NumberU64()) + } + if params.IncludeReceipts { + receiptBuff := new(bytes.Buffer) + receipts := sds.BlockChain.GetReceiptsByHash(block.Hash()) + if err := rlp.Encode(receiptBuff, receipts); err != nil { + return nil, err + } + payload.ReceiptsRlp = receiptBuff.Bytes() + } + return payload, nil +} + +// WriteStateDiffAt mock method +func (sds *MockStateDiffService) WriteStateDiffAt(blockNumber uint64, params statediff.Params) statediff.JobID { + // TODO: something useful here + return 0 +} + +// WriteStateDiffFor mock method +func (sds *MockStateDiffService) WriteStateDiffFor(blockHash common.Hash, params statediff.Params) error { + // TODO: something useful here + return nil +} + +// Loop mock method +func (sds *MockStateDiffService) WriteLoop(chan core.ChainEvent) { + //loop through chain events until no more + for { + select { + case block := <-sds.BlockChan: + currentBlock := block + parentBlock := <-sds.ParentBlockChan + parentHash := parentBlock.Hash() + if parentBlock == nil { + log.Error("Parent block is nil, skipping this block", + "parent block hash", parentHash.String(), + "current block number", currentBlock.Number()) + continue + } + // TODO: + // sds.writeStateDiff(currentBlock, parentBlock.Root(), statediff.Params{}) + case <-sds.QuitChan: + log.Debug("Quitting the statediff block channel") + sds.close() + return + } + } +} + +// StateTrieAt mock method +func (sds *MockStateDiffService) StateTrieAt(blockNumber uint64, params statediff.Params) (*statediff.Payload, error) { + currentBlock := sds.BlockChain.GetBlockByNumber(blockNumber) + log.Info(fmt.Sprintf("sending state trie at %d", blockNumber)) + return sds.stateTrieAt(currentBlock, params) +} + +func (sds *MockStateDiffService) stateTrieAt(block *types.Block, params statediff.Params) (*statediff.Payload, error) { + stateNodes, err := sds.Builder.BuildStateTrieObject(block) + if err != nil { + return nil, err + } + stateTrieRlp, err := rlp.EncodeToBytes(&stateNodes) + if err != nil { + return nil, err + } + return sds.newPayload(stateTrieRlp, block, params) +} + +// Subscribe is used by the API to subscribe to the service loop +func (sds *MockStateDiffService) Subscribe(id rpc.ID, sub chan<- statediff.Payload, quitChan chan<- bool, params statediff.Params) { + // Subscription type is defined as the hash of the rlp-serialized subscription params + by, err := rlp.EncodeToBytes(¶ms) + if err != nil { + return + } + subscriptionType := crypto.Keccak256Hash(by) + // Add subscriber + sds.Lock() + if sds.Subscriptions[subscriptionType] == nil { + sds.Subscriptions[subscriptionType] = make(map[rpc.ID]statediff.Subscription) + } + sds.Subscriptions[subscriptionType][id] = statediff.Subscription{ + PayloadChan: sub, + QuitChan: quitChan, + } + sds.SubscriptionTypes[subscriptionType] = params + sds.Unlock() +} + +// Unsubscribe is used to unsubscribe from the service loop +func (sds *MockStateDiffService) Unsubscribe(id rpc.ID) error { + sds.Lock() + for ty := range sds.Subscriptions { + delete(sds.Subscriptions[ty], id) + if len(sds.Subscriptions[ty]) == 0 { + // If we removed the last subscription of this type, remove the subscription type outright + delete(sds.Subscriptions, ty) + delete(sds.SubscriptionTypes, ty) + } + } + sds.Unlock() + return nil +} + +// close is used to close all listening subscriptions +func (sds *MockStateDiffService) close() { + sds.Lock() + for ty, subs := range sds.Subscriptions { + for id, sub := range subs { + select { + case sub.QuitChan <- true: + log.Info(fmt.Sprintf("closing subscription %s", id)) + default: + log.Info(fmt.Sprintf("unable to close subscription %s; channel has no receiver", id)) + } + delete(sds.Subscriptions[ty], id) + } + delete(sds.Subscriptions, ty) + delete(sds.SubscriptionTypes, ty) + } + sds.Unlock() +} + +// Start mock method +func (sds *MockStateDiffService) Start() error { + log.Info("Starting mock statediff service") + if sds.ParentBlockChan == nil || sds.BlockChan == nil { + return errors.New("MockStateDiffingService needs to be configured with a MockParentBlockChan and MockBlockChan") + } + chainEventCh := make(chan core.ChainEvent, 10) + go sds.Loop(chainEventCh) + + return nil +} + +// Stop mock method +func (sds *MockStateDiffService) Stop() error { + log.Info("Stopping mock statediff service") + close(sds.QuitChan) + return nil +} + +// closeType is used to close all subscriptions of given type +// closeType needs to be called with subscription access locked +func (sds *MockStateDiffService) closeType(subType common.Hash) { + subs := sds.Subscriptions[subType] + for id, sub := range subs { + sendNonBlockingQuit(id, sub) + } + delete(sds.Subscriptions, subType) + delete(sds.SubscriptionTypes, subType) +} + +func (sds *MockStateDiffService) StreamCodeAndCodeHash(blockNumber uint64, outChan chan<- sdtypes.CodeAndCodeHash, quitChan chan<- bool) { + panic("implement me") +} + +func sendNonBlockingQuit(id rpc.ID, sub statediff.Subscription) { + select { + case sub.QuitChan <- true: + log.Info(fmt.Sprintf("closing subscription %s", id)) + default: + log.Info("unable to close subscription %s; channel has no receiver", id) + } +} + +// Performs one of following operations on the watched addresses in writeLoopParams and the db: +// add | remove | set | clear +func (sds *MockStateDiffService) WatchAddress(operation sdtypes.OperationType, args []sdtypes.WatchAddressArg) error { + // lock writeLoopParams for a write + sds.writeLoopParams.Lock() + defer sds.writeLoopParams.Unlock() + + // get the current block number + currentBlockNumber := sds.BlockChain.CurrentBlock().Number() + + switch operation { + case sdtypes.Add: + // filter out args having an already watched address with a warning + filteredArgs, ok := funk.Filter(args, func(arg sdtypes.WatchAddressArg) bool { + if funk.Contains(sds.writeLoopParams.WatchedAddresses, common.HexToAddress(arg.Address)) { + log.Warn("Address already being watched", "address", arg.Address) + return false + } + return true + }).([]sdtypes.WatchAddressArg) + if !ok { + return fmt.Errorf("add: filtered args %s", typeAssertionFailed) + } + + // get addresses from the filtered args + filteredAddresses, err := statediff.MapWatchAddressArgsToAddresses(filteredArgs) + if err != nil { + return fmt.Errorf("add: filtered addresses %s", err.Error()) + } + + // update the db + err = sds.Indexer.InsertWatchedAddresses(filteredArgs, currentBlockNumber) + if err != nil { + return err + } + + // update in-memory params + sds.writeLoopParams.WatchedAddresses = append(sds.writeLoopParams.WatchedAddresses, filteredAddresses...) + sds.writeLoopParams.ComputeWatchedAddressesLeafPaths() + case sdtypes.Remove: + // get addresses from args + argAddresses, err := statediff.MapWatchAddressArgsToAddresses(args) + if err != nil { + return fmt.Errorf("remove: mapped addresses %s", err.Error()) + } + + // remove the provided addresses from currently watched addresses + addresses, ok := funk.Subtract(sds.writeLoopParams.WatchedAddresses, argAddresses).([]common.Address) + if !ok { + return fmt.Errorf("remove: filtered addresses %s", typeAssertionFailed) + } + + // update the db + err = sds.Indexer.RemoveWatchedAddresses(args) + if err != nil { + return err + } + + // update in-memory params + sds.writeLoopParams.WatchedAddresses = addresses + sds.writeLoopParams.ComputeWatchedAddressesLeafPaths() + case sdtypes.Set: + // get addresses from args + argAddresses, err := statediff.MapWatchAddressArgsToAddresses(args) + if err != nil { + return fmt.Errorf("set: mapped addresses %s", err.Error()) + } + + // update the db + err = sds.Indexer.SetWatchedAddresses(args, currentBlockNumber) + if err != nil { + return err + } + + // update in-memory params + sds.writeLoopParams.WatchedAddresses = argAddresses + sds.writeLoopParams.ComputeWatchedAddressesLeafPaths() + case sdtypes.Clear: + // update the db + err := sds.Indexer.ClearWatchedAddresses() + if err != nil { + return err + } + + // update in-memory params + sds.writeLoopParams.WatchedAddresses = []common.Address{} + sds.writeLoopParams.ComputeWatchedAddressesLeafPaths() + + default: + return fmt.Errorf("%s %s", unexpectedOperation, operation) + } + + return nil +} + +// SubscribeWriteStatus is used by the API to subscribe to the job status updates +func (sds *MockStateDiffService) SubscribeWriteStatus(id rpc.ID, sub chan<- statediff.JobStatus, quitChan chan<- bool) { + // TODO when WriteStateDiff methods are implemented +} + +// UnsubscribeWriteStatus is used to unsubscribe from job status updates +func (sds *MockStateDiffService) UnsubscribeWriteStatus(id rpc.ID) error { + // TODO when WriteStateDiff methods are implemented + return nil +} diff --git a/statediff/test_helpers/mocks/service_test.go b/statediff/test_helpers/mocks/service_test.go new file mode 100644 index 000000000..776137433 --- /dev/null +++ b/statediff/test_helpers/mocks/service_test.go @@ -0,0 +1,540 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package mocks + +import ( + "bytes" + "fmt" + "math/big" + "os" + "reflect" + "sort" + "sync" + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/statediff" + "github.com/ethereum/go-ethereum/statediff/test_helpers" + sdtypes "github.com/ethereum/go-ethereum/statediff/types" +) + +var ( + emptyStorage = make([]sdtypes.StorageNode, 0) + block0, block1 *types.Block + minerLeafKey = test_helpers.AddressToLeafKey(common.HexToAddress("0x0")) + account1, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: uint64(0), + Balance: big.NewInt(10000), + CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), + Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), + }) + account1LeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3926db69aaced518e9b9f0f434a473e7174109c943548bb8f23be41ca76d9ad2"), + account1, + }) + minerAccount, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: uint64(0), + Balance: big.NewInt(2000002625000000000), + CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), + Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), + }) + minerAccountLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("3380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a"), + minerAccount, + }) + bankAccount, _ = rlp.EncodeToBytes(&types.StateAccount{ + Nonce: uint64(1), + Balance: big.NewInt(1999978999999990000), + CodeHash: common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes(), + Root: common.HexToHash("0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421"), + }) + bankAccountLeafNode, _ = rlp.EncodeToBytes(&[]interface{}{ + common.Hex2Bytes("30bf49f440a1cd0527e4d06e2765654c0f56452257516d793a9b8d604dcfdf2a"), + bankAccount, + }) + mockTotalDifficulty = big.NewInt(1337) + parameters = statediff.Params{ + IntermediateStateNodes: false, + IncludeTD: true, + IncludeBlock: true, + IncludeReceipts: true, + } +) + +func init() { + if os.Getenv("MODE") != "statediff" { + fmt.Println("Skipping statediff test") + os.Exit(0) + } +} + +func TestAPI(t *testing.T) { + testSubscriptionAPI(t) + testHTTPAPI(t) + testWatchAddressAPI(t) +} + +func testSubscriptionAPI(t *testing.T) { + blocks, chain := test_helpers.MakeChain(1, test_helpers.Genesis, test_helpers.TestChainGen) + defer chain.Stop() + block0 = test_helpers.Genesis + block1 = blocks[0] + expectedBlockRlp, _ := rlp.EncodeToBytes(block1) + mockReceipt := &types.Receipt{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + } + expectedReceiptBytes, _ := rlp.EncodeToBytes(&types.Receipts{mockReceipt}) + expectedStateDiff := sdtypes.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []sdtypes.StateNode{ + { + Path: []byte{'\x05'}, + NodeType: sdtypes.Leaf, + LeafKey: minerLeafKey, + NodeValue: minerAccountLeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: sdtypes.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: sdtypes.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountLeafNode, + StorageNodes: emptyStorage, + }, + }, + } + expectedStateDiffBytes, _ := rlp.EncodeToBytes(&expectedStateDiff) + + blockChan := make(chan *types.Block) + parentBlockChain := make(chan *types.Block) + serviceQuitChan := make(chan bool) + mockBlockChain := &BlockChain{} + mockBlockChain.SetReceiptsForHash(block1.Hash(), types.Receipts{mockReceipt}) + mockBlockChain.SetTd(block1.Hash(), block1.NumberU64(), mockTotalDifficulty) + mockService := MockStateDiffService{ + Mutex: sync.Mutex{}, + Builder: statediff.NewBuilder(chain.StateCache()), + BlockChan: blockChan, + BlockChain: mockBlockChain, + ParentBlockChan: parentBlockChain, + QuitChan: serviceQuitChan, + Subscriptions: make(map[common.Hash]map[rpc.ID]statediff.Subscription), + SubscriptionTypes: make(map[common.Hash]statediff.Params), + } + + mockService.Start() + id := rpc.NewID() + payloadChan := make(chan statediff.Payload) + quitChan := make(chan bool) + wg := new(sync.WaitGroup) + wg.Add(1) + go func() { + defer wg.Done() + sort.Slice(expectedStateDiffBytes, func(i, j int) bool { return expectedStateDiffBytes[i] < expectedStateDiffBytes[j] }) + select { + case payload := <-payloadChan: + if !bytes.Equal(payload.BlockRlp, expectedBlockRlp) { + t.Errorf("payload does not have expected block\r\nactual block rlp: %v\r\nexpected block rlp: %v", payload.BlockRlp, expectedBlockRlp) + } + sort.Slice(payload.StateObjectRlp, func(i, j int) bool { return payload.StateObjectRlp[i] < payload.StateObjectRlp[j] }) + if !bytes.Equal(payload.StateObjectRlp, expectedStateDiffBytes) { + t.Errorf("payload does not have expected state diff\r\nactual state diff rlp: %v\r\nexpected state diff rlp: %v", payload.StateObjectRlp, expectedStateDiffBytes) + } + if !bytes.Equal(expectedReceiptBytes, payload.ReceiptsRlp) { + t.Errorf("payload does not have expected receipts\r\nactual receipt rlp: %v\r\nexpected receipt rlp: %v", payload.ReceiptsRlp, expectedReceiptBytes) + } + if !bytes.Equal(payload.TotalDifficulty.Bytes(), mockTotalDifficulty.Bytes()) { + t.Errorf("payload does not have expected total difficulty\r\nactual td: %d\r\nexpected td: %d", payload.TotalDifficulty.Int64(), mockTotalDifficulty.Int64()) + } + case <-quitChan: + t.Errorf("channel quit before delivering payload") + } + }() + time.Sleep(1 * time.Second) + mockService.Subscribe(id, payloadChan, quitChan, parameters) + blockChan <- block1 + parentBlockChain <- block0 + wg.Wait() +} + +func testHTTPAPI(t *testing.T) { + blocks, chain := test_helpers.MakeChain(1, test_helpers.Genesis, test_helpers.TestChainGen) + defer chain.Stop() + block0 = test_helpers.Genesis + block1 = blocks[0] + expectedBlockRlp, _ := rlp.EncodeToBytes(block1) + mockReceipt := &types.Receipt{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + } + expectedReceiptBytes, _ := rlp.EncodeToBytes(&types.Receipts{mockReceipt}) + expectedStateDiff := sdtypes.StateObject{ + BlockNumber: block1.Number(), + BlockHash: block1.Hash(), + Nodes: []sdtypes.StateNode{ + { + Path: []byte{'\x05'}, + NodeType: sdtypes.Leaf, + LeafKey: minerLeafKey, + NodeValue: minerAccountLeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x0e'}, + NodeType: sdtypes.Leaf, + LeafKey: test_helpers.Account1LeafKey, + NodeValue: account1LeafNode, + StorageNodes: emptyStorage, + }, + { + Path: []byte{'\x00'}, + NodeType: sdtypes.Leaf, + LeafKey: test_helpers.BankLeafKey, + NodeValue: bankAccountLeafNode, + StorageNodes: emptyStorage, + }, + }, + } + expectedStateDiffBytes, _ := rlp.EncodeToBytes(&expectedStateDiff) + mockBlockChain := &BlockChain{} + mockBlockChain.SetBlocksForHashes(map[common.Hash]*types.Block{ + block0.Hash(): block0, + block1.Hash(): block1, + }) + mockBlockChain.SetBlockForNumber(block1, block1.Number().Uint64()) + mockBlockChain.SetReceiptsForHash(block1.Hash(), types.Receipts{mockReceipt}) + mockBlockChain.SetTd(block1.Hash(), block1.NumberU64(), big.NewInt(1337)) + mockService := MockStateDiffService{ + Mutex: sync.Mutex{}, + Builder: statediff.NewBuilder(chain.StateCache()), + BlockChain: mockBlockChain, + } + payload, err := mockService.StateDiffAt(block1.Number().Uint64(), parameters) + if err != nil { + t.Error(err) + } + sort.Slice(payload.StateObjectRlp, func(i, j int) bool { return payload.StateObjectRlp[i] < payload.StateObjectRlp[j] }) + sort.Slice(expectedStateDiffBytes, func(i, j int) bool { return expectedStateDiffBytes[i] < expectedStateDiffBytes[j] }) + if !bytes.Equal(payload.BlockRlp, expectedBlockRlp) { + t.Errorf("payload does not have expected block\r\nactual block rlp: %v\r\nexpected block rlp: %v", payload.BlockRlp, expectedBlockRlp) + } + if !bytes.Equal(payload.StateObjectRlp, expectedStateDiffBytes) { + t.Errorf("payload does not have expected state diff\r\nactual state diff rlp: %v\r\nexpected state diff rlp: %v", payload.StateObjectRlp, expectedStateDiffBytes) + } + if !bytes.Equal(expectedReceiptBytes, payload.ReceiptsRlp) { + t.Errorf("payload does not have expected receipts\r\nactual receipt rlp: %v\r\nexpected receipt rlp: %v", payload.ReceiptsRlp, expectedReceiptBytes) + } + if !bytes.Equal(payload.TotalDifficulty.Bytes(), mockTotalDifficulty.Bytes()) { + t.Errorf("paylaod does not have the expected total difficulty\r\nactual td: %d\r\nexpected td: %d", payload.TotalDifficulty.Int64(), mockTotalDifficulty.Int64()) + } +} + +func testWatchAddressAPI(t *testing.T) { + blocks, chain := test_helpers.MakeChain(6, test_helpers.Genesis, test_helpers.TestChainGen) + defer chain.Stop() + block6 := blocks[5] + + mockBlockChain := &BlockChain{} + mockBlockChain.SetCurrentBlock(block6) + mockIndexer := StateDiffIndexer{} + mockService := MockStateDiffService{ + BlockChain: mockBlockChain, + Indexer: &mockIndexer, + } + + // test data + var ( + contract1Address = "0x5d663F5269090bD2A7DC2390c911dF6083D7b28F" + contract2Address = "0x6Eb7e5C66DB8af2E96159AC440cbc8CDB7fbD26B" + contract3Address = "0xcfeB164C328CA13EFd3C77E1980d94975aDfedfc" + contract4Address = "0x0Edf0c4f393a628DE4828B228C48175b3EA297fc" + contract1CreatedAt = uint64(1) + contract2CreatedAt = uint64(2) + contract3CreatedAt = uint64(3) + contract4CreatedAt = uint64(4) + + args1 = []sdtypes.WatchAddressArg{ + { + Address: contract1Address, + CreatedAt: contract1CreatedAt, + }, + { + Address: contract2Address, + CreatedAt: contract2CreatedAt, + }, + } + startingParams1 = statediff.Params{ + WatchedAddresses: []common.Address{}, + } + expectedParams1 = statediff.Params{ + WatchedAddresses: []common.Address{ + common.HexToAddress(contract1Address), + common.HexToAddress(contract2Address), + }, + } + + args2 = []sdtypes.WatchAddressArg{ + { + Address: contract3Address, + CreatedAt: contract3CreatedAt, + }, + { + Address: contract2Address, + CreatedAt: contract2CreatedAt, + }, + } + startingParams2 = expectedParams1 + expectedParams2 = statediff.Params{ + WatchedAddresses: []common.Address{ + common.HexToAddress(contract1Address), + common.HexToAddress(contract2Address), + common.HexToAddress(contract3Address), + }, + } + + args3 = []sdtypes.WatchAddressArg{ + { + Address: contract3Address, + CreatedAt: contract3CreatedAt, + }, + { + Address: contract2Address, + CreatedAt: contract2CreatedAt, + }, + } + startingParams3 = expectedParams2 + expectedParams3 = statediff.Params{ + WatchedAddresses: []common.Address{ + common.HexToAddress(contract1Address), + }, + } + + args4 = []sdtypes.WatchAddressArg{ + { + Address: contract1Address, + CreatedAt: contract1CreatedAt, + }, + { + Address: contract2Address, + CreatedAt: contract2CreatedAt, + }, + } + startingParams4 = expectedParams3 + expectedParams4 = statediff.Params{ + WatchedAddresses: []common.Address{}, + } + + args5 = []sdtypes.WatchAddressArg{ + { + Address: contract1Address, + CreatedAt: contract1CreatedAt, + }, + { + Address: contract2Address, + CreatedAt: contract2CreatedAt, + }, + { + Address: contract3Address, + CreatedAt: contract3CreatedAt, + }, + } + startingParams5 = expectedParams4 + expectedParams5 = statediff.Params{ + WatchedAddresses: []common.Address{ + common.HexToAddress(contract1Address), + common.HexToAddress(contract2Address), + common.HexToAddress(contract3Address), + }, + } + + args6 = []sdtypes.WatchAddressArg{ + { + Address: contract4Address, + CreatedAt: contract4CreatedAt, + }, + { + Address: contract2Address, + CreatedAt: contract2CreatedAt, + }, + { + Address: contract3Address, + CreatedAt: contract3CreatedAt, + }, + } + startingParams6 = expectedParams5 + expectedParams6 = statediff.Params{ + WatchedAddresses: []common.Address{ + common.HexToAddress(contract4Address), + common.HexToAddress(contract2Address), + common.HexToAddress(contract3Address), + }, + } + + args7 = []sdtypes.WatchAddressArg{} + startingParams7 = expectedParams6 + expectedParams7 = statediff.Params{ + WatchedAddresses: []common.Address{}, + } + + args8 = []sdtypes.WatchAddressArg{} + startingParams8 = expectedParams6 + expectedParams8 = statediff.Params{ + WatchedAddresses: []common.Address{}, + } + + args9 = []sdtypes.WatchAddressArg{} + startingParams9 = expectedParams8 + expectedParams9 = statediff.Params{ + WatchedAddresses: []common.Address{}, + } + ) + + tests := []struct { + name string + operation sdtypes.OperationType + args []sdtypes.WatchAddressArg + startingParams statediff.Params + expectedParams statediff.Params + expectedErr error + }{ + { + "testAddAddresses", + sdtypes.Add, + args1, + startingParams1, + expectedParams1, + nil, + }, + { + "testAddAddressesSomeWatched", + sdtypes.Add, + args2, + startingParams2, + expectedParams2, + nil, + }, + { + "testRemoveAddresses", + sdtypes.Remove, + args3, + startingParams3, + expectedParams3, + nil, + }, + { + "testRemoveAddressesSomeWatched", + sdtypes.Remove, + args4, + startingParams4, + expectedParams4, + nil, + }, + { + "testSetAddresses", + sdtypes.Set, + args5, + startingParams5, + expectedParams5, + nil, + }, + { + "testSetAddressesSomeWatched", + sdtypes.Set, + args6, + startingParams6, + expectedParams6, + nil, + }, + { + "testSetAddressesEmtpyArgs", + sdtypes.Set, + args7, + startingParams7, + expectedParams7, + nil, + }, + { + "testClearAddresses", + sdtypes.Clear, + args8, + startingParams8, + expectedParams8, + nil, + }, + { + "testClearAddressesEmpty", + sdtypes.Clear, + args9, + startingParams9, + expectedParams9, + nil, + }, + + // invalid args + { + "testInvalidOperation", + "WrongOp", + args9, + startingParams9, + statediff.Params{}, + fmt.Errorf("%s WrongOp", unexpectedOperation), + }, + } + + for _, test := range tests { + // set indexing params + mockService.writeLoopParams = statediff.ParamsWithMutex{ + Params: test.startingParams, + } + mockService.writeLoopParams.ComputeWatchedAddressesLeafPaths() + + // make the API call to change watched addresses + err := mockService.WatchAddress(test.operation, test.args) + if test.expectedErr != nil { + if err.Error() != test.expectedErr.Error() { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual err: %+v\nexpected err: %+v", err, test.expectedErr) + } + + continue + } + if err != nil { + t.Error(err) + } + + // check updated indexing params + test.expectedParams.ComputeWatchedAddressesLeafPaths() + updatedParams := mockService.writeLoopParams.Params + if !reflect.DeepEqual(updatedParams, test.expectedParams) { + t.Logf("Test failed: %s", test.name) + t.Errorf("actual params: %+v\nexpected params: %+v", updatedParams, test.expectedParams) + } + } +} diff --git a/statediff/test_helpers/test_data.go b/statediff/test_helpers/test_data.go new file mode 100644 index 000000000..e5a06a2a1 --- /dev/null +++ b/statediff/test_helpers/test_data.go @@ -0,0 +1,73 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package test_helpers + +import ( + "math/big" + "math/rand" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// AddressToLeafKey hashes an returns an address +func AddressToLeafKey(address common.Address) []byte { + return crypto.Keccak256(address[:]) +} + +// AddressToEncodedPath hashes an address and appends the even-number leaf flag to it +func AddressToEncodedPath(address common.Address) []byte { + addrHash := crypto.Keccak256(address[:]) + decodedPath := append(EvenLeafFlag, addrHash...) + return decodedPath +} + +// Test variables +var ( + EvenLeafFlag = []byte{byte(2) << 4} + BlockNumber = big.NewInt(rand.Int63()) + BlockHash = "0xfa40fbe2d98d98b3363a778d52f2bcd29d6790b9b3f3cab2b167fd12d3550f73" + NullCodeHash = crypto.Keccak256Hash([]byte{}) + StoragePath = common.HexToHash("0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470").Bytes() + StorageKey = common.HexToHash("0000000000000000000000000000000000000000000000000000000000000001").Bytes() + StorageValue = common.Hex2Bytes("0x03") + NullHash = common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000") + + Testdb = rawdb.NewMemoryDatabase() + TestBankKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + TestBankAddress = crypto.PubkeyToAddress(TestBankKey.PublicKey) //0x71562b71999873DB5b286dF957af199Ec94617F7 + BankLeafKey = AddressToLeafKey(TestBankAddress) + TestBankFunds = big.NewInt(params.Ether * 2) + Genesis = GenesisBlockForTesting(Testdb, TestBankAddress, TestBankFunds) + + Account1Key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") + Account2Key, _ = crypto.HexToECDSA("49a7b37aa6f6645917e7b807e9d1c00d4fa71f18343b0d4122a4d2df64dd6fee") + Account1Addr = crypto.PubkeyToAddress(Account1Key.PublicKey) //0x703c4b2bD70c169f5717101CaeE543299Fc946C7 + Account2Addr = crypto.PubkeyToAddress(Account2Key.PublicKey) //0x0D3ab14BBaD3D99F4203bd7a11aCB94882050E7e + Account1LeafKey = AddressToLeafKey(Account1Addr) + Account2LeafKey = AddressToLeafKey(Account2Addr) + ContractCode = common.Hex2Bytes("608060405234801561001057600080fd5b50336000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055506040518060200160405280600160ff16815250600190600161007492919061007a565b506100e4565b82606481019282156100ae579160200282015b828111156100ad578251829060ff1690559160200191906001019061008d565b5b5090506100bb91906100bf565b5090565b6100e191905b808211156100dd5760008160009055506001016100c5565b5090565b90565b6101ca806100f36000396000f3fe608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101746022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b806001836064811061016a57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a72305820e3747183708fb6bff3f6f7a80fb57dcc1c19f83f9cb25457a3ed5c0424bde66864736f6c634300050a0032") + ByteCodeAfterDeployment = common.Hex2Bytes("608060405234801561001057600080fd5b50600436106100365760003560e01c806343d726d61461003b578063c16431b914610045575b600080fd5b61004361007d565b005b61007b6004803603604081101561005b57600080fd5b81019080803590602001909291908035906020019092919050505061015c565b005b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610122576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806101746022913960400191505060405180910390fd5b6000809054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b806001836064811061016a57fe5b0181905550505056fe4f6e6c79206f776e65722063616e2063616c6c20746869732066756e6374696f6e2ea265627a7a72305820e3747183708fb6bff3f6f7a80fb57dcc1c19f83f9cb25457a3ed5c0424bde66864736f6c634300050a0032") + CodeHash = common.HexToHash("0xaaea5efba4fd7b45d7ec03918ac5d8b31aa93b48986af0e6b591f0f087c80127") + ContractAddr common.Address + + EmptyRootNode, _ = rlp.EncodeToBytes(&[]byte{}) + EmptyContractRoot = crypto.Keccak256Hash(EmptyRootNode) +) diff --git a/statediff/trie_helpers/helpers.go b/statediff/trie_helpers/helpers.go new file mode 100644 index 000000000..869b0cc88 --- /dev/null +++ b/statediff/trie_helpers/helpers.go @@ -0,0 +1,129 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Contains a batch of utility type declarations used by the tests. As the node +// operates on unique types, a lot of them are needed to check various features. + +package trie_helpers + +import ( + "fmt" + "sort" + "strings" + "time" + + metrics2 "github.com/ethereum/go-ethereum/statediff/indexer/database/metrics" + + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/statediff/types" + "github.com/ethereum/go-ethereum/trie" +) + +// CheckKeyType checks what type of key we have +func CheckKeyType(elements []interface{}) (types.NodeType, error) { + if len(elements) > 2 { + return types.Branch, nil + } + if len(elements) < 2 { + return types.Unknown, fmt.Errorf("node cannot be less than two elements in length") + } + switch elements[0].([]byte)[0] / 16 { + case '\x00': + return types.Extension, nil + case '\x01': + return types.Extension, nil + case '\x02': + return types.Leaf, nil + case '\x03': + return types.Leaf, nil + default: + return types.Unknown, fmt.Errorf("unknown hex prefix") + } +} + +// ResolveNode return the state diff node pointed by the iterator. +func ResolveNode(it trie.NodeIterator, trieDB *trie.Database) (types.StateNode, []interface{}, error) { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.ResolveNodeTimer) + nodePath := make([]byte, len(it.Path())) + copy(nodePath, it.Path()) + node, err := trieDB.Node(it.Hash()) + if err != nil { + return types.StateNode{}, nil, err + } + var nodeElements []interface{} + if err = rlp.DecodeBytes(node, &nodeElements); err != nil { + return types.StateNode{}, nil, err + } + ty, err := CheckKeyType(nodeElements) + if err != nil { + return types.StateNode{}, nil, err + } + return types.StateNode{ + NodeType: ty, + Path: nodePath, + NodeValue: node, + }, nodeElements, nil +} + +// SortKeys sorts the keys in the account map +func SortKeys(data types.AccountMap) []string { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.SortKeysTimer) + keys := make([]string, 0, len(data)) + for key := range data { + keys = append(keys, key) + } + sort.Strings(keys) + + return keys +} + +// FindIntersection finds the set of strings from both arrays that are equivalent +// a and b must first be sorted +// this is used to find which keys have been both "deleted" and "created" i.e. they were updated +func FindIntersection(a, b []string) []string { + defer metrics2.UpdateDuration(time.Now(), metrics2.IndexerMetrics.FindIntersectionTimer) + lenA := len(a) + lenB := len(b) + iOfA, iOfB := 0, 0 + updates := make([]string, 0) + if iOfA >= lenA || iOfB >= lenB { + return updates + } + for { + switch strings.Compare(a[iOfA], b[iOfB]) { + // -1 when a[iOfA] < b[iOfB] + case -1: + iOfA++ + if iOfA >= lenA { + return updates + } + // 0 when a[iOfA] == b[iOfB] + case 0: + updates = append(updates, a[iOfA]) + iOfA++ + iOfB++ + if iOfA >= lenA || iOfB >= lenB { + return updates + } + // 1 when a[iOfA] > b[iOfB] + case 1: + iOfB++ + if iOfB >= lenB { + return updates + } + } + } +} diff --git a/statediff/types/types.go b/statediff/types/types.go new file mode 100644 index 000000000..0a29adaf8 --- /dev/null +++ b/statediff/types/types.go @@ -0,0 +1,120 @@ +// Copyright 2019 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library 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 Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package types + +import ( + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" +) + +// StateRoots holds the state roots required for generating a state diff +type StateRoots struct { + OldStateRoot, NewStateRoot common.Hash +} + +// StateObject is the final output structure from the builder +type StateObject struct { + BlockNumber *big.Int `json:"blockNumber" gencodec:"required"` + BlockHash common.Hash `json:"blockHash" gencodec:"required"` + Nodes []StateNode `json:"nodes" gencodec:"required"` + CodeAndCodeHashes []CodeAndCodeHash `json:"codeMapping"` +} + +// AccountMap is a mapping of hex encoded path => account wrapper +type AccountMap map[string]AccountWrapper + +// AccountWrapper is used to temporary associate the unpacked node with its raw values +type AccountWrapper struct { + Account *types.StateAccount + NodeType NodeType + Path []byte + NodeValue []byte + LeafKey []byte +} + +// NodeType for explicitly setting type of node +type NodeType string + +const ( + Unknown NodeType = "Unknown" + Branch NodeType = "Branch" + Extension NodeType = "Extension" + Leaf NodeType = "Leaf" + Removed NodeType = "Removed" // used to represent paths which have been emptied +) + +func (n NodeType) Int() int { + switch n { + case Branch: + return 0 + case Extension: + return 1 + case Leaf: + return 2 + case Removed: + return 3 + default: + return -1 + } +} + +// StateNode holds the data for a single state diff node +type StateNode struct { + NodeType NodeType `json:"nodeType" gencodec:"required"` + Path []byte `json:"path" gencodec:"required"` + NodeValue []byte `json:"value" gencodec:"required"` + StorageNodes []StorageNode `json:"storage"` + LeafKey []byte `json:"leafKey"` +} + +// StorageNode holds the data for a single storage diff node +type StorageNode struct { + NodeType NodeType `json:"nodeType" gencodec:"required"` + Path []byte `json:"path" gencodec:"required"` + NodeValue []byte `json:"value" gencodec:"required"` + LeafKey []byte `json:"leafKey"` +} + +// CodeAndCodeHash struct for holding codehash => code mappings +// we can't use an actual map because they are not rlp serializable +type CodeAndCodeHash struct { + Hash common.Hash `json:"codeHash"` + Code []byte `json:"code"` +} + +type StateNodeSink func(StateNode) error +type StorageNodeSink func(StorageNode) error +type CodeSink func(CodeAndCodeHash) error + +// OperationType for type of WatchAddress operation +type OperationType string + +const ( + Add OperationType = "add" + Remove OperationType = "remove" + Set OperationType = "set" + Clear OperationType = "clear" +) + +// WatchAddressArg is a arg type for WatchAddress API +type WatchAddressArg struct { + // Address represents common.Address + Address string + CreatedAt uint64 +} diff --git a/README.md b/trie/concurrent_iterator/README.md similarity index 91% rename from README.md rename to trie/concurrent_iterator/README.md index 9835b0045..0f2c86af4 100644 --- a/README.md +++ b/trie/concurrent_iterator/README.md @@ -2,9 +2,7 @@ Official Golang execution layer implementation of the Ethereum protocol. -[![API Reference]( -https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667 -)](https://pkg.go.dev/github.com/ethereum/go-ethereum?tab=doc) +[![API Reference](https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f676f6c616e672f6764646f3f7374617475732e737667)](https://pkg.go.dev/github.com/ethereum/go-ethereum?tab=doc) [![Go Report Card](https://goreportcard.com/badge/github.com/ethereum/go-ethereum)](https://goreportcard.com/report/github.com/ethereum/go-ethereum) [![Travis](https://travis-ci.com/ethereum/go-ethereum.svg?branch=master)](https://travis-ci.com/ethereum/go-ethereum) [![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv) @@ -12,6 +10,21 @@ https://camo.githubusercontent.com/915b7be44ada53c290eb157634330494ebe3e30a/6874 Automated builds are available for stable releases and the unstable master branch. Binary archives are published at https://geth.ethereum.org/downloads/. +## Vulcanize Specific + +This section captures components specific to vulcanize. + +### Branching Structure + +We currently follow the following branching structure. + +1. Create a branch: `v1.10.18-statediff-vX` --> feature/some-feature` +2. Create a PR upstream: `feature/some-feature` --> `v1.10.18-statediff-vX` +3. When a release is ready, create a release branch: `v1.10.18-statediff-vX` --> `v1.10.18-statediff-X.Y.Z` +4. When `v1.10.18-statediff-vX` is stable, merge it to `statediff`. + +This process is subject to change. + ## Building the source For prerequisites and detailed build instructions please read the [Installation Instructions](https://geth.ethereum.org/docs/getting-started/installing-geth). @@ -55,10 +68,10 @@ on how you can run your own `geth` instance. Minimum: -* CPU with 2+ cores -* 4GB RAM -* 1TB free storage space to sync the Mainnet -* 8 MBit/sec download Internet service +- CPU with 2+ cores +- 4GB RAM +- 1TB free storage space to sync the Mainnet +- 8 MBit/sec download Internet service Recommended: @@ -121,17 +134,16 @@ Specifying the `--goerli` flag, however, will reconfigure your `geth` instance a crossing over between the main network and test network, you should always use separate accounts for play and real money. Unless you manually move accounts, `geth` will by default correctly separate the two networks and will not make any -accounts available between them.* +accounts available between them._ ### Full node on the Rinkeby test network Go Ethereum also supports connecting to the older proof-of-authority based test network -called [*Rinkeby*](https://www.rinkeby.io) which is operated by members of the community. +called [_Rinkeby_](https://www.rinkeby.io) which is operated by members of the community. ```shell $ geth --rinkeby console ``` - ### Configuration As an alternative to passing the numerous flags to the `geth` binary, you can also pass a @@ -148,7 +160,7 @@ export your existing configuration: $ geth --your-favourite-flags dumpconfig ``` -*Note: This works only with `geth` v1.6.0 and above.* +_Note: This works only with `geth` v1.6.0 and above._ #### Docker quick start @@ -288,8 +300,8 @@ that other nodes can use to connect to it and exchange peer information. Make su replace the displayed IP address information (most probably `[::]`) with your externally accessible IP to get the actual `enode` URL. -*Note: You could also use a full-fledged `geth` node as a bootnode, but it's the less -recommended way.* +_Note: You could also use a full-fledged `geth` node as a bootnode, but it's the less +recommended way._ #### Starting up your member nodes @@ -303,8 +315,8 @@ do also specify a custom `--datadir` flag. $ geth --datadir=path/to/custom/data/folder --bootnodes= ``` -*Note: Since your network will be completely cut off from the main and test networks, you'll -also need to configure a miner to process transactions and create new blocks for you.* +_Note: Since your network will be completely cut off from the main and test networks, you'll +also need to configure a miner to process transactions and create new blocks for you._ #### Running a private miner @@ -338,13 +350,13 @@ and merge procedures quick and simple. Please make sure your contributions adhere to our coding guidelines: - * Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) - guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)). - * Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) - guidelines. - * Pull requests need to be based on and opened against the `master` branch. - * Commit messages should be prefixed with the package(s) they modify. - * E.g. "eth, rpc: make trace configs optional" +- Code must adhere to the official Go [formatting](https://golang.org/doc/effective_go.html#formatting) + guidelines (i.e. uses [gofmt](https://golang.org/cmd/gofmt/)). +- Code must be documented adhering to the official Go [commentary](https://golang.org/doc/effective_go.html#commentary) + guidelines. +- Pull requests need to be based on and opened against the `master` branch. +- Commit messages should be prefixed with the package(s) they modify. + - E.g. "eth, rpc: make trace configs optional" Please see the [Developers' Guide](https://geth.ethereum.org/docs/developers/geth-developer/dev-guide) for more details on configuring your environment, managing project dependencies, and @@ -365,3 +377,4 @@ also included in our repository in the `COPYING.LESSER` file. The go-ethereum binaries (i.e. all code inside of the `cmd` directory) are licensed under the [GNU General Public License v3.0](https://www.gnu.org/licenses/gpl-3.0.en.html), also included in our repository in the `COPYING` file. + diff --git a/trie/concurrent_iterator/fixture/chaindata.go b/trie/concurrent_iterator/fixture/chaindata.go new file mode 100644 index 000000000..6961f58d8 --- /dev/null +++ b/trie/concurrent_iterator/fixture/chaindata.go @@ -0,0 +1,27 @@ +package fixture + +import ( + "os" + "path/filepath" + "runtime" +) + +// TODO: embed some mainnet data +// import "embed" +//_go:embed mainnet_data.tar.gz + +var ( + ChainDataPath, AncientDataPath string +) + +func init() { + _, path, _, _ := runtime.Caller(0) + wd := filepath.Dir(path) + + ChainDataPath = filepath.Join(wd, "..", "fixture", "chaindata") + AncientDataPath = filepath.Join(ChainDataPath, "ancient") + + if _, err := os.Stat(ChainDataPath); err != nil { + panic("must populate chaindata at " + ChainDataPath) + } +} diff --git a/trie/concurrent_iterator/fixture/chaindata/.gitignore b/trie/concurrent_iterator/fixture/chaindata/.gitignore new file mode 100644 index 000000000..8836fe152 --- /dev/null +++ b/trie/concurrent_iterator/fixture/chaindata/.gitignore @@ -0,0 +1,6 @@ +*.log +CURRENT* +LOCK +LOG +MANIFEST-* +ancient/FLOCK diff --git a/trie/concurrent_iterator/fixture/chaindata/000002.ldb b/trie/concurrent_iterator/fixture/chaindata/000002.ldb new file mode 100644 index 0000000000000000000000000000000000000000..8e5331a4a271bcfed88409152aa392098ea42edc GIT binary patch literal 5765300 zcmb@tWmME%_Xa#?7`l<}?(RmA5D;kv32A9*0TG7MK~hRWV31Df7C{;W1SKU^5EKvz z0jc*l-p}*AU;b;|YrX58FD}=*W}kib*>UZ?hiTT`Lm00c+~EuleqYVU>wd~IWee?t z!`!`h@%z)~SuzV&NpxzqpbEe+pJNv^>r&mW+Ar^r!HB+s*mid#ZE-1)J&Wp=mUDJ4 zd~3ey7R_UIBtYNVV4-1nXIgw2sj;5ib?j+zeT5;@y{Ze?i8Ow(Z(u|BO=^P2M;waD zp^xeo2C%x;U`@uu5j+YH|I8w+q6@tMkE=^hsu*vf+nZ}qHj@2Z^zJE9CWLgFo|9#) zF6^dTDPa9SN;&7TI=_p152Fq~t~r=r6qZadkq0l{*NO>sE;Vc|nDhT%I*p~mGGM&M zSOFsGk}@?rpcF^8*Jil4bD_J(AtK`yRo2s@VE;o@Ys z^B8Lh3pNr7cmPNOJZ@f0`L&~X^+HtI{fQ@NEgBU1CG1bbIYCFxqJR7i{FMF|iqLHV{x<|~VcG`#Uj zHz8E}m}Y6@^2FlB?omsCxS5suP!XVkEpWY|-G8)tb9&v-g0bWJ~$ zK15dEaCRtv;l`YMvp&#(XwM=_~w+=*|*LPX=#?NryhkJuKDwc ziF!u(*?15t6bBCYlAxDE@NhW^dNJzevK|!=Cv0<{He22m0` zVDwDqi0yU{&AvGDy@8?FHUp3Q`aGS{k1a=y#p;Q1Hyk7|B?i#(i-Y$Ak7-q+#s%BG zJ#NZ`PQMV#KNLDS(WEWD9n3HaPLcdNLcZEsaLGN@riJvL#;@BAwi4wYbT5a|-!5L^ zxq(ckMIVh-D+Q*TsG0os zk0si2@fyqjHOfuBIO68T6J6V0R2^*^ z^330?Oy%aV{gD@~qIU4?8W65>gsv+;cTXikQhkk1?@rBDS^nw64-be*7wpEAX<;%{ zPkb-BfLIq4wysLGlsdGvLT?aTJ{UC9QR;Jmd zUYi60wjsMF+-aM|+_u@~l(AR&?hqDP7JFW#!pKuGUQEcYVzVkW*2DDLr4)azRnc;y zlE#KO`->=pRFB*!7dDX9GeH?5(OjK>e!pxLXd||uJHC2FI`~Gs@^7S!rg@5wP<2m{ zpOCF03W*LW5vFsXYg6RJGY0@w^vXvdn8b&WFf(}fJ`ac9S~wD$2Zpr$igGnn2vV2J z8u-jd-#psgnupNfa_`ygX=;2sMN*-k@dPjfF^WKm@J8DHW)oT~7p&o55B1}F2rDj@ zkv_Gw?L9j^K;?o0$WfqNiAZ*kMHQSzGK^9AQB~{4LtBpP+F_h={q&q88;8KVJ zvIpxSvDwA?GoerJ%TsUd;h$269#^^ixEWT@<81FXv<|%%c^YJ1V{sTlU-bC*dy{!_ zM!qo#c(Z!|)gah`QErIn_;5Xpo>yDL# zv|WNHiZ{HHKz9`i4q_$R(C>^7wXUca+zz`8luoT;(N$=#qp@4TsdV9a9t$NX*XWV= zmnc`N&jE&?hAh}~`9`A{4i~OXM;zyNHC|gt10&DSFynAcKY@ZiL0MYyjh+Olc^R1c~s1&Gw_WA%*E@E|~{5Q|A6no#ak+)Wtax_Y>X%Cb$@X zpg6^C&emlXo#a(sy^bgJ&u+anzAdy{@N`wP603>-;J?;$%egX#YS!}^2D9#5jP04h zFW#{+_$8zeOqMHsEj^h53jjYA6FkB>-FKwAD{=^WB`sLs=LtwJl)Qu^BN3$nSAo1m=v0f6u&N7k~A)E*5xO=qdl_attMxj zZilz@#`&-q_Y5NvY0CgTe*@MG4Tn*NA2&x={qU)>?yNiEo!TR^=M9T=`_su*{_((I zi1~m7oPb*N=1uaKxdHF#UTuO8HuMxTA3uynDShA4e=oDGMTEGOkJf%5=qx2%p-1{8 z+PGz!$?W#?J<^bk)V_Tg7`zmNA_f(MSHf ztL-v>sM0A5QYP}z_`CF`B53NUiJ10E`ToM{@sHBcy@Z?r#A(hUFn#{|>+aN#XYBFhJKUuP4oL>8lkeZ4^D4$RYSVX`kiwt5*;5C-j*zs_0C0C#ot*WxZ1ew8*=Ys zq?UjK(4OV@q+_Nb7B^YRvwM4iL`TTW8U^@Nt9?XDXCZ4^-)?U@jHEclA)c&CQseeb z?I6Qzke}bhir0SY)lr^9kxWcCGY{(gDyv)G8{icD_A1nt8qDZfLIEYt&V6j`-MIFZ zMnNLK)h@@++;-nH8=I`}*)L|LIg5+OSl*8@0Yw)40*(OWRB3@KxuGv*2V=+#6VCq=P~EPygQZ9JuoT(q(zY z%zd4U9KpD)A#Bc{_OFJ{uE^?HrBH+)P)>b(()E8))Bi7Y8PbXpi!C^ek~)&;3G7K9 z=X~3eTr>~Med#QU8ZwlkcXBWwfy2ntk;$qNshU-{2`!#~cxs>(QEbGH=znyVuZfC^ z(*r@a0MW^G7=Ah?7ynCm02w$)MZ=CU9Lrf`?2*p*t}wDklHwj@(M_Uu&2Ebw%g;y_ z+rH%ZJ?Mp~2RQHAxZq6hWElHrN#$bO|MCX^RCV12C&&AINr+^1jVk2{W zsQ1Lmr{GpTa5^LDMn=h{U47lxiu7l{7=oMb1Ag!~Bdh!>G;Q)QA`9l`VA(k(m2$)h zO;aCF^_uhFB`2>PhcdDpIm&g6wfWTo+OqZ}Rx2{4TaBOr zkf#PppI7yJ$xrKqjNaW|2#g;R{xh)Rw8CWFOyl{iSc2)l)!LT|U%cs_+mc0TtC$aQ z^5MWJyP#-w(fecbtJ9syThVpEU2g*B&1Sxv1lc6*KyYH+IihxH#)Qh}-iO>5wVzO4 z`B!4sZ%5qw(f{!|1i3(spKsLSSmMvjpCopPn^2#0n4N`H=VxVq&GEec^Bn}4k$=9? ze_j#%IF0G&^^Gzw$g)rsa}!h7iaor3b2@sHI&7?}$?NTY z#8;Lq7t(-Yveh&0MX*GigGu~KEw;?@L{z!WoRifhJod|t#YtJw)S4kd?`1t~i^y9p zX5o6XXvmrVEpY*POi;ui0xf*?_U|-J1=xgwUJYc#oy|}$m=%pg*yJVPj^siq9i%#X;zLBdm`#tKj;t}L z1{YtJx;lL1P~u%w#od+Eho(!P+C?uphq+GNdvSBce=10Rkb4K@}r1%};!I&EHg|CtY;uF~c94IlvILtzkY zN{REsHr^*I|D#>ucGuzhw|D7MCU(BQm8h>jNVZAL8S`ZhNgO447O;j(hr*EPRKqmQIPxD`tDp0~Ox6V*p>ksy z!W@#qkAnSAMiol#gNM7?NHp_yHJ`&I_v@l8)74eGoBG0^s|^)Bmg>~@@v!tq0M9>+ zo!QAe*1N+xSTQ{4BZDzVwo}k*NRX#ZXus0BkMAev8qld%1Z6Z)-I0Ry38B?(=>w+U zL@U(@?Y0dS%7LpIjK5OssuM3r;N~PS*WfmYo>=J>Kwn^$#EXt-C`q(s^mU@MR!%*^ z!;v{4(`|qMKI}A5N&CNE@5&mT^{(T|Ofl1yrs5@g>t5tqE!-`7$#uBTjm~%HSQ?l~ z@ddJmCI}XMiN27V#>R6)WM?kZ&$rxRbaZ(l$$5b4tNJH7v&AJUQw&`x)78 z3NE6v$e$|zQ;cJL35z8|@5$Ye<$3CCfnvXEJ_9@bEzxc?r3azA@M91R*TjpmM`8Z?lW`<%#z#>X%#dbuX((e((iMH&?r(!?RMdRl*?!?JpEgr< zEC1-{UoYL*t9o|}gb=5}45LpGP@~-s!{$Mvb7`lNdnm%L%dXMB`#kkQCW+5N-zO3dj4Ga|f#uN2yM*%tjeNdrX94TRZ!K)X;0ItI-er6H_O zM4v})Y1B{|h+Yz5AgC=Y-;hIaS9-6gJPB%XI(9&!;n;mn0ER%{x(FkJgu9jfYQfR_ z)Wlbbn-!5;q+9n%a40g9li-EDx?tne2_NOO9KCv8j{cYzh3Re z-T6d1&u+7sI}&+JY&Xz*{nMwDxI|{oretX@y%gaL^5>;)x>NRv zA=3Kdw0oNzshR04`+T&JJ+$Q_56dG@5GqEnKmVm_O$R8SXa7t#`KW0))8!URMdaRJ zDtx@`ib#J~8BwWFMtyKqTb)eU0-XK7RE?E_>vuTUBjq5hn z*XbRxQU8BYH7HzSzs+Q?Hy|ftvZQ(y z(77egTgJ$xVE^>kx&Bp%j9`U!NTt4eU03=4r4uyS#LQ**$!%O`C0cR9W^&gxuIqnh zy1JLW=8IO{4+}ASA0%!HhUEB>HIp&l*_ehC;6yJ5`=;AORPV3eElzImjw)=`tYg!I z$RIxu<3}0mn>|Ql*U7mhm4(Y94cGQ1Y2L*U16!0=CZoP{D{b_cx$2 zLMWXekxYX_fPTXx+&ZdEVk{?Wms$^h@;y}3upuh=W};3w%uOrxS^oCNFN(buh-O*MP}FqbTz=}j898#t|J1U@1$3h7#D;4#2XKez%v0ngB*<})YR zJ^B}PcD0*9pH}C7jMqLI$dshHr9fGSDEL5$PCaOE_mP~M)q8bB=e8;t;1Tn?J*G9L zuYzNdTs8c6Df;B+gd)L66)}soSJL_`;}2&Mxv2dQHMH&KB?8{ z!Nk;->!HSP{RKS&_dgxXTIel)9^xl_5^3_yEfd%rU4L<6=~JS z$6jH`QMez4j?X9|yn6SOFZY+;$Y(DZyVdD(zY(?gt37YmHkaS7=|p#U=b`Ux^)%`>oAp3`0dE5_)MyCcmPmX0()s$@`sO#u7;5V+f|4RF!e0^qQ zqU6!HXw29rl{xpkTE4X;iYH5y^z)_~wuizBOW|IY<}BS|Z$v%N#_(Hc;{lP8y9J>~ z>yJy07nPC_OQxpWVkChJZ=yr83B4@@`BUfDYXVe3hzy!98Z_fDn2YwCor0c*%_97CElDy7uh0;eGTEzo*si zM51SDA}`7rr~DP(vaWfbfB5m_1V-Jk!$2$x$+&w19Vh;^AoCGP>TIf~k~DMQdv>cA zvz8tkQ$FnknL|kQpREIPBVXDHksYCySxb{MPCYnon}jR)^4wejNx#m5o~yS>43*5d z+#tK9LWIxNiRKMiDhkctujYHDk)P}oh8`B?VvaCikK)aNIe8;oB#3i+&61o6@bSmB zcHOC>t$Ah!}Ub(GAZt=|Qgim9Ik5*3@Fi{SLlXrf+Dxe;E^F2HipgXri$L zM0Y|J_N{MyT}eX)`=HNqM_9mYi~&)0%m#OWATPg=m8p}o{Kajo7pV@z^@h&T;XO#2=n zKM4_rb3OggX|>l=wvl@S=S|guJj+dmRKRAg)pGF)_wW_U)nPJB7(#F>x4CG>!cd1A1`B1|$?3V!=NBHaBy1I@;*xrm3=EbJWpho#DCHQc_&= zcfMY{0a9-;>@X-RG>XvXwe#gez6bhzl#PjBc4qgRhWZ7{y5FvxP67%zlz3(Ke)>n# z3-}AyX*GJ$7wzd0J@%KBAoA;Dq~E+kcXZJSlsZuo^WU;>?PgdO*pyv}v=toOc9J^y zW`f>%XZ2efwIP-UoB_1tf-ai3{@5f;Co_kaw)#_dtgrRtsDYp;g%07(plZ>M{4m$S(O4c+r`|hi{AO#MdeGE$N8W@&jj-f;x+Ka(mr0o zgNQ3Lt>Id(Sqa9)S#tecYl9TI$xki>fSf>*tE6RHd>wzEdrXq^wI?zT&e}{&HZ~)d z?2N_R?iqXKXpe1JOa-)Dqn!y8O*awH$3%Ea!@ zJ)p^typ$(Mz1iuJyCt$XfkdBt*X*pn2Ku^2 zGXC+w_KnEZdemhV$wr4AxcW~Fo&a*R9j?)IXX(;a`ZzSBAS%;?m$va$ z;}F5M=7F$pSwTTZo7t~P2@Oy)W9aaA?Jt=^w$$j|kA&15RZ{xOofktqw&F(Xuh=cv z-nW2c{M$|jiB=qDuG!IjlP1N}J%3lB=g7VChx(mSiy3+H2l=@|0jEgx&Q)Er$MGLT zuLvhmp_G33%o6-84A+V(&hbfWt?eh8LZY8`MrfUVGif#F-ee1XyQ79hQYVO4f=tv9 zl69l3F|EZcPhFW)g*qQg3ebGssC&wlogzK^SXvd!rO z@3WWpPqL0@S|lgZBDWCpMp0fiUgLlC8gy8}ZJ_-y1oBq<5VMSCY@7nE>W8*y$uq8yT{?vr0ucX)lVH~6|9sF@H6u)I{^tXByuTLr%d(O`@0DlRBM=GM?NR3ECtR@)`#5GaW1kM)`BwRghJBAqa> zW?Etkd=GA5I?sQhk01!Jk!Sq<0SI!SxjMWkp*8+R;F1o@%z2vBS(@@>r;Si~A#CUe3-8Gs!%mu}Hs|K>-lvr-X%9w&^UJr#JD;6d2G#=>snS3xMKkuO ztrT2?sJ0bjw>!<%>V-Eydq>4I3w$XL>>0Qy1!AR;e#ZY2aXOdT`o6=7Qlba!73MUG2DQDTyHu+b{5GXo{=MLO7$n zH0k{4o0Pna*aKaX57Qw*P#g7cJ0Ktnhk-D*(m;1oDjjKSJa=a=gRyVAi%Xf$^Ou%t z){JPR;|QAC3L%?_UBUEas-I^+nWK3*sZZ>8JuBq7u3~8cNy%xS>%xtqWtz9GNB89CY5ce|o1@mq zFGOeTHThPmCNd{c=$=&+C1nJ-5SoVyFY5!c={Gf%!SR$>5)}U4$lO-~=J>E*&L&pX1&{CA zT&M#%b(HJB<^n@#ZX$6J)o*VT+P=c*28)Nc3V*z);NA}R2G@BWVF9t@B$@XJs%2qg<+7(xCQm~@ zqIygO5(<(KR_1Q>-3*q&B|s23QXKe0<9Ey&r;&IW#v3=-En#F>qdV+q&tY;)a&eM_ zlqTxK9*s-8F*?8KVTiHZ?YeA3^T8gYV7Un?y>`O#!o(8n0+RrvlR|W6BE5~12=!|7 zl-)g}&Z5iUdps_Nd~9>D9~1s@2D&`xguGXt-c>lfp47TaJgIYzeM3n2jlqJ_)>Ll% zSGPjnpnv${o#l~?7l_J?wHn4mUqMQL<>kquo5Beth`jnNeiDhccp_PI-z-$og)GTim zt8byko9aYEFLZqceU!0+%m5q!!8N#_waKr?VedsxaC}>uxGEEIZhh53jd#_*QdUt^ zy6$q3f=EljQ0{>{M>gWT%Aw73j$f2no0t82~jXj-lw1>ndX? zAeMABjUi;f<$d(DTB@zI7boHP*OC*S&anT*G~9d|<@#^yeL&{#7AW^C{#$6O;p33n zl)G7@w~k(PkiWmq-81i|Mxd|T$p%FiRayog-gOvWDx*#DI}VW*EN!ZXkyOW9w7aVz zbs7(y33}FiuS|fR6d0EvHpn1(kHwAm;-|7@(o4VgpvCe|e3+*9)i0_|%wn|chBzM@ zuM&fGIT$tui@gHpfsw%ce7AB62o!Sq<$hJgc%^Ei=c~Oxj^*}sU!Q`j!aj->#gnn) z!Y0MA2`Jg{@PO7BA1U-@VH)VmSAtXgx$gDX;{l5(MxybOF9=BwYY!*M?@}ADk{Rk@ zJ$%?om@jwpVG{r?ME)X^R)$CeoClANhLSk$g1AGFu4#d4B zro9Z2-_QxN&IVKt)qlRm55&2=zmpd-(EGlm<%8OZ;l)%oyN5F94*{AOBi@4!kz;kB zd;Hww$%GP5<}Yi#6Z*1NN9F92@M40=+@G)2VYp0UoCs{Dzi*0v$P|Ppeide$kG$Hr z=PkIu)rVNsE2hu9QGh4O_{3?s=x6a$qbiDmw?JL|0G3n^1;MXc()N)Rbd{rTkMdEg z1dd9oe(xws-x6f3WA=VAuSL@AP{&2Dcdpn2hH19XqDN1}v0fR-@ z#HJ1>kG{NN1VTQHercfQ1iX^)f4YcBAkbwT5XQ z;HN)PHq7lAm!w>FeBX58PbE1C(yN#pGWdHTq%oaz7h2_a`#V}&v*4L;+WOHd(GD|& zH3KSyo~x);(B1+eDQqF+-6G%ghc*^TD=M5EL$euFSUF_rk96jbww6Z3sz&$q+6zxn2xykFfl% zKigm~2#mx@*H^_p9ro?cSs{Mdm=2z`Ly>dE7(%+cFYne!SWOnVK73(k<~o_xh5X2K zOrMaP!(O*=lMMvCVoJ{taDd*~1F3cYwG(A@h*uD|$35ZF>huqrdQD6z*!C+E$HAts zV_K~JgY^r3J{ZR<@AT*OtE zH3Ig-Or8>IEJInb8!$f^{6W>iP(c{NM+RF^H4DM>nkhR&@Cb7M`Krs1?Hv}eJw^S{ z;a&|P0&&%cv(@=XY4|PF{s6Gx1=wlOF-(S#N)dJ`{2O;T@@ULV9v%;wbbekNgZXiUlJSDdmWoKTyIKw}XzzwW~%(OYhJIjn>U$yKC+3)iaay1tPDM^x!zB&jkR} zD9AqChY+%;;nM_3qOt^S6zh2K$8dAk{^1mvyVLNDRA*b5!7M0chmcGH5VA&8E2n&r zfhg8NC69P`=-mg&y^#r&V^EP9K1#VO6D0UTNX{h)*(Ia1T12rn#3lR0;n%2k-z(yI z+p_}V!|JrGpXNX5!L3_d3ecP5nM2rtDO_XDBJ%Xpf#>`02kVz|Z>`JT4^|jJTRvWB zJ}Co%ckzWF!{HY~*b$#wQz@_Rd(ZX7PBI>+8@}=8Ck^Y@+Bb{Z=w;dr1~*?quE+Na zLe9(RZ7H0nUSVi?5T8*0(A!qHe#Y9%{k&-4J^YKzFF-knZ4GH~no|dcVGtY3hl7<@4r78pg}cYK*_T!M$%$ZbConE?dtiTX z;sh_)@l&9CVOc|RHv{*HeOXhnpUX9#J1raia@o4%n|2=Tnw z#wm(?{L}kkqcViIK*z# z{;k(e2mMx+k0I&;4+eNOhA^IX$%9Rx`T_Cl3sVJJlmzhN0ibwg=QLn0JgTmoYdXz< z>L|uh;`_dkSc0+yHGV@s(6j>h0Z{5^uY**=k7;!*e0d^Bm8LMQo#xPB5v3=&pF@6Wc1Ma&yz;2*c zi+(*b-&TIHV{}rU(S2-Yh$`Rol@tV(SxUb%__(pSVQ02RzLsHW&bREJRbD?zNC66V z%nCb$zL5kQr5p^fZFV@gi(wr<@Cj5E5z1RknlLdoKa`SNi*S+{G$53lt@@NaPW<{k z^4f^D%Gn@RGD|ytUID;b&01z8bk7==nZ*(8Q29{5FhBL1Pi) zf*cA^va3LRX<@3!5R`|EdA)2pg0NRFg0x&MTJGGU3;s%L!2@0sXko|dV6VXe;Hkg| zqCq5U5LSn4XV=QHXKUp_Ded>P>x;ETD_j2We2ilb-?hJv{sk^9nH&)8StNG&NE2l1 z<(6+u!TlJnGq;FMxUQ^02EKZZUa7I0K*IK zKpED^_S_jNluMt9=w&YoSgctX?IN75)|`=~WXwW31Nvzgu?QK&fvEUbFHyksXHg16 z?$R^stDjy4^hV~l-y%Q5&Gd>MCUDfx-MIpr72?Xqn0ZlINc$mp7I15()Zh%pW2U@STx{{iTB{mSxfx9>mhq{{OL1^85(!lc?g0oHuk-np3qeItXzJ&HKpJ@C6Zukt@oJx) zmD<*pu=6P}DT;9mdkC4(;UX7JIS~29NFj2(z0de+vi5ra&j+IkRn0cz^FBcEDU&#Y zhlk`IKJurr2>f%l$hP$B+E>0#3VFH|F!z%qTHHYOFU0OMFkO1C3rx&vLotho*g3`U zfp^denS@g(+hH11`AoL)%>{`qp>Nh3wAQ6%f^X2{^ssM(1yMFUVt_#86d_PK^T01^N zLc0imA@C_OEIM;7KF^HPKnNH^v>)>%{BjVuEYxo8S?G-|{I-6blk@rawtE_BpR|bR zf>_v|`WV1K_TSO zwd+*l{R^xPCCz(scWo2`25ER+s<#8bNXXx~%b`sB-BeBgq@uJ)E(GU~p}fdd@izye zuFG?5Q!1@F3HUUyem28=L@ygu>GKgkx0tlhVtSDLZ7nGQE`<-njqXIN#@};!=$_bA zd?V8JHU9pZvyre4P*wvN_8b%^{5uf(_x9)U#FwL@R>iD1_hYESH`rQ&yPglJkg=Gq zVI9~2fly4PM-VLme9Jvx&6|rcST_BCTf9vA|4dpsp=d#icR-v5j`dSax8*#GyG&TKMpbm2 z>u^gXG{E!ao#V&w={#<2Fzx{(et-!9f*;UXxRRr{X)P@Q{LkXbtt;I2gkEjRQkfgy zJQ-y~SMR-nktxD~ASNnF@CiUL;#Lb&aE2fuWFumB>njsiNZVSz^SRE{e{QX`GGzPX z*VDCu6@ZGY%m!2VfBScE4Z@O_6^Bh#InYXv?ao&i(dYOoK1UrrI%Qc>@&E85Ap#I* zL3xK4;=V8nv}M#-s1=~KNo~=XE2s-)#A6?R_{^R;=%&O@N&_sHN{Rtdg!NC`l?#cc z-Jmzx_#Ukk&Ck~|8F*Sk{Z4JvujOiC%BO+ulakM1jTdUWm@p-p{&JRFVnM0;bI6|K zLYws(DScJ;&QP5bC++o7FYaoXvKY1lrgkVo(?+`MpOmTH_nxcdly9tsYkEC|aX!(+B|BM)JC`ZG0NbF6@;bgddarnRe%t~=oW z@dFHEK}Mm&5N9s7hrX85HvW90$nP98v>jw5SGu# ziZO4JC@|Jng@@$2vhyph4LL5#C)1Vv@B#+7K7g(NC5Y6R5sYB!9reynUu`&V-e;MA zo_>w|QB-2_5>@(Lsx)Jgx)-3^9coE9??6ZqtJsnxU2kf-3pn>1J?;5-u(RCc)moao zoX_VHhl)V@;I9U>dk|KX^qADaIhDrq8)3KZc7>o}*OLDS6W#B}tsnSsu+KmV8oC!B z)MMjGS>;{Z{16~(_4H#Nd)4>WGUB}QFcWf50hMwG-{5bc|8M&y1tDcW zQYh*$m7hl5c{HOjsPWL##LZ$o?H4$>{kIXu!<2ftV%I0PgFLs-Vfiydq*r&$+SUik zNte(OuKPiZFIGW98FW7XO9-i$li0736#LYndGDM22m2h3jkiDKmhC>84}LiFnY#uC z3;y1UtQf+oW>a}*%KzYbyIX2Ge1mdzpe1yyV(x$gOpr&57Vm=&&%bsh#Be%w`3icI zw=z-@t&bVkV)@5EPsLRl4qmD+}sA zXQu+IN>R$-;n>h0t@X!XF7~fn;%x}4PfjTO`&!+frpkn^DYks-XS-JgLkTWl>Id3{ zHGkLyQ4vgk5Zreh*-=I-0i3n-CYJ=-Tve@W8Q-QXb#5G{g=;t^EQ}d{90E&x0NWOF zM5ak7Fihjh((}3+s&0tC5RTSMyz<$6r7Hi!j}lJ2&>B+S3)l-8#}rIpWXWI?*ybQe zUo$<-5c~MHswxcI7diwd1v=!m z&VG~YFHcj#$zln1yU6lhbgt5rUpE(NfXULEL=Bi56SgPj5Esl8FAy<$z!aDvE(l%P zDuMsCvSa)mhNdRY0&>9t{_A-J=gLIv^$s`cE4^EQpy%K5FCkRVVU9u#`Zp|>B4639 z=%~fBw>=O4v_HnMTII1#d!H?k6Xs4sbsy0Q|0jE3rWt`d>2aa!p#<+F&)>*YYqjVq z`Rfzcr-w=!p@~A}^}wJdQ+@_J3POgu6xvDc^J>0};~#2!CZ#~AMxT9S?kdZMs*_n3 zJvKOrz!a!(2pPWUXO(PsqEu1N&wBFy`5uFb=+JZ5pZ9&{LP*HD?*q-XzrIS{0%0S* zMwpnaop^?ivY!laK3y!@?Atr}v+Ob4kubR&zYI#PAz$U-g^*8X?G>g)6M_^{ju3?} z59?dKNA%~L-W5cw@Q4;`kpfjLsC}nv#Eb~xF*<7qG;LMns>l1PmW_FCjsYCPlVYzB zg5>x@uXnjHYY{GCjIAw2piEbXkow4^ogthCJ?MSYZ*8>mW`cIu!&$SLvy^a_sqtF8 zE3Kn}kHzLvE!HulA=CjxLtywq0KkaCpQG}5 zviMbPPa2-9zRoE8&CVG%4vX7g6K3hH6T z>OO%6iL{h!CH;jYmSq7zYGDk5z}bjiLXE2i+0{g?A35Cp8j91GjY z=WcAP8F)7Z!xn*Fn+mf%`0(TR>-Q&4AMGy3en{^(%{@^u5{?l>M))^5wIQga&3&>r>Bvlv{$q7DcdXtGF zl_7;f%;&}#K_U68U(}8tzjB=in_ZH;+YeiZ?a0G{Fot|=LCb?{2=aEOpbS9`$e6R5 z+$x=Q@8oiat9Hwt9#U5)hU92{41XE*+MBx-OBhBh#f8KelTZrECR&J$9>|zNK9F{E zZ)8bd-=>*wQYU6vca#{FjW^T#WmdeA@7l1+*ekt#@9{NttDo78+LctqM9|$eR@HSekTvsLhEIWvP3<|A>!RXEjd6?Kn zpN;2fk0fhLfe608(;lqv5Oy~a-lpDl!EK1g;Y*ro?l(i;;L!@J72}e@nBx^hZ8S`RrJ=u2vJ^)VWH3Xg zoRFFZy`&}EI~VW@fA8$_bIg1`RWw;`Y3+sXa-f0<*j54H81gR`Otm`aAjwMF*zF*{ zCq|-itWm|gAi6q5?{e;k`f&8I<`m@QWBdz7x_XAXtUrXo5hp~YpQ66$T$iQuWVO38 z5U!pSEO^~K84(1^9RD^7X#4|+v|<52Eh$(efq%ryK`pO*fyIu7!q}2_ZKd4e0&P2{ zQ!si9U<*Ue$gTrj7ssgDno*OWM?Je6_id&P-uVRj!D#*?jvo(1>a`ZFV1iU!JgUyH zC2?G$j9N%*JTwm%S`J6)*%OLicWVpPefPythY61CquKJmy!h$CiWLmo6%vjQ^+GUw zDcS|0=Qt+qF84T05jw4BEN&h%bQ@T`*>|ls1@~ah^4Rw=F4-8w3oX}pu`kuac z7jo`(jkYHY`7N3AR@UKZ@dvQhq!|S9kTw0>0)ZX?+YdT{^Eq?^)7<8d06+EOf)_vb z=i}~18R^o-#`X9I7x!QJw2|@!c0-Xo2&TiGMGO-c&LYkbxP%U1Rve4}7De!o)#Lm2 zDs7$23LI`KKK8uUPx(&V$2mWsO<|RcV31L@Mq#mp42D$Ka*k>{bp1I}HF_E~e49q# zw2Yf&Ki5W56=PdX<^EURMbjRBfwG70?B6&0H2DINp?Z+@ouoJrq$JtE_h z3S9rgJ_aGR#kJ4ErP3wK2fviR^fu8wST`1TI~L;*l8|111WK)7Ym(&4h%b^*_L_jz zh|3`|ARmTF&}|dz>K0B*>&GNMqOl8EeEE*rXbnD2r&}2NhBOd%BnSt77;_#%?S&Si zc#7!&CX(-il0GuIS()~MB2YMSb4i79x-DmzfX*>~w@k0D+>xmfkVOH^pbo*k1n}HR zp>{|NYQf@hVK7pt1+#~CXWb+)81!ElkYLj!jQpn!!&1`jD0QVT(S9c@(m_e4c%d!V z$8t1yjbuhGVilRy2fAYZ(}wY2LAt9wPUBPw;2#R6c2pky6635E_w#!{SM>3jtP@{G zdm&7h<-cv1Hni;fyYQ~shZ2n#W@w>JX|iv#!~E1vYDw^(wA zSy?Hoq#}e6NmlY0Wn^VWWh7fDBC?XbiBLi^-g7_w-%q~$oOPdb&EIuBb>M*x6bW1o z5NW2F#T2Lf$vDRIw97>;o0pjvK0mnX%V8CIp{(3T5+6)%gLn#%%`5^pYAM?AswHuq zLL&UiV*&>)#S;(S`)X_NLr zEHdw3^Jckq^ieL=3qps%KVc_Xd&N)TcU%BVowz;HZ9wb=$*B)7h1G3h@wF{aZfPGR zTdR8N^tu^KiZl=LKaB^M)^NddMk|Q5tLM7q=zje=*W}bMvnSQu^S^JA{@zx~6(8O6 z6aN$jUfV+v$%`6?*GowTekcw4Dpxow^cT+m@v~OVS07}I8jm}7I>#Xgs8vy*!7rLU zxXasn54hJV{k_jOP=5-_x%TM_U2U+2^~lpO?p|37X@I!M@Dos@_7gsuB)cR-AjU0) zvHk>;Wa4N;kEezVSAfTqQ;a!vgGrK=p$ik^k=6PKV(Jp9}Qs%>Ux3zWSl(!kyO7Q9URv< zeNMN~z(~BmnC^^*#WPOz@BV8fjQZ)3+0nlmfw?O}aTE32Nk-s;Vww)|28S!H?s#%E zU;dWh6#hH*>R5e9{Yy{pY@NHo;49g`;1vtB@rfT9)`l#75#<&2A0#_vBDUufHpD*= zDDpl1kw$IVVIGLuz*$O6mmoGRur&Es%wScdR<&wC-ixY)?ZqkKRKlhtPW=1M1lNFD z4SN?>6ukf$_nNaa<`}Nftj6o+)10#nv}>dM8u#q0OVoSUi*}sqRt-kTk5;!3t zj7O_t@hkGK`VWV~lwT6QkHN2PoNdXB+8d>(HFYR%C>p0>9#=H_=}$1QBogHx(4K9G zb%~BSXATreapM9ssaq*t)~9~c(scQ6mPJkvMSkAI*?Cv_${AjQy}Qc}Oo$GH+$YRg zTyy~=6P^#EE7z)zST&8jErZ9oT~fyh13Hw(S8|7JdQ(K|a-x!f@CHJ15?(MSG|Ex4 zd`xylo>{FNh6w{(I6}&vuiW-Jd;I}}b@Jj%p$?Gejl1Gx(h&PLdp0nV%>6~4{S8$p z8Dp+xo#d{NEim>}{^d&^5elLga25kYFT}Rl57KsSn>79Uxh!*~Me4d%q)1jcbya^0 z?dqwbct$|)rP7Dxy9tq9s?rgsA7?DkDfvHp?{|c69vf0v-=vqfD#FXDo3;ullA(AI zx(F?D|JdR-lk}1gf6kS3yKH2fEf5}H#>BOmMk(?aOYeZLasc9?k`NVv*s<1^M7l8} zY`4qQCF*DCjDHtO{nBX$w%q!cx~gNq@FdQ9$1+&J6aH|~`X;08HO?z{F79pJG(PaU zEHQhZ=_JkhLi^I_SD{D=Gk*eViM(KjzT|ac6G*03hx16U!PR$*N9r%wzPk3Ojib}n z?;$}d4Szf$)P7yWR@^<2iXDUt!PT>)ImZD7;iZ~)q86f}qpz&K5k@LCkF$j|7m3gQ z8r3qSuLXp4BxoX$7PX>=F$#oN3)l>c%)82B6+W?VA~*h)g{Cho@T3>q>@)}G*U-C! zFoKEb(T0s|nFJ3RVwwJuQ}=T&(*&+#O;c|bDPvOC%4gIO64w9BQ6i|UCXgWMKLkjD zc6js*LnfPI^r2Xkt8}B5Y!=t%mhSqYtTV>Bs&*igauf`j0H6_@CQ%h!`+T&b1hc3bdAwj!%V2B6Ui7Ck zrUs6x3Q2hO{Y5q7;I*)X2EevM!z*#D`Yz@MV^x zV|jz0oB32yY;$}gb|`l1Jcx)Wd8Ioi58QOvpA>OfKtmCOF@4TZdsopXgkVeJ<(3mvj{~a!#u~~;8aym93_1|gX~`~z;NK4H%Mty=)a?4|T~u>K#K!jf zA}JXqytXgEJ%vURm8Vn}A^1c^&FkC3BYJmIYd(&JzMffMClOrbP;-j8t3@>3zYhF! z|H)I~BM25dTk2eWuEtYGV);b6YMq74)H!8!ujt@h{YbHUFdO!|jQs;55_UdX;>X<> z1Lf`x^52v9sj1?pE8jkCyq)Xd;vvL7K2uBrD4+k!&rn~6qbk;Hr(LYSNJE$2&6x4E z@EhMkvgYS23oi5P%eU$TUjxMrT-=#SZ)PkSbK1Sb{mxsrWiNtOQK6oZ#OUb=n^taa z-)@)F;VMiI5D^}2JoGCH@xWL(Ip)}Jo68gu)OAx|2Pd1aNC%Offr>WQye!ykLar|XJp_gLupgb!uCxtLM zxur9vYVz?W$RK5xMp(dhwAQjCsqUSJi!3=ej=Rn`i|G4pvKvs+zEf|gd^hv;KJbFM z!YwE^QPbIglv>}@h=#(Uw!t9u{JDmxc{VLi!uZB?+OesffLvh5`Y-*BhcbN(9o*HJ zcFXwlrm4St?WtTWKO1n~=m9osI+S7JqYMQ&qWvfAi{Um+9*di`eGTIIrNmZQnt3u| zDE2+qoJ#`N(h%UJB}acs_M#yq5}N)yqDSAi)M-=rd(`!l%HlrZJyqKzNsY zz--#Ae5((*Ala|EC^1un)zN)Gt1BxO&vH2vYj&I=${o=XAvVN7^jrN&f z?syMkCx-{}QQP(c32E2}f`NV)F}U2uo`#51wi8Etd&GuvTyM3?dQ?#;-@oaea&$y0 zXcCQ)4IQEeC%nN8QUqLvPZr#UbNQ4Wz3kA_%^I_PLb}O)=X=`iQAz)G`lkdobbe+v zY{&-%eqwYpoiIknO^exnhkDA3a5K{ZA<2Q-Ce^y`dY-q5U)?EWEN>U%XULO}#J7AA z3HW{>BsXB_g|Q_m`qr@a5~YIJ^}9Mj7@u$aE`GH%sngf_x$5dwy#s8SfO+k|&b{9bowQK9-j)3}Kj&i~YyYVp*l0rh2JTCc8Ng)yvqs60J9|Zc z1VItC2X_I5(29o4Ub=B>PQO4`Lmi^>{}jV%C|18=PS;9&L$G*o(_ujc(8PK7ikRh` zN%Sr${%y&-1|B3L^n)%==UjTfA}}!tbb$({7LT779+ZqJTvzxEOJTS}*D zA2+q!jr{e%Zv5@8-r%$H*k+(l2J-PJu| zf}ww-eIYu5cnO@Nb2511cXRtRiMZ91fpOA zW#GI+`?fNn0+UX`ZO<(J$_wP1;0Or_5%?JWoN(n-ATtC^cW`rP{{)y6nJ@^Syj zC1r5pjASDRqB;KwGnCL##F5Q{pMcykqw#xG`tJ7Q)Ol{F>X3Bmh#Jz6UR6ynh>IFw zi7*gbsxdMYn!+iYLpIb&5P@C2aFaH}gGtsPnU*MNaF`H;;xd~U7%e3B41)drD;$yX1kb*1dP@aIje5;HGP z+5ofXG?Lj+zEg+5mvFQcFe@(J{)jH6*hoTQephHA- z6^=W8Ma!=S5!`xrwI%3$+GsVaIm_?Z`lnlm2RFU+TcyFl9e_}vG)aCmEI%0nj-pe| zl2%k#aH5oV?0iDA3pNX(-6FySm#{wCQaQ;*Tn)Ri&W?_a885eO z)C;}k(GtXK7kS77ylN5pOW6pmF1-8GOxDhJK6%BHFPyAWKP>PsR{7X-J#m?hNT+SR zUL1`?iQoZgRJcTt{Bu3UCSb%|G7kRhoE_)sJJJHY{#s=Zy=)mHmXyIUfkLv1Nr#47 z@abTLSB5_bl@;7FIQbs(2@Q@7!i~(YKVe?|QNDDo3$ed1Y7K+}L+-36gD*BedHavD zH-XF|h=VQ;Bbu;XF29oSiGL`C`S51?tVylMBii;Wvzhx%?M7ODMnA5AQhS^MOX3K( z-8VFzw9PW)?d5fb`|06<9p2rWKWZ73J1q4Zm^6Qa_gy#%pMByKnk&Wpj_Zwl#I9g( zHHoF@iOu-lO!PCsj*zR&6|ZV~&@~8T_>-VvNix*z**ARqI53M}###QNg#680RrOIK z-{lB&ECE2`_AIJiTj|-Y& z%76a_dBF&YB-BdeXv_%DcMA`5*Tkf&{vm5`>VAyTWvScezaCdDC;HXhFX{rbEGmvz zHcN;k#b09>&dfQ}z16VSa?(4SoMi6Myd~;Bg4*lVd3W#GX)>(IdihtNiJ~wYH3hL`q1f z8oEtx{n0PO`jbG zP#W=3K%bAg3dRd+2lz*%0c9USpO~0^o1tmjdSmeb{OL1_h@Ydn;<6t9g#^RYSKCKd z)(^UpP=^7Hxbl6um%1U@Zp}V&HtZy`&zg+E=JyAsnP;oKQtwzMupkrC|6JN{((qCR zAVt#EcsSCZLeq!TTd#5^WjnRJ_C+cawXd#zrTpcRJZR=ir0c^A-r)nV28B2CB%DN% z=Q|OTPVb1vg=4)*)n5z%LnVaJCUvAZSwmBa%ZGV%8_ z1UF3;Lf8istYG(}wf?5bRkE{^xRI=XH0UTr&d#OWeONzLGbsquxLN&t!isRwiEa-<@J)6W#n7{XC6Xe4@ad&?Rt}7`Fz>xpcFC5 zmlmjKpY zsDedEAzS4#k!#4bsiDoG0_pcp1yyFp?N29TA2mFFR`kB-E8`T9fH@bGRl*$#588MA z>4mgD$)ni4c6^^RgEK-hHtf481ZlD6^ZhAiZip5We|ioVLJ$aV2{4!TA;OBo)m)bt zJJM3LH~Osi8{hdod61s(SGnTZzN=HI&N=OIyWmI{A&7-j5Ya+#aI{Ip?Baz?kGfQ` z_`$xmePKx(I~78Xj~w&~^Jc-o3gQ(x& zVyGXJ#>QC?luYYmdX=S|`EuzVk4S@0X`VcD`y<)G!Ln1}GdGTyfzJZ5>Cu{Bbn@gE zhfnSNmQwrqSBtuq^ORz9exRh=^XxyCV4MY}uh`7tb=oZA8^P}y9~?%`+Ev7HHR)d4 zR{kYA_NR1C|9QqBcq5EZIHIl;{$Dt3p=c7wKQTmh;d4%bZCkZwneN|PC2Lf>0jcUC zi_g0OkJ3L&l3*KxUt_YRPdEFoIdR_%zgqM;BrQ66VF3TMnAp+2Gpp|paB%{6e)K~S zTeo+jzJ3B*+VxF%CEtOErpGsseqX)i50AX$JfaCY|L(sjyjiz zfa3#e1Wgo)gt)}UacHfV$hBq1T;v|FHWq!2VZ1OUl8ZCV=fAUG#-4;rLYn_NyM4?% z?bYYK`_zaD8~=K|=JAB(!^6D$M0c!LM3Hk61or4ZTfhnn?lH{ZAk?4|AL07mS4Wg< z4W2V*_P=WJy6AJi=#ixDMS)v=XQwiY!f$;C+phc+P}q@Dz)8AyK%-q31qJOZK{LwI zKK%xLZVg>#KCic-{!|yGgOL@s|AK@lKRy6+aUTu4qT%9CD@TRfj&qo+?Mvm-S%mw> z31pq|c_*crcGYb}lS;r8hU5mE1Purc7XKFA5PN3BaYXrJj%lRh!`wETq|aOXuRJ=> z2RX2S&l;eaS1gY^1P`Z7dgf|Xoyaet$~v)o_-udP7y@NiH0+uN zFGFgstu@=D%{_Yt6T$*Lli;e}q=Uav!J>l3%p&0lqJd@wUnO~G*Ghcr)UbeQ8EtNVqn35AT%wJu|k?vxdO-XSsvex)-rQL&bd;z z%=m1%^uXlHC3_zb7Z!eb^wck*ap*IcDM)$3NOvv-gihfXn*NyzVl44&F=@_u;r1n2 zgoVB5V~cU5h}mdVCgMk;hFVJ3pnIW@3`^@Hlw_pQOFi)yMMw&;1*9BXTVI~$4}GoW zU2Y$pkJA64+rdE(@N*H8O?WiaRB#h3@|LPW+b83kDm@ABcEu!nMa{mc;I$v)-t70= zQEvr?_RzWJMQdhOt)HGhnR&vqLO!-0VNtI1&m&CLwR%LCl^V1AA#EQJ^Z`5g!cRPc z*k50o$)B<#Lh(UD8?P`%A@A1C&P7J*vdPLFn$Eq4hGRHwF$dwkOPVrD8ZKHCuKEh=qG%_iTF#NQk^k|l@St7 zjf9wYywVRO%-?$165hQCiqqI#F+!gyBS=FZUCsHZlkwea_tgmx5ruA@a_$E)tRg}2 zrE)T#FKmM^DY$)7L4i%ooFlZxOij-6D4%k!LijZezsKgsfVt<9VgB!?K1y!@!bQ}U zK^Q1~NTYd1Q*u8&UE+Lq=ETxxd%8cPvWAgdWTlth)fl&XrLBOTHI8la>uOCB)cRDYR}h#0ax}e3~zT>T{NL^`+lN!n4DKq*|l3S zi!;#=M?dS$Y!19|E0f_o${Gb`Ya}Qkh7k=(h*6D~_V@R5gzy*Nq<`z(twmrv9sXXE z>im-`!=QW4AkhpLG9;dfin5`QOn4ly=}pJ@&?qU0#w%c*IdrWpTaD;2X9{QuWIw?2M?j>~>A-8L5}oPWoiZ2Xg@hKX zx15Yw`}Y~oovb5lyekDRv>Z0q0en@N9D%5K3EUs z0#;J&F3lWhzQs!KQC}?QPU5h>Wp26Z72#!vK%eKmoQLyGHAe5bwvqF!IR6no5Np=| zGId5cdhruDjm^!Hog2gZ-aA*CONtjJ+1EmbhRrd8H)7uiHBfl|0QGtx558EUvv4Ah zTwkt=lWWo<*l?Qr-)7!!PqP<4kE1RqWMgPp&&MLFg8yW;GORR#GTUt)%IuRUfz2C_ zJJ#J&Zt2;5PBW!dg;Mq)sijk8B27Vfe2T8p4}jcbT&j$62TIraKI+*3NBYjX)}u@v zuV)9kzTmxqOxh6Dda5U1Dj1>zxOxy)Gy@atX!JE(yxXZ`Ev)L<9<8ifwO0!L?@@ZP zC$|^a$7!Lmht?R|99(+DNlvrOIYzM0sdn?;llnbF#)T*IkA8@aHlFgDaHv2S

5) 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

Y72~q@aS% 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

ZnV4CG5t!6u&DWU&JQ49t=!CUH0( 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

*5`+Q^Ix~Rf_zFzfs7o1HtDI7r@}X;!vqn zKfD>h9w@D`pW?;+VXRKG5!vG^wPN=@v1BVD2=)v75|QuTjfuZzzZURBe*8`2ash`% zD&=q6!8iDZApFwwt%u~k>#>?=|#f1fJ))~>m62Q9Q&pe#!-Pkh7C?y&Ev^b38IX-so z*FWANjffqohKcatk!#>O;pMqEl)BWA*Ct*P>Ub0$mPx%(HK1+(dDeorjsjO&V@wLT zcIX!3vi8_>FrLSFcgNSYQvab7kBMRYMDeBKJI0%z(R{hUwL)jKHN>=GP4MgaW2EPK z!OM$`EhL;dR{i({sF+P_?-fUZYlhCW|ARdm$|#EO{1vIrt&K{kN0Y*4_C5b6YK-aI zmywLXH9|M6`|(O2FXm3p5pP~)+l4>xM;X?SSTFW(~h^f-*wO%VNGQ2lS)!%r$YHhQ5r60euqx_TTbG>E7n!hV*(q_MtK%WtPt5C zpL{HS*$9lwo)54amH~GtJ#y)cvbY?8*#E<(x>o0Ami~y7u19hf-lmJdZJLRZm$dlZ#?`me zFG_`5Zoic|s8kDJNQM$u>d6LNhQ)Y+k#*n91B?EkjtcJ-Gb)rjh56J-?mr z-@T!fj&fQ9qcy%)2BW2rjg8y3q%BBm8tu&sCpE^m+67mt-}|qE2s_|g zV?KR83Hc`p_X)E5Gu!S&r2MXgSg z_Q^z&Uf$di5j6SylEs}<3@1@o3P^>nrl;bI^oHB=I{yA)zIis?_OVlnj_oM6%XTU6 z^63|N-%o~4m;bTYh|Uv&L?>bilNO$ipjnNecBZBoD~3rtuVy!mfLrSEdN9zEWlyV%XcT*XuNL{72?BaN)qY5#9f|-sasd9Iu(3Lvgc6&r#o$ONJr;%Xy!Ei1}7%7xunT zX*DOCHy947?ESsnnZ260yU(1HYmQj!I!Hb{@dt~Eh*25@Aws}x%}`d7$$*LUKmo;% zHWc~tZf=Uubv*a8(w1FZa;1M(@P-})Z|Hdb57l_RAC;Od?mqv8q*N7CVO;;-+nY(8 zq|?|!yAaOS0zm7WJ|o{3F^!ePqR`S(lw}FtJ9racghbIUmOuATLQfbUBs_j#Cj#%x z$*PIG4Hma;=So(e-xpzy0`lVKT^6PQ2GNn(Ze9@02li#xs7;jLl1L&4Wm(ckFEbe& z_+I_-U}8+)AT=j?xsA0CoEN-y%gC>q!{;d#f@CfE5AfdzQ0T7cQe^0bh*_ZRUsjq4 z0OtYSQDffz(Zkm1o72{?u~0idli$jgqx%_F#J?Oi5ucIdfOCTm#XYQf>8)hGj2z2o zA(61CayqrhuEXy;_ob8lGlPzsfpdXQOP!1UTS#P9KZTm)FMF#$7mQAqv0eST`>OkP zE|V6Mz&Sxz^)w|uYvPnsh`Z6r-EwZ_Q`#N}mQ466(+!G}wwTs3aE{PP@Yc1y7$hGI z=h&tc$Gs?sc*b-0W_--(pSmPx+{rYYuz!RuQBkE5Gd)f6OG2|)!p@NTJL*H1vD#Ne zPE%T|ZJzF9z}Z1(VZZ)-89naUTY!MLO2}4m?y;Q>omqB?OzB(J=pQzYz}Z6QF+;1r z>pK5kl1M}L>doIs1q4xTgZHCmv0D7scuXDcz*z(5Cf9z^p_-0Hz3lZoWg=8z>RpDq zN1Iznhzfz2ZTycuWZ3uKNuxMfaTX%crFE^gMZ~00_jIzh|1*1HN&K#Vws6bjL3kb5 z1ZoNTUdzi#n#3aRh=S+e4vB-P(F`-}{oVNI)h4w^UkB_Z!D4_p?0en>H)*tYLb{6k z!kkD9< zCV{91pT* z;(Wy#+XpgigfPMCrH;o)6|woTD|Xja5nfPM$)iBvG@;vn|6Le2JNSOd(F@!y`NU5> z&h)GY7%ky%nYy{3tsB51ygGEEqEv;y2F6zIEPX!0xG9Y1KK5~aY(x^h`8l=Q9@D)R zI92Ed)Py99J>T5yanNyJ9DF}7qZ_T8*K9ApsW^Jl@#hGp?<&w;1d1u_1^tSv>p-{c ze3)^UM?B90gQOwITjwU-PyX32;NC!|xzfiU6*k$u<&tzvU6eECNVGZeFqe50K_UFN zWtqePI3?(k-2al0r8^-mFN7QPUWt0!|D%_UA~&&oK^n=k(FH+G~0G#u|t-d65sR`wgyt zS-Gym>_`Nrz!9(o8jlI|S{O$^0#{u#h5R zWg3OnBJr1Dz2YTwj<)GvgSlI3ts*)w=y_$=kBWS({wZs zc2)?!8RJ_RKWWCh%^$>T`W$_X*pB0tJ(aTd295{1r&1sB{oc(8ZnOxlc3iv~>3H}v zr@eM_-=Ykc!-V4xteJ8__u^|Lu7_Mn*rHt6J8njry&sFGywzh)EPZHi+J*N0*noQu z9hJl1@m}g}i@M>EMx>}@r8Su;y81VClCRZJnF&09TmZ)ooYR!cfCC*^PICD29+})7 zd}l!a_F1q7QE+Ux(joV<0@(7wCM_3f?AG~%2v;Ix^>18IM|65@zvgU`Cl%xo;a%SH}!2L8U1P6G%@>5Wn zE?3jF=r=~@-}ZeaM)OY_t7OP5TI2ZRp(`#rcMaScKmnVF^wq-;Uju<*b&m@L2eJ(-# zRZqh4NN>eLy6Oh6jmyiPOznVQH5YJ0KM{0gKi4Ard%|{pYs=*xkA|IH8!*ZolsplX znW86QAq!jujsQ5Pl{m&j4Ci2?=(lXPsYoB$d$>M<5dKFL>Krbpm`XSKph zg)ukpCe}Q{M?$71CI8GkB zP4V+Gg%ceNkfWGtOE~voFcOF)nVvi@(G0ZUStK217T}Pe(~@~Hi0)~gFkz$e?1#v$R~sG2(3+ze>71&He#e212ynOh zz=fs`MoRTq-cKZCsZP}pcZ*Cy!M-=}GZ%rOHE5B_x5(CIXylNx_{B&Nl5BG5=3 zP^N>cQK8g9H=I7p+~-+yya3!4blR%s0?3rRDt>Y=9$VQDCm>QtbBN3mc5rz}AIG^D zWCM2r9R`{FrpUNtT|sd)_dt}9bSQE2SALbs@qvydHHW1rIA1%1uIPqT5T{cY@uh6n zfEK-F^+9B3pwRplRsfntO#mwe%t23~%c4S+W^s4kp-w*7UHzrJ<>0$)?V*OBbPs!lCmIyGpr-%-Ub`Iq@-<2 z6ti5cog4Xf^oIg_!7ef{B$@1D!m_717PtfG4i+O6yjFSM(0rjFbwjf&s()!o#aR3% zUpujcW<2x*oWbk?=Y~X4M_Ay+C}wZpHMpkmGV$BJxYw~`1)o6wCuO8mn>!@U*5QsgmZ#@EpPa_}sbpU9z2E;A9? zlBgTFb>N&f1LEExOQlkC7U$hu2f9=!zE5Ilai*4VxH7m+!`KBIURJ@TC$i~^)2< zUM?F(ZB1(Lh~DLw2x6SiF;@$d=+{PhaJ^tzA9UxnxGh&d<}Po&9m%7K+%F%AejzUD zrQ=OLv+6fS4h#h_!mPE*l)Vc^E0+s$J1HxuP;!Aih>+mQb22+Ms9X);6zU))zj z;dID)AGlHIKDgL*o3R%tcbUkH8H9=SKKs-p{575srAQkL*m&`*uhxPiyUS zFxh1Nw1V8R4VolDobGTpMssb*$m6w&u~} zYE6FlLfB8)oJ{un6sa4ddn&9bDGn0AyVhI4eR^Z<^iZ2%_G*#*4HpCbTOD-ua_?9X z_nOUy+(68;{yQLA6YR~n3=Rw*90!W%lC;legDI?0V*;tCq)JGlJ|Fhjy-8RCt^u}g zm=!^^%HbN(Mj56WZPQ3ysn$g!v{c-5q%V8deNOlZaCOk_EA2~45)X*Umi9cLc|5Hw zxbfDB)WNi{6nFUWQ&=dRCDy>RI64@m3gv&!+?f~7*4(-c>KesJU#O4s+pa-Wc!m_`&Pw)wVN0QHBxlpVPz1m0=g?<#Vmqf!oQLY z*C<2nZy$#_?DWRl*p{l&K3(a{7d-*496FPT@qr)h?}Y*xLW_fbJqy}$&5|x!eur?; zLqjeZN&E*~DRcs6-R(Q~c>nbooAl&}&baK6N~s&sZ2J){$<7GGq?7?y44hli68{j# zika8bh5NE8SM}WicD?w@_q8pj?1c>$yvw*?=lcd;Q61qVw8Px>j~dM-vux7BxRQS$ z7cGUjW38)Y_I}Sw7u?$O6?Q&juk<}_=_w9=o+_i2GK}2k%U^oEWEM#5vEGQ#(uqs~ zmk--F6dZvqvU<*#XPBY;7cQXtr$%)!**Tf>PIN7F^?cx zfBmc3@lvKvAGj3YocN;%kca(3F_repGKz)VNbfiMOImq_y>&Zpn6>OTLh?W)F}XP9 zHXa?lp4!wl$_H~r4s*p8GHmhS0Y!zyYzP#*S3caHsIrL~Uj_leoc}1btBAl?(awYY$rBhDaUT*)t*C2fc zi+CI%ibu)|9c$(&639f+%)eMd0%WQ}@1ar(@DPXBox{x)!TO-?!oiVXQO$MuuV8!- z;aX7OH+`VXU=^J~v31DoO6esAH%|q^)*Uq`-dErnpw3qrG_?zP>?B8Xy7ma&5gVsF z`&+GiN!xRTKdAXds3|b81R$%~d)FF#qn=+Rw)|P4%WUi4Jj`X3h)os=qWQw%hgPP| zQdoiXB70x{Uz(@sYhzuS@MyKo6mr|I46|bius-Y!uU%z1qiW*4@9ue${@jf=!S^mT zBk)X)Dl>Q@eEs7K8DVwZ6S`MPg*Hhn#8=x2Z;w~*pLr}ir2eyfCB90jaCe-RAmTf4 z?$F_FiT_#tg}D^F%j>3mkKKllnfQ&$iePDly~$E4$`b@|uF(A~&l6+c2~oYQb98)h zMS>YEVxw-9Sd3m5{8ffB?*JAJoS`EoEnR+mrFm?s_zCB&Z*mC2Z(k_EUtrZvazVB&Ptcic3k=*NHL5DwemHa4-B$G^O!M;0-kN-e#L?2l?dLgg4$zq)MCu7w!;N{5 zGScsUJ~q`fyL!OG%Q!!`+{WTqG^qrfJ#-%q%snK&xM%sAU16E1qHmRib-40UqP?G@ zKk+j0z3~C=19bdp4?LJlOt<#DBt9+H9cbm2n76Xk*sWQlpJ-5O&=3M=1D#kLuH}X1 zZ>($rH}-P-)^ZE(Bt1k<~yv z3pnoCq}j%IDUBej-9Hn#JP-Sw%l4zlFD8lK z8L`*_#FDSAew~^QVn0i1h^=J|0L}zD4Dpyqc}g!+>v?BBBV%t=GWFuk5iuPW>xPVm zThb~4;EaHCsyG^tw(NR@GAe!OIc@yz@8#pW4;I;bVy3%-eHAi#as9Co26x7s6fCW; z>FwJLso%Ht%)Qm;ya=ae(b=8K$r0>oEekBiMZ!erfsutw4^6p3`smG(nBcd44y1+= zDiI&~*TQiG^`gB9&cQrzR2?|79GVcAD@?143CBN7{r(!=NsB4HL|qL7t<0X@-2a32 zI&fO>EZkCX4wFOo%B+MEZCxKpD2e?$w+o^pM;$)6D^t?^&lNZg=uo8ZsT}L?KL|18 zT6m$?>&Ln5U>dg@-K&1|1WC@=%@jB_=%VWPu*3_DRvpjon4Pm&q?*LZ`b%B62;+0$ zRS24&0ZGqPd>j0uqm5KR$|1;W8z12*Rz@?XL{CD|P_kLr{qoHs^hhq>CBVSWh>+^p-D?-PA3K84as29BNmUu(z@$RBF{PkJn?57T4I zN%~)eZFJeOrmfHUd4_F;UJ(7WP6+uuoe?yo;}jbV4lk__(_^KuU11SSx|)D-SiQ~e>&x0GbGxf3+y#%A);O~hiCN$TpsP6u z@--$^j2p<)coL)h4%tS8GkD{@XB~^CX?=nWYC3Q)q2uO~ux#!z!`g0QrneG$5*;DZ zcd8J@Or+0oD30Ne1BcWX|Fti_oO{mx*Z%4$eci@U%DIMC&VjcmE$6IO=Y9q6Domq! zpgYCm^=X;ruy4?a6?&|z^;Ij#s*T6ROYCTkN)_TP znkJpmZ>6+ejZ3^>Bi7Cx2|xkvIdqXDH*aVJ{hQZ`Hwg&%QwmL^M7yW@q=QAI*JtKx zSml9Zhwj+uckClBS!ta{q=tUO9@?}CZKI8gw~9Zm`kwN&%KZe64Lb8I68C+CVcVwC zR!-z{Up&w1ed5lSp=G`jB~p*0M&f~E0nSY;;^nthY^1}AmmLcExDlGt1h-Te?=I3c zVlFC1m6d7WQ27)rAeTS4;dv1=hn0#NR{8ITe4xVkh09ynQ6~TO{VHktFL0rP2@aLq z*UtN6XucV93ut39kNG0xt68P-yK+4H&^(R1D) z`n_$tH3Rmu-NC8xK+B>Zz&(O)@{?~V6^+EaT>RGRXY;iO%}tEBy=;_alUVqP4|5mc zf&m?LyxjuF`Fl!F*71^*e6jd)SLFLV2YOo4e8yUur9z)60!IrSS!R)cKT}xdP%$Bj z*33bW_bjIp>xMgfu&DXnzaA2#z)?d-tIFM|Hq&r;_*6fVhOUX%6!XP<9?o9MdRfk4 zEE-)n2vR{;{oFw%=;*uQ$cSBAs@?ZLb40W09HV(z$t)+mQIWge zBh}|MlhT$o$Dhrk1=Smj;vz9rhS%C314jm(*Q-Y4jll*IMLsHijI;0$?n5gR{>2+Y zx;;A82zJjE;O;~BefeJW@eCR3{Xjjm$=fHkbPS)by=g@{%7!|LLyE58Eu9#;A6SS7 z9d!PdOuxLEwbqcoEzLOb=cjTj1Vl1@j1HF)0*(l}!I9D(pFA7CN`W@z*7HZEj1B42 zX^0M7`;1`IUl;^%N=yKqt)^6c_|xCwdE}MCZEhs581Zc*tyHKDst0^LMpAk#fWw1s z{_XLY{ZPVyAI}8#=+e0(9qPZYKgNg)X8TbEm%r4&`aTYDZdiP}-);NNnu@$~0>UOk zI$ke+QZ&9{i{e%X>N%QRWHv&CpRSgEV8)*n;ef#9mBf zWiOn=Dcc>`|Nc&OEf&wXQ`b6~xVNQ~djFg%wr}gF`oW2b zO13}iT>N?S7+t~y2Gir3BxGr1R%&ZUHdx+51I`HrGn4UA<_mOzs6fIaz49D!`(uuv z({PiALn(Ymwom?hp12@#u&Ud&t9~!(j@++1q&sduZO6H*#}&oeUe;PKH<=_wK% zO{Mf}L^Qbs_&j%cq^r|ZeoziXWG;GawrkC%RLbbqOagbS2aYNdQld;Q^p^JiF!eu$ zi@}6UPsOJ*UDc%V3Q2h)9DKB;sMml+T9rq=N*mYLXu18Xay%o27W{GSsWtkg(QXyS zQEd4doZDYPXY^XgadML~Yblp-%Jz+8G*{JkcBkoTM?T*VT%67R&cIzj_dPc9Zs~d5 zJRz<8xTumA%Sl>x#IchL>QR<6xy9{+YT(YGJ6^`OR>}$8-qX9!@^z`B08t8{6o;se3Yp=GZaUrBazFoFN=T=jZ%I zHPkTiOJdEZh=G^X6^wU&P|crQkrn1A#dl*E!9Uv(bj?$;lTx69-oSzvw>l~qY=cjM31 zP;^e5t)xFD5S^eYNtUB}U)+FD6~x=t1D$W9{ehd%0-uYDxhO|s&SMW&d<9kdW~r~V zl^GXqMu#v@-GuG?zVUUdJMw#Ur3v0s@%CiAQikTgN*3)+Rz41>Ki}#^0k;layhYb| zLB}Uy{dMx34#NHNw)!u`eBySUjK8 zS35Ng&n`tF1 zs?9>jXMOGHX4r{T(XHD;_EUTig;m@(<5?xk#(L3ow8WYyaMRF@BzdMV8h=WxzrHBM z;8#MJpFYcbabs`V!rP+L^yo_waFfvW{^=sKs8A;?t1#THCWJgv=2QdgE~C(iD_Wh2`2JG_ z?@V%2v{vyn_b8i)-^P$LJjvwP7P0gK?gw-Z3HUKAw$X$4r8s4NVJSMZrJgMJZ9LO3 zxA*uRxr+pgYJ(b}|7m2IaBR?_N^a{|2c&R++WChnxXo3m;-k>uc!9O{^E2pwsQntC zHqECz-15Scsq-TdA3Y0|@P6v$y|g|IoUM)$vIR7ekY^xZF9;afo5^{qh|@1XKJ$}l zjPY`@jayMYNu^`t4_78dW{_VCaNW>J(X=80-eA)v0Cs2ei0ihe=pfg5?-7hLKJaoT|ZVe`cZm6Y0lXncL5X84vN!EiiBl+ z=;=uNhIq!czXFM_Fhbb-tVA5I_@22O|Hd;0;aWAo4&dnt>jff(M(ScGz3)%Vr22k^ zVY~@%tZUI_;ae|{S;FevvE4)y1 z^Ug+;fYvbz-!AHWcz*lYOSVH8oAutX!mq?1a<_LT=toGBe3T#TMq-59e!n> zQN~hwT^&}98fmF8h*zKi#=gKo;Q>ZYR$(1(m#wuG?C_5A{$3?b;$*++IvV8DAebNJ z!L!wJn-%#vfZq18`BVY8EO=E0Umksv`&{^5na!2!ku>htn1*x>Dt^M37rzPu zA1lxd3dnD)4hA? z>xf*5_h2#Ntfx^PPM4CQ>*KDqxjPrVTh(rI&!-;CK1MZJce^Ei2y43OhWs3@1Gq%! zba8d~pML#tH|QXkKbQI7wbb4wWmLd6{#9dO66w!*xZ^G!I@y_;{qRz9wT@y6rQjnc z8XHW3p;963c69an2j(LzuyPO!U1GqBp32=j%(+QbUoHf4?>-ofc#*K~9D_@}Qsqb` z1GCy_=#Y7TrhTIc^x+D6OUN%nRe0sA={_ydE8%LbVx_eacLZD{a85`{QG4rr?`Uh( zQQIe_NL5x$h0JJ_*y_|Jx;~ma-U07=3kPplB913`?WV_w^O)QkU%}wl$g-_kVGet* zbQ|T%ZHL4>ZV)XL_Pvu1ZVUURUir7ClN5H7-BIpUiSrB3TdfdHR}AryR(AhajvN}( z$oW4xa)<`Zkr}ZfZ0-qA>#jD2+;QrRN2^}-eXbZwZYf}Xu+y|uZxY|~{&6KqCoOn-BB!tC9Y5lXc|C!?c{9LkMfn*x zA9%6d9+*}LNwLzCF58_<(B?}=?@|$Jyr9+I(A2xYdJwjD~@+Bl0_}JRwBC5JYMDgy9npCQ&&u4 zGt-M`%@b6Zt2#m#p-&KRc$i@|amnyP6EQ-P-2OmYQn^Va*2m;d3o3OSa37)5*s_%n zP_epuSt{frGPY#*>3tNcGVk0#8oh(}I@J!GuGvACI?*)boQ0h^`5v)9VCSO0o!*p& z^N^dc>T%0VAYUh({@FtJJpaz1+fWSlKN^m{N!b?R`7dr!`)6!v1o#<|ADXLcfU}0K zmaNX_PN1FJNkG`tT=x%5!im$a>l|aM_uWEH>B^yfz`X;`i>}`J+eZFVdISlUOB1(_ z>p#p+yi^=T?U(D@2E*Im5eN=2R$782xoRG#_-Uov8JZID4NZsQb;}&v-w@IAQS6_k zv&BMlbs(TQ94l2nWd1-ZyVv+QT}?Zia=XL5A2sBz`_w0;Iflb>cN|;bOko2Jy4ART z`)p-&c5~6Se`B{{E;5qTqtvJ{VXxgzkMb`7&KSBLC#NDuqe0n#?ZKCfeV(tH4)NE= zQI=lwbBubf1^2?e6Nb>SC!JwWbpHOJ|B9LM_3pC)%Vne(tdQRg+kvLHvP6;9!0AIL z&~;rKFHDp3^6Lu}g2vVanZyE>S%S}3%F{LdjawKWfzyR9|4i&lxYLW)i9ZXUi{FmF z8CAXzwL37J-wZ$=(Dh@2#UX9zK9Ekz=wvAq$PO9q7FGyRxmrK2+cxt}o#Ap8eBO^% z2An2zd1&`u%1-5=dXMV(6_tNBq`^!NdoywOr%@a&T3jQC7;x&)VPO6JCz$#Zzp~k? zC7X`I9wUNGRAlnKP*ODsgIOOMDsZaM5mW3tn{F7;?aC^1*t%}K9oCL`YpJs{&x5S_ zgw&~Q2{;w#{wZ>tgI5rFCbOx@Aw=G=O(g1UEEO@!O{n#Tc&aVKy7C+7lrFsP31(HS z8H%ojUCHY^%we%(JY@x*EKN+kBLuOYLK#FH6d>1s_%KG_PY(>^k?`P=7io zG5lBhz%W5T7B~gyJPaCnYZEE%yTrx>>(=Qdbyit)8Ily?KGT^e?%4S6`5HOk+_o4H z-F2U+-!Ytt(R(=DA#ka9J=Vp=FQw)7DX}_Z6dT^FWk8bLll|&TORcE#Rhm+ddJNU< zo5ys_uBuw3IQ&klinQUl;J8w-|4A+;Nv`eYaifxcZWI5Oy}Z43_nO?d|6!{{GueCd zq)gymf#W)zZNyrvNbu4x>>PJB2K=yzes`_GQzH7=@#59m(X6V$cZ4`tO}Ut06Z~CV zxVSJj-M%d8j~Y+M{>=9dJ;C9AIgwH6p&W=N3WrJMNcG8_`S2XR2KFVeYnh#2bdd3B#+RM##RQgk0bLWQWbxmV)2tmr%4qn@SL$#kSkPO2tP<-~^%b zxwBv^TyYw2FZb{nGrQFry3adf2V~ScqeC2`i+7BBf#Zj+$I;fdq_6Sem^mqj{gY!C zO@Y;~mHRy3N1lZHZt|Mm0>=j(ennvekBOSv7v6a}mcG5_(JbFxF%)}(>R%g1h@p%< z;CP`MveGRTvc+Nk+Pmyfrm$LG zFnWfZW?(wq7QK1P@@S_xnEvf5aGcQPCbvv6b*-p`B@PmhGX$DOJ#MDMpS2>yh;NzY zx70iZjsv>oNwz7XjP`O$ryC{vDO-f!%EcL1oTI4CTNaHuR;o_mo&o1XT`$>kH2yIR z-P(a^^-5J0@#d}CN``-+&@8BVuJ5jIOF>t0JN1M)MT*y(eIv z$fl9m{JQ+LQvN>iqkBiM-R~-XkZRb9$ld6f%jzA_VFmFX!@eh-i2k`_*BvvoqB_8} zvvF5)o%e1-7tx6we^B>2x_U8i4Df89x9Ur}=H$s;*EYEk%$W*hUn5zUp9Z|t8#TZ3 zo@j9ajvhLUbWV@r4~tWwKdh1b^&aiwACN3Rwqg6bUq?c)Gk*hf^GWz4)o?V@UFM@cL8RsU=XcLV zNb$$>IxVf4ywMR4zy=1Thp+l#XHLev_j>Z3J@R@gzg8E~aBzp=35|aWRrt#WqEW&= z--kbB=DQyMR!v}^<9A@-2l{#A_+y;;#Hr~nN3eBe7dUd*x+`^>1Tv|9V{!`K?AylP zHzDUNL*Y2`cMCb^s56+0ega1dTNg`(m1NY#|K|GPvG^Me!j0+Hnj5D{ZF^m9Y+bG$ z4TCEL3CIE1hxZQ}BvSGl@;{26QKXXEhie+H(>K*&u=+S=4!wK`qTPe7bKEm<3oJ*I znGTU9?I9lBOEQyEGp>7*I+7rD%aW*j0vsW1onLNoNyWJ@_DrkWI8qXR>>!^ve?#+5 zL1YtG7yi^!xW0)Gom|jOn<26zdX^PqFn@Apz>rpwX01^ebu}_RZ$_~*EZXBjr@f5$ z;jKui)G_diTQ3TSB2APjcCUWn@-uyJz8z&GCve!nxhdMpyW1SemfoASKCazJ#p9x7 ziB4E?YNw0mlyc|u^?-d33p@hf^5ZmmIm$51MEw_%aXv>VMQP%xp`}i)b3yxCyQdLw zvk)fidsG_J&4o{Io;|a+F>F7ZH|nTEB8dHM*^-89NoK4`lMfs^Y+q#QgscY2&-YF^ zOh@&v(iD9*3GJ-1mprA`x4_0-1S}$=LKh(yB(qt7SW3oFO&fei;aGN{cG%u{$He=K z+?!-v_m{vSL#NfXj`_O;Ga;c?k@`)hIn^p}vlo$no{BdYdcL+(8xwE{;GA@>DjsFJ zE;lN!& zH)EB@KeF`FMEaS>3>#YA&rRD{=Cb03OOZpI#TT-;jKG~k=O*vBQzy$~e)L`;{;qZ_ zCw}gF9X z90PX(-R5X28-0na_;0z1sicSx8sbvFr8ea8*;zgaO*GVFV*~dGxI;x$RK;wPT2EdZ z540oJGS}307hP_PKODbu4`wp9VqLxic&Ps0^Kec|`gbs@D2aokF*ua1zU{uAr!3&a znVDk#bh&1bS|SPLzB&Twsne0O7@1T4f)26B6e4Id?R+0$o$|b1T=DPjf>pws)#WV2 zZzdPF2Zj-Qw}xG;CC=^1cHV*{!4?Qpnb`cD6)WEstL}h0*a3IIHim+uJ%(xg;Xy^? z1AN-)n8b%=n;vVFBufr*{{q;w31OPIrH&L7iNN?}v%~e`u!rB56#cq%xTSTZUDo)a zC4FnPG%HoXN)UkX%fx>&rQ;uB`)VIA{3H=}KM&@el2C|wpl6YzXIGZ;GDGW#Hhvf@@=o8 zDVNmBGcj}OY2LNvxRs+8NBoGRyajLUm;o^9P*>tMo zQ6a-j-{qHMxJ6iq8L)nhOB71pywMllchDJ_D|3CrU8)DZ1{&aZGyZ(B0NeQmIOvo* zSidH8VSVUQo4d#z^KMk^T=S~LmmH1#MO>!-n7qef=|m226R>gJ33KRaON)_1bULeN z5wk4%9XKfq0@=sdTDk{vlU)YNsAG^}(iw9V4XC}_Z}N9SdYZ6NKv7@+T->`!YcJma zY3n&s0b&F+&e?YCh8&ACMma3y?MX*>IL;}Jy|Ghb6=AcQGreR7oU{zXU+lb5e#4Zj z*}VH95hiAnFFEUn`pLohF8ip;#yqZ1W=X&ef}^^<3{b-FuhKc46Vdc`NGZ6`yvycS z(%$^wk>@=+o8_oK|5u9apEs-cKPhrQ==MmFTm7^{zbPL$Xr_)GH%Gbqy&cJT<0X?i zI;c+gY^9+E-t~LcVT$Zm_N2&%D50>?vPl5f*O7v|yX%=4mmzt;mNPZqL#;3XyFo|Y z=f3mSa@;!4Lvv&9wfU>F=X?yj+We9<_(lel?+S0|0PBROy-S@%v$*SfJ4jf@iR({M zX?sV${`EaKq%HUU;wVWECE(h@X-Cc#FW8QIJbYl9d5xB?HY6oG^6FaVX_4h-tT}5{0p#B018lxt3 zj;WU?x0*qpOlb{(tAq}t{g`dzkYZmr{{8N*G?K@cF1na76rNP0t)Q`uyC30-%XjEJ zJNYWs173K>DKwYYh}_{((EaQllis)M&U>@m#Qt>y0KOqLNYX_h&e=brXIen znaDsvN8j03*>O%V&Z&nbixTKE!rOo45~nNM&uE)Qse0NI{Gv$Yq|xVnfR@pp!c_q8 za7DnmRURw^t%%OM56q`LAQu-*!Hc_h6dR0|occohn8Csb7Y>w#AVZ#!CqoTQj0hed z4l5$J`#s;`^^(XhNP7K;#IHX#a}3TPUV%EeQ}YII`sEaM1#`1Kozs*RK4S6r4?n&j zE&h$N`5awG^bEK>*go!e9J(86dL@miMz8;2>@#DE(GEVbstZkg@xiON$^~XTInad< z$&6d#zmHIV=M#I8h8bHBEtDTx$8up>IxUQv(Jc&I7IgilDPx|Lq z4Of4B>m$UX5#-`UT-m^7LN|jRIvcDe6F$e4^K;ounEX}lmCi^(Pjory%$$N&pq!LrMCq-9wbNwyFIqCMajbpxk7t#YQoM@()t6^1c1v3gq6Q*z zU(N;P{y6}b_}|$k<4h0kvdUoKhA$O3m&=uXU{EzSil9=hx?^10)$ z{2yEY)mHIWAHPjqjjt`6K<&CBdu>pH;;#W*EOcyZsIzJ~L>Dw;G*%};ht}-JKJ}Yj zyQrS;%u*LvEMQeM8oJTxUsiYQ4bk}@&it)0^&P>`UOi%Vk}cu*LT%=7RXqk=By^wr zM_rp^(a(7Ww~i(VvSvay>?F;!>w6hE&%*0(>dJu&2hM3jb6SadAtsq$Fnr6R)wlgL zWK%94KdT&TRd41nPTTto5z3_GMvAngZ8fw0t#@BO$ltsbNvZ9uzOKfxs@JH*!)|in zzh~e>?r=E;Ieg~E-?3nQe2QkHIf}eKz@{$vNzD4df$^PGk(QH)HzEkULagis*|)zg z3(uqtp8YPgDa=L;x7>t^c^xxL!NaPvCw-D$(wiT=*iR6xJTl9MPG!|ZstaG#(2OVjq{IA?Jz;9Q_5`0gviLT z=W0wH%ldxLOOEE>^I0$D1Yr>^f7HJKH6SZLTs;*IuPEo201m~;X@5b}MT|Lb4O4_GQ0gex1Q5qRQw0GbtyW#OBoEVHe z?$H@;Lt<;di3m(*5Bs3qTTU`)Y%WfX+zg>wzzdYb1+|ElQa>d5bF{d?}ebHaMn6G zQ=-J=^!x*yCUoGtyKNe6W0t(aqXDcUr77nQ0liNaMHr*y@8GxWNXG%E4xCfO+p?j{ zb5*RI>wBVwO5^uQhsn>hETqr2zgYd_B0jr~>~)f>F{GaA+Xd(*q{k^nPvyW zWxhACd7Y6nIa%JF?Z^^V%~P%qX?568!z6p#*)?gphpKw7#4L>m4x_w(|5Jiqs!V|HeDuAMp0nQM0HwihWATvk>C z^u9Y9N5QJZseu~pm9VGJxCVc{k+|hi?m->`z|YBtxOhM(&x zPuGNZWqlJ7J}5KZp3L31e=vkn51b@)n*-#jIlpz4_zoCGo@L}uoDamAc@#eO2<3n9 zr$UnwCfA=s=lqCF;87OA0OiYinOfwsye$4$-&A86t>PbowkzpTZ-5g6&hyV|0|T$1 zT#u7ZnekGZ3k9Mqr4>rShHINHipRt?NdF={19=%+gZi~v^$95=jkKjbIq zu31aI=k_FzeELqeM8iJjJ@f_FhKgLIwC*RpDsY_8u}$QDOBrp*z?Kj!P@o_0uxev{ zq2;~1Wh$Jv6zw?=v*qm2sr@J@Sfp1;QO+X<`G!YyUeMjs;|8w#Ejmd7DL^jgWW< zj8w6&*>u<;bD5b}dz2;<@eIckf%2GO&y&Qx8H!>4poLh4^*r~;AX(NRxmYQy-45eZ z#bBviEh=yfuzvU0aDSDKjg3+IGZecMH#!VSp&Bd)_ekREr&cTahFAbc2VH}Bo*Cvk zmd|^k`tPpr9IbJcAEgAE{R55+)^7Dg$7G!`*luWZi7#>E`*%bx4u_XB2M)^MKW7()Zb#14dn)_%pf!EEv=LnOY4wrcNI?{Kh$za%hHJtOs4 zU3xGX z_V5$dsdkIqW-H9q-hZ)jpQ){$DkL3L!dWmf>XhXx0O{(wbe2xaUaZ#px~@z==0s;(h_fV+XtM|e>G$W!{)QGX>pe*Lr~ zkMwnSGzro6i(7q;$_LSKHg^RbS-o>g`WvFuM&8^0rnlk`{+L;x&322hx6FTOe=j{0 z4crBER%00?ofA)$T2PRU@4C|LEWg=j<{I4{I&NMt*9GBm19t{pRn&^#l%Z+Dy+3Uo z8eC^v8Y&tj@$)n9bcDi4$0!wG4&W3zh3yrSsm{NG#vk8hhSwJA%kUzFT}k%sJYUj6 z$sqQEyRlB78?g@{t8-psS5C1ZWYkl}K(w~^6x=i-(chie9oTyW)0;=oMX>rSh!M7b zTi{H>b-ye~q*N##k9!~e<-oR>u2{eI0JuZoJe!3{E5o8FO9@FA6oM^!GJ9Uu7lrbO z)}9cw*iDF1BaWl&!{WqASl`+`42(pLKe=d`yN8Uu#--4Dqc>l?jB3_&+R_S&+Xc>- zUx>GucRsW*(piBIte{4<6cd|PfH+dgXy8mS}e;#-OBcQ+vyY= zN*&r|0Aoo*g}uudQbdheK$S}FDL+%%A0F-^wIjUha)UJTdr4oOf1ZUMUa zxJdawRnze+?a1bAQhumLC{w$UC&J&_k*v;vn+ML*fpyFyTu`5Wh)^*GA&Xpz&~2=Y!s@t@jd1^v_w{PaO1!4cTBa)6Fu$J{8 z$#_K%mCy2Pbl}FIi);EQ_;~eUFr{CkjhTg!nji)42H9`Q(2fkIN>dJ>A>c-!n|#rI zIeJ`;sWq7pRi4yoN$|#M6Wzl`^{k=q_BxLe29!UbBOZO1XT!DTd;MfVdeMmYOMZL( z0zVUxqsnI#YOZt~m>?Sh&KE;Maf>ZeGxYDGVs8CQJi(V#zsKyA3;gfa^|v~61a?60 zLm5y9TMOfVT@}n%5ESFqB$m0beks@_Y3{AGQE7RkO`1W`lnvK9`rw7J*6$8}OA!X& zqH$RiJlL8VWW|5UZMv$G<9=XXGj%xvTn}{LXpHPjwdY4(-Noxo%l0&;YOFsLY1Lj5 zbQ~Oes`Kgta9z-8A2rkY1aC4r?Qvaz*h%mP~U4dzwH9RZSkf@wex8CfujX@XAn zc|a#u=0CyqEQe?&lnAc02ZJvnG*M2Jr?lCMOygI8Yk)4%?v)WSo5+g2OoBa5Xzr-F zyyQ;`u`CSU=j!y+i4$;+SO=Z|XH0M9$$wHPWy4QLh(RVoaQ2b|D<$b#O5;&aq7=+j z)j~&0F%}W~SU#=T?@#{^Jj!k_{dO#_WU+eErmF8PyyS3CMGbVF9R-j6wAmGlJ&Ll@ z@K)9-sQ>AvryWe}1UyjUuDBp^3&|67oaQcL{ z?@k>FTm^JGQ|WW!nn4uvsz}#bD}xRz?(@_Z{`;nr zhe~*}_hj6C+-K0pN)&B}tE2p~4?N|7D*?`vpH7ZK!KChcZiYnnZyJG+Gfu+Xu2&&O zGU(}=ksX&p;O+MXY+2|qxhI<666{QOR}ILm_iR0e; zazrigQQ{&`X}+Sbvtc8-8v2-+m{l}bMY`r^qGXtKSLM2TNzT&X@UR?^G78W33fU=9 zadvc}eI;C$zrgz$XX6qBQ`P--)PyCYj@d8pNn)^>`|IOBM#>Xq#|C?6l_}N8&zPd8 zPT5QgQO3L+0<%UoK+Q7M!N*7{N8VsOjzFdg{37^+eR~<_^YO?mzRG#{PFr5*gJ>HJ z;L>4B7gNut`Tg3+@8cqE)@HDnY*>}|J>Mut$d2{UR!}CW1TGD>)TUa7KT&pUd-EbJ za`9_m#1py4C&r$)#03sdu=NH7!7+F#V99s}2Lp2`aMZoBXlch?OWRZMj!GI2U(Ck) z>m7SAzD5uzEeXCyTP@kwcDGxKTe_9yT=pn0JR*}Ps}iy|w^k5La!;1StSNzdLPsGCvb7lofr=ceYAe#LMtPoP^==6y7j(% zAV4u}JS+yAF_1a{z6N4oE4VX0ydNRL`^VC0;q6lz?lsKXhX0a&6M6AfWbC7ZT{BJa zJ>qfS0Xso*X5G-5h8khUMm?g~Lbt~h+Ao;-$ph~Qd0-`t_uJn>7PAW*=RYf@5X7v7gwPRMLq zZdsO_$47e!|5y1IJXlLs9znGB_p%iT5hCcy>W8$JfqaLuRp`$)6SrT2H{LeK^{IaN`Q9`N?fS|+2h9#OiRm9N!g7mIg5Vt?oheBxAg%nDm6{l| zXM*?>)0>D+T<_2qRo3vVynEIYb<=o@ zh78xafb)ay7HL)QpQ4z9&eLf1&dSJr=G6MHtS^=2C@vN;vb|n30OtemFpXun~NIZowC&yuQAxvvjxB zTX9IMlM1F_Gh+Iv6_T45+ArXop?jM%`s&BcgC2+ah*z3@z3aHjmzefSsfvHH2ql^= zdf{8v5jGY}`$Mn|eI|ZVGDFwj?T*iB!8eJ=J)MPd_5WH# zd~pyl@N!*GIPOUBX)-fzYB9fKvI^#;>nK351qUMCzu!Y9@SDSr3|+Je!BlBP+k*?4 zo2_B`)=V{=B&qQ?oaotrOic8o{TkX6iX4J~c zYV*P;k7v|4-h$H1;19boG>>!!amU~x%fFGB^_iGrRO}Ts@`3j&#lI<9W-;JqdJ}ku zeI|W2*mX^e^_Q3aq#{~wB>9c!h?Lm89_Gw(50PQv2hJEetz|MAhpGNgZ`)Wgv~kKF z+!yQ$o*Z6|){`X9dhg744>&{EioNvvI$@1dYRiU!k>6STj?62G?u@2IP;%dKuo$#Y z9Gz>gFTxw)?tMY`LEm?axD?N5FsMm$f_&y=$8!q`u zM89pk13AP5sT%pWg8NgqDM!4VlUHgSAA!?`)yo@rOncQK;QEG1aUV#>;Ab)^1^xwdwrVKgJ~X zLENkeIv(22A*+}L<{3il@crR-kG*oouOs?$5?`8>{h5d@UZeeACvh<>Muz-PJS?vc z<6&JdHJ++?U(Ybovxl}j3{29-)IFs+lqD?)XuAI27Ga`NRvpH}RYQ5>8`v#NKEKPl zQ_vd+w)l6l8(Nmyq#J*7@e_>511JsR;Tk%djIK$J7)3~X>snbnAsD_=aw)rD+b-qvMeDj%yXOzW2vFXZy6UO zgrqHF)=nOk#LdCb;2CuH+ii^e?jpn9cP7R84AJRVYOQTdlc_Yt{0Qfv3=X>jPWZp_ z#P2ABP)$XVvID4$t5Q&dEe%j_XTD{8!gdW5z?aqpP7pe4Wa?3)M|E2VzoQF`g(if_ z9d|MHaNFuJlC-%`Os@oh6M(Lsft5(choC-Ve8`sTr-r6*NhSTM5G`RPLmXjd_BfpS zJb^CNfcF7oPgB#u(|+Unr)wb~)8`^uGJ28L#(;OWCIBZ6ywH77Eid9UG+^!G@Rc~h z*j5Zs;VRfS24tgF}5|(B1Z!^Ix=w#jV7@H>b^nlRg&e zWg`K{2_5pvX*1i`h4SA#7V7!`?mesGm?35T^K2|gt(dwe<_Hc%?9d6j==7?j;)(vj z|Ma6uMVy4PS5C6@hGu)F7U_yssIvyR$H4jWW{+$wvrOFv-wrn_f4`b5>Q-HN_sOl$ zj{?EFRbb!%z9(708nIVssE{|dh~WNpgbRbERVXFhAN}d3#f~kyIMxwvB|K0b6Pyy# zThRu2sRYw^i~TlN{uxpHm5IjzQHzy9sqgrdD-`h)a17wOo-xB{x;;M^<7uDuSK8#h z8b)}UuPk@HZNuRADEV2(44CSHFA{sopPhG~COs{1IHC!5(HR^b;ApjQmb>oMu0SVJ z3St0%^rQjfnmzwQLn*0(am$l;yWKRuaQ!jzY8>5#qGMXc3D(q|B)~PP;J6mLE5UB$ zNUtNcSG}7}Am4OP>j`t1E?(OF#+RCPMHV!0zb&KiD`AQ8NnRY9Ppnlry^hw~4Ybjc*e>_Uje6jg(I|dna z`d6oxGM4L4*en$#-WDDG6aQ*v(x|4Q7%F;@O&{z7qcl?JR(T@l`acEDkjT9{kom0e zO8#pd=GfQY`UnY29NyIZFsDQeoad6mh9E0X-Pt_?yC%sO+-2lSi6Md=8kgGVij=mQ zd|(3)Aq%6Y?y$YkyQx+irnN8)ClRBO0&%T9dHTQ`f|uqUKBhb16HYK`$SoFOv|?sg zE5ucz!v2X1d>XE{YOv#hP0p`sE9zt{xH^an?ww~{Oj&F(f6&+cK-vrGcAK!-fWN)3 zhYl~V_Jy)-lCKe2|4SNfFZS2u?~nPA(XCz(AL|7i)FTNK#u(Y#vpU^>FrDcKO2Yzg z6<_DNA>>p9%gcVgB9$=7mp5Mz-SEy)_j=NBu*SANUOs}o4g;iNoU>6DD77xq=q@eu zOYs>Su&7t%Vp558ugib^e0r%n49Y`;z3$MOT)R!ntsS-dg5gz&_td-HKeD6VW7ZX~ zxy|kKmqma>g?HHftK9<+RMGijlz(Efk80g#5h{j$<3F?`PVkwkk*QV%4jDRX6~F%b zYB=5cp~NK@H1A%XuN9QwwY+huszZ7n7ZmXwI7H|S&4jyB7fY3jmO1<6)W1G)RG%TB zow(HX8%XfezLkfGi90pm$kMvW&X25X9lFA93khwXm%56Con0=vqlm0LQ+w+i58MrO zLaeI+BGkA2UtT=4I8EbTHxLS2EWR84wP|kdFM_=Tv-4Nb(QdgTKTxf_P^0*%J$V~4 zrgnUP`$guke@{g};>gZnIB*xxDG%qOSsNTE@6l#^UFjF+cN4xHYoEW-`g-|3F|G7P zJ8);fdFlr`UA*#rCSw-V+>1CxPT1)sGZ+^MChtpL< zj`}XO?FhIv=r}PR%W0r1f74yKYq*?vMIe)Hw?o&}l<4p2vM1o}3FGP&=&DOT@CRLU zekCf6@FL6NBNL&U`rv5y_IBIFq&NMa9Nap)1l{NzhIVfQKhjQ$l7TXL)hLT(#z^{_ zDgy6O`s!?%)E#gO(4nMweYU4MZ`pVr)=Tfntzhwwps^~x0wn{R<^>shjXiMl(2b4i zJva#r3sl5bj~@qbfPSI(=dCBMH!WX`xefROYJr=DE{m0sDgO@P-}syLM3jL^GyfEp zzzh7nB(D|ERUZnv0N`ezYpiTS-#2R~A6mC#(rFdi4y}9lt>l%`%XED+DiyyFxU4b- zU4&0@0(#R!b1H8{_UPWzV{V4wIwO(D3ZiFrgh#q_r@&1>7moC1MN414RD9%k66`%_@zxINW=<# zNiJDFZ+~(}A6%ktzUbpfQwFXBIt=!;gs=_j=2jQIR1VXBj+=_~f0nWQnuw&AG?*Jr z(tvA&&ZHju*X^-d(=!(#lPHfGtAl}?uLF6r(>})|!m$S*;GUKi=%O$tWgoN^3zgc_ zi0io;)zY_>ZKox5$+7vf>^=G{jtpEAboFnp-oB{aY|Trij6UXi)A>m?i%Bu?xM}S{ z8s^gp{$$`9fb*P<>X7kdgrqnKJS1WKy<+56&Y#8+hDBfDV^S)*qx z4Ns!>vmcmQZs-2)fg5gW6u|U>1!ri$9pj*~3+J1nQjPzoI7?>DKMz_&rV1$-K17^9 z0ImvFZrf)pasS_<^xnm}tuL=nDZjtgw(DL=DX#EjoKi|0$cj{e5HLCO&PaRvOAmtU zKsb}n3}3endECi!ZaX4#q>YS#H=UrgG6k@V9n0(F;HQ`L{!j6tP+jn+0=42DOs4M>iqGWNpq%M*tfO8g_VcIn#NTb0{S5xc!8BwHO8Wvz z^TjxcjQn!4$tv!2O)>V=X?Eu6bxvlbg*oW_XWUKJaR|p1Pqp3W_qOTKPf>HAf zb#acUsbBdNQ4x{7-?6kfh^Dkyf$}~pfHz+z|8NFV@1^n+C${Keqw`(L)v!5X!pvOF-4kq;m2Xght$mwy2jnxhPhEV;R}sBVl{6+Cms&iRsmBjW780+$P&zV%Df zbAp;m5~nImrEhos;uvyWxZK3ulj~n|5QtCqfXjgn<@@cX*D5=Eo0XxCzOhyLH_0EF z4@`@j7>ty>_8DW~6zv0a&qOfLw+>h(T{wyq_5bkOM6it06Y~x(#yaNt7V_*!1D6S1 z=1qU-i=ijAOyQ@7i0$c~k0rV8|F&Vmcr8jrbV8Rk30yjGo=F+PoH?Q137)m);dY6i zD87Ao^jv+7Y`q9^<^6iN&x$@m8d(3B@u(tT!#v*$Nhi73DEt;kF9%!@0{$@VD?8q4aIXp{|0H= zkhu1?F1OF?WSkGUIOuLCsRyKM@L0CGweVHBh25hAu|M(&kl0}e`2>uOyGH;Q16`JO z-z{}p=@LtEj7H7-U5an%!6BS!5(AM7nuIvQ3NUZ`4!VgquULcV%eh=q_}*ugdVcSr zQTpq1*6qEJ6`y~6@TLp6NZ@?EJre$g`s*nP8-9~xO(p)`%219$u-h~ngRdI*Ax*~f z|5__hYE@Z*zLvp|b8i~03$ zM|TFsl+wla)Gs@Ndi^Y)=wfML%o_wBpFh!u5E1e?et&MkrAz8j=jDk{Ll+_{3KTA{ z^V+2h5P%DSwg9-4Bq6@7sCXBN4&dC~i7{>E;H7Y=Ve(5*ezK}V?O*Y@078f|MEm9W$Y12-VC>9%v1atmCP7iP%(AARg z9hLUCmT+5wnpQ+e9d=6XEo}~H!12#xa03Pq0N1J{ZNJ)>!Fq_ zOoQ7(cTdl~%;&=&QUfmL2SeS}0d$--&_!H*s66T~IFVFpcwG3fm+(!8}%60jE^iUNzMvA#i5UZM3R&q$r*sUDBA29sE2$c!b5p z?XE~EI!a+#wxImqVHPIP(SDHZUQOJ#WD2fQ+P3Az4l zr(}M4FQWs86q$9~ZyxLYpb+`Vd$!KN=f2_gau-4DAl+ALsoSr^w2ecqX8{Dip=ROq-YMmGtP^ zKOKu+`>Qd^eNR8GXlA)F60CJegLzJE<(aF#fyf!ESNlK`)jzVwzQ% z>7U{DeMtpytZT3X-U=Jfg0-(AEyB{b!+aN11czr7Bxw=j{h6%c`EkHK2etFGSGjm| z@=e;TI2_SqP^S^2#-+f?nZv1<<`*BHof$va{3izHIqM^nRqW+uj(0ESq-hkIijlX% zWM7t1+q%8=%2vErJpf9324AK)<1#!PURv=#DoV-(E8^b1J`3?J>55}J>3i z&^M@=56xfriVNfuFwi{q4C4}4Kg7?SBkAPTBle>SMB`Xq&@;evtwVKcBTZt>okZXT zo6hKlU%NXYP{>Z+wEUV*6*MXCGffC{u?%Gh2`szVPK2pdZUsb5Uj&~sCUs-8ru1R4 zbusV1{-FB7tPnfAft?tJk1t=NcBH3uT=z>i(Z~Jx+}Fh>CTGp@S*>e(6Xr@D!y8!3 zk7cT@Qhn4-Z2y|@gtEJ=u%7eTswT;IydATuX!>j5Sb+0Q-eMW*rdS(vjr-PBw=T5e zUSNgKqa-w(C4b-;9I`M0r;1D%HSwnfwuYTT?2_KppTF43k0zKcE7=x&*V#flUAt&+ z`f3EqV}Mgd*F7gU-+8H*CyXrqJjcw7fmvV0=Flr!Wod2VFGNQQfTM%;n$G42^AQ!JtsEQ*b=q zHFp~K!?fFtmV{hPWZesUO#7=X?2Yh!hrEw!HpRhk!w)&U%lZk#Q>Jpq=M8+~_#fd*8%qU*dDFe8bAz{iuLmd++O= z`l|_6EK=n0le~*QAF(x}VHpY0;9fSJ<2!m3qIYLO1ol z{~2L`tNP+#laf+ z_0|gg0P!~|64jTV%yKn+KZIFJtmPLTgYU1Rf(7Hv9AP0{_C(Y?NpkKoD%??I?Wu>e zgz-!sd0I{il_ogo7zoJV?Re$2@Kfu>{hw|#!97n8CSv-0cj;{z>+jsSEaRHLYhZy! zAS!@`z`2b1pDaEK%Ww3VCY~FAuUgPlx*~s~L*uUeeVPEF11=ce$%6-*Ex59NHL@>5 z7aPtShmTLH`K#VQ+7`{+bCg=^cryz|C^yjEM|!zfA=1Y?b=2%sRg8i0qs#(3$*+UD z#XtRNb&DO`$#n%?4qFE~525j;ogjXv1q)kDLq+iqEF!R2C@UN?TI7YGjR4_dCvnG!j;1u`5qh8$vEM16c!^o znO#R&+EQ%1I17w&0qztyPZzY`sCqpYePO=WHuSFypI(R(F+}f+U8SBZvkXhF;9O&& zoWSyQJ_em7rdNHT(>(WjR=uiJ%7wnE!xWpNU33tNt1QR?$~%IN$&QD|w?8b%Nv3;3)hBTcGn{LP)EF7d}XaZ-ceFyTRWL$|iekNT1Mr0x+!P|GfI- zj<Xaj0cxx z*X2Q933N2(k3N-`H~J&{bTHqwZdoF<#5VuhC`T$h&^R;@W(?L~Tk$XNHLm!SPgDJ} zUueIQm}AMlCJ7fL{o!HCC1?77kx4$vIP~SDs%(0s#8q6c-hxe%v{W9)Hg?YRM=y=YGyv=hS zcizO6i7A~S;7uA{2RRD)uoml6Z@qBZx(D1maGp1`MhuLEt<0Y^pKuvnwZ-+jb1!qt zqkr<()O?KAv44eR@B@FLr~g` zJa`Sb95JfyBfXdMz$InZ@2WuRE1}~X5klv$YZ%uybPTEjZVJ{;rd+epUQ$s*+5Xh9 zg93~Xf>=^Np6@7->>~H@NXRS#Hv!#iw2~Jhrk~54${fsvOvIkV7{ssK=y;8Vlt_3; zM!kT$RmPx0DWd%N5IG*fM-AU4wzSzZIqf%%**E_TywEyK|6x%$u#CXgUf|I^#b>3C z!5U;Wo5N+dxFg}KkE{DyjnY8o=6m`Sd?We?80CEv)nAzBZhIc?b5=jWASmAt=kVRo zJhKv}IN6Zq37ZF{4Z+qfQ>AiF&vd{!eV&Cl6y|Auhut z>;Xf?%|5nYPB!-Kh54<=u#*7l|=?+)m0 zy@|};cN#`h-pjl6xAO(C3(Q8aS@G579cujA@H0DT{je|GF4eDaH>ve5()J!KB1P8$ z)&ZOC^h2ey{mdU{MR~zVJqX7=X_?BG7luQfop>gC8@|Fh+8*xCw$ZT z9=Cn++2K0d(@27SbTRTqs}iBwV&Gb!^CazFv2gf@Bc|yrR~V@HOGv4_oeh z{?(IyC~HDJlJdz3)D*=XMy3{bM0O7IOm={zMv}^ZjzFnJ-v| z?|U!W=wWOBQz`pGbMxNt*H1WLc>7c=%Q4f16>M5)~ z@cj#VZLKm2CL3_I(3x*g7z(?OACX__qhk3Rr#bV#cXwkMJvhu~>;u-0}u{sk@dLF0G$LXFLsyHNxQGN19t0N#FqS1%jYbhz|Zi)_%mib zhY2Vwf7eXguU7nXs4Z7VoL)bqdZX!v*SNX|W2}7Wv<=gZv6{d9$Qav^8p-%dH#+rr zi|JZakrD4PBK`dDeBg4SJ7W&;?5A?J@3ehekfjsZGmlF0v$9oaDS+b8PG<)52DlvP zu)bA(@Tuy!=c6U|Um1MUNKn?HWjLp?Gz?)C?imI8ln1C^}O4pM(zRo+QXuR8yE=E@TN5TCV; zdh*kbjFqe>5pYScc0X%SdpOB-xhFnw4c46z>3ksUh@4yhg#FK^;46y-m_JyKUF7&QRcDpc{*(Ug(%!W5Cz!4O&CSnM|#6d&=TKOU54$PQ2p{ngs40 zbXp3@mr?R1n$oEH-o?B<;oZuA1U4Top_$N4xQBnOzXUE4xWL4d2rX)4il{Gd*I9Cc z#~1gxEpD<|?pcVD zTC+q=*71cy;ahnSot#QfG@f?e+|8OU9Bc9P(^Qpf9GT(^Pa}G2RpT#d!Kf$%R`A4g z{hm2iK;$3d{N4(11nE|E?u=Y6%H>jHY8tOzF&z4Xp!4he6|$S4TcqE~n9rfl^{Z5H z-(7=dpeyMgr6j#)ybW*x&{67_rlS10EsVQ2wCSmnCeLs$X4PLkYjslh)Vfty0It9L zK{sq5iF1F6VsVFoLQbGx%)I<#@0$k_wQK<+udA%>rD3YV=fCSRV)>~)_Wi>9rkAKU zo%zr@tYfP*gqF39U>DoOs~8VBFW@}0wqKen29u45tN6?Ku4Ad*&tC5fo*A2e49~@s)hLp2g4^<2NfC;fePQ5ZV+T~BYunsZmpwugXofwkK&M?`zJSeUfL(lnaMs8k+4y?u!p z^-^rZy-Pv#?7$y5XXvONNMY%d#wnH!y6p>_=?01y^jq1l!%N22(-bsvpsC>xcWq=C+0&&Srd!)u#pdp zNAi>FqN@MA?&A{JQMMj~f0^5YAwBEzsepjxS1-|_%6Sq;CBxe#sosy88mM~ymg!yu zflQz@8_-(cI`(BFuN1Q&GY4}^7pzXF#eUmKXC$vZs#Hk>R`b`wH2J z`O|Ig+|U8z%O1Y+!Ex?$#8!(4OVsyCk_I3?u>|qS7ZZ8p$A#=}Rq<_PQHLC!V!E4k zEfLFc?={n&F$^hzG>QcXPyC&!Yn^Rf9vz<}u<&#CuBCG1xoNgKtRzh)drcQV`3&l2 z2B(~jH}i%K&6a_QQ>undi`L$>MZRQ$O;rDq{21f$OWjt0Gl6%c+FNr(6XQtpN*s@s z!++#`Y~UlkGp4tg83#yLPG@pp|BW%&f76Rvh-V@GX{+Hao*GfA=FmP)+`=y{41pN` zm>3W0C*a&ILky5=`4)2)pkmVa_9lA&iOdq#-#cQ(_9f{PORW9TL3Si*n4r~{|1Z@N zGM$aZn?d*BN=AH4IN0D>=J@&Pk7y)MwNaVR-;Kp!;HeAdEsx_3Oed5xL+3i|O;wV%TqH2p!R?B7T*?GrJ@ZKE9U3+qDGPTY-XrQ&*}orCMxeC zJ}j^exCKxX1OTf)9JH1bGbQwdIR~2V>F8KA@xAAux_P9aXFEb1VE`gob#RwGPRbSf zqF6t1yXsbd1sf9@HZ==<*qW(zRF;WuXE!oHVXE?ADe(ERnUZ|ae6vPe55-G#7omLV z*YCwEYNEZO`urM3T{eJIhW*pgWXAmD(sM2x&4UojQvh39yMy+~scy{CY@I1yeU=0` zMd(sKl5GYBHK9lmBmHtoJLI64Al-SmN2ca*|-w^}l;#?waOkR1v0w zAgG)`5ld%)KlG2J$G&4|I)e!<501JrlBiES1#3B&1ltf?24nr6dobiqSbkZ(Ei>S% z&j`a(_%iGYcLYm;_Wme8WI0}`7z--wWr}jBN|@Z(f0*;-Q=*(taC2AGIm|6dNP^$D zen-?V1IJa86L0Na5?p*sU0j}9L8fZ-2hv|prw_;JffEPy^K^^}JNfq>>3cOlhIHl_ z5`Na0x!$%A6^m?q3qLiocgH+}C`<{~EIjrYW5q04s>Gh()zQLU?nAC%P8)snNcfGZ zPxBK{nh3lqrEFQ*{E$v@faf;l-m^dEM79TwpEzv=F9f_J>nb6aznl zLfc8`t?1#+DOzquw6y1A1s&kHpwp>cyHd)!Gg3$Gr$nHzXhIyCGgB z0)s#f=rq{Q42Z6eaK#s*%bGqr6)iTTQ(*MR$K}h}Ey>jfb^*r*ow*3r^B$xO}wRJ^qV;I(ZDdv06%79~qE;zLB_W|K#9djSj7IVNG-M{l*UsQKBTpaFm z-iuQ7^#YC=IA7=S)L5s>_^WjJ;a(|`$xO_`xj1q&9#f-OpPD=LRu1^qV+7~&i&zrk z;dl&*-LxLM6+M0?fmNY3DfRb?$2UYFT&INuZZ@Hp1S2jx1?~aCP)0#Cqaub^;Ci?+ z22Uq1C*dBRWcLG;Kq;7?rG@pg>KK^QS<2lpHYeBq;bM(csY#%j>wVI)zRmmg%OBBp z;HaVV|F}Ud#gaPKCo7{VWo*aN{@gO7G>ygmsm25$pZS6eaFoztJCf(vv&i$X7W!8) zZ3QVaDz+^zd^1jam5YZSlh<1d+#}#T@mD6Cg?wH&uAJBU7`D4d^?>Y52ELxcRYIa%Ht6z?E&mnDeqkH zDzvn|8E7HgVN@F++M>1;QWz0TR-+mz&7k9I0Y?IB_g9%qmN%g;hvxwQIWq+|YoW82 z&46YF|4wFSZ}ewPm|rA<&gEErG1K+9?%(}rdYVL{HmsA8JK|Vd{-1)rn%^sQ6oDgv zEPv*47H6Oxau5y0U=S35TU_gNhi0e*vuEinQt%>?l)feI6kK`+Lg&G$o!*f%8AtW0$)vJ;&tZMm7`p}qHK6bavp$4AUKw5 zC{MVry&?Y7y`I0I^L*U4;`1MNEc1$)u&C4=@=>_k00DM}!6pH6AC320XM|`MKat67 zSMfOmj#xN~6sEHitcPV3fV-6dH!+80!A5MWVmjgbT>i6f-El9KAG`nb@w(qB^jT$Y zkaz~TYv}w=cr0S4C6?dZ4N0C8e&W0I4m+YcX}x%8&R$M0?}`H4C3FkV3=L;6_6M&8 z7vFZZe8?I8E21^(5XbsF0rUR)WS}Q-=g=i1u0^j-i-dM9uf6O3V{e#Zn@P|g^Ktnz zKG}T2LnF9P?H_ddMukR2a#QT`3B8-xL_-NuwN25<$-2qT;6yiO3;~z}`3qgCrjDWd zuO;t4>Yq<(`v}6n*Nen`qqILm%UV2{A?tw)(Z|ruU`A^=xObeZDtdAzDg8xenT)So za419Y62i-Opt*pPoIlXrZ|Sq--hL6$yDL*nv-CL(eRMyq&sk_9rC!7d(VXZWa0k#K zX^(xi`YS-4fg32)vPe7pv`WK-D>BpU>ciXFCfbfK!0kczm*RCtbn+ucLBDOc}qi-;4$p0=EO5bWv@`-!_EsMd@Wp3@`&H!<>q8z zj&ln*-+65;%_oRH2MlL!R=jn5j5|nu-$UL`8YH|b>+0}-C<2G+4G9n&7t2!}ckbL? ziTRmZzNUFSYMp6&xQfTBxjrfJ$Wb_x0u=ZgUYM)et85L=UoEOQM|aPUjjG}?sVKLz z!;Ny|Z2b=}Au8Zjp*x_UFJF~WdwR^QaChL!Q1Zx{@#$Y)H6C_e^zLTS%Q@hdp)(0s zC(L>kbFF=jrt*EmDm;(S_q5xqWpHj`L4*Xy98Q`Rp|eo+Nmg(bW9*(aD+r)49RIRO zlM!TjbwBitKEV&Ob{LNR0?reW_$SWNM{E{BX2qPe=Wz}DgO`-$#HjWYdutLek=no? zD8P||@xl7O$3D6nzTZEL2hI=8%M|)w)r~Z6-tD^Qf*psZa-g)I65!{N_~Rxc5$~ca zp4a;KqUm6u;o7%&$1BhBOI)?zOFvcNfIbat7ry4;cA5tcEp;%GFMZ!~`*i)srWw)V zPn_?M7aQ$wyn&m9Zc(&PYffE()Gp1fe(Is*tt_)$TZCv+!M->rf-DjlOeK#)7mIzf ztHMMhH7DsVx~nmPiPOjsI31DO|JY}3S>1UF&W1*zQ}V+Te9wuYicGgZ^xAO0Lvv!3 zv#--8l4kMWQuJz}+tK``4%TYAWfg!FNOcLpwpZj31 zRxB`1&*-tsvInIviu3V=L=ib`CVaLXjr|2K+X)}rIQUenl*NbrvnIZ(isoyqFcUVD zbi0wCu8(7*)kH4$fNKZU^W3Gex_97WE-y0MM%)=msJQ3q%OT!?<2HVDvf`gO4wgMz z!E}vVe0Jl}ho2$r;y)K-tPGqh>*f+H7`;{ODipGE-k$M;(wgB_iN1t&kl%6-x;c=t z%Vvj&YuE0Hcxp7_ewOvoA1Q;vaLH~id)%So0< zX^SS-k-2M9(qsDNehClppgEnhe3_slng>(|ptP^BcI7KU>F8m3pClt>1wQU*4&!yE zGV+cQJ$*ofvS>W+R0CW!tX#Met zFAHzW6P2B#Lt=~Cak9AEv4Jav&ij*L`oBqp-H$rg5lOj)tE@ILvM1rpo8t zVVG46U7k{)?u+Bws)zzohGe;+A-?1&;}y}+9pso8^q5b+PQVob=Nscpvtl*L;i1tt zon&>0xP3VvJcAth^Drn>X5^9~QXEba3)l@KN*p|W@HTUdcYQ?e_T@PKV3j9QuFIBA z#-QINqA*y2;y!_%Cv_MxhavRY%~B=!x3uX~bAp zyyFgo`?fu_eKKSeH}|IL-h_U$i0ogEX0%%u&LQ6h?jvl)$JCBw%lIzNx1KdP?mRDB zBLW|keUI`irv1w#sQk1BCSS9m<8yLN^G18(GNW@`5#M^}E_P0GrK8xSjP!MtJG?^x z=Ipbe%baiLY_0zK?iCjQqqPlA%cCV%1lDH`13~+LG9T}3!YOA4bZ0JK&%=JseQ;wv zCEv#_C{%qtIs0pAV^1W?l~wrv@pV^WSu}40!0GPp4haG25+o#)l$0(h>2B$ilEObG;cLAr z9AqI!=8(6=B#Mb9q~B+FRePyk#CbW7?;X?+h_ zhpg8+6|Mvlc~kO@I5gt5!3VP`u%2bU=mjnbI3Kzj13LE=WK>)SQo@f(==;}!gA1}! z!zP};G|W_$UV(=j6TnN%@j@6TSf7fl;oUov!~Q43dWz>{raUTKsk0Tp)pYgi1t{$` zyf@zeMd1@1iOjvK;qh3>w7+I&!WAbIbDoplQek@-`NsyhSXjGl^24sXy*!!9H0evc zJ_*^F2r)k2OT^teUbXw!KKOVIla&jPRt(S8l$T;)3Yc<#W`aWl{fUM}`;TdZUQC!Ly*ea9LDSpCfw* zK0TlNzr0ok71V=b^--Cl#J&G;P8Zg8nLhp$4<0@W#nkq}QF*&aV69Y5e&sdrTurj{ zl6at`+y4Vu(t2sY00BFmJ{EXOAg51gT;Keo{w|rJFSYB8lg<2s-4?Z(xuXBl%$=v) z@lU~y#N9vu z`$e^T$mk4pd#O=Oc$`Ll53?6tIcEWC#+n((X83`sS)HLi90}Zg-7U7FXUg>FdZ)d+ zNHa)SYSVGF@pKLqeD>W3mor*0t->noXAtF$7QHo2UBqdpErb+Q5H0-eM?!#g<&q^Uj&Euj~RobCbze>{B?`i#u@qxJlC+Hk-c}RcK zRubNF(dUW9J>OhAwe)llk}CA&DW@hwWQJqB!+*yW8v1}~FS+}dXrVUnF#A<~92jS{ zW^0!v&0D|BQM&)$^`Cz!Md|B>4Md6Pr`I~Q^)IDwIv#l>?rZ~R3tYhR zGY_!VM8_z8cAoZywDVW5cc8 zRwg0jOs4DC-;D}=p>GdDB%$B!=C_C~U_W99&ICF;_5%_@5yD+WyNkvC!a{{chE5fG z?5@Gb~JVlc)`UEke17D+`S{m1^X5QO=(^YS@S{5K@6IY>+8;|qNzi@r>#?f zlY*CL+EG!8kDGA!CZ)fVM0etBrZX%B?}M~OFyDK_KrA;H|4BlZ_z3+*iAm{MPj$<; z_&qWVd+`L4F(+kqS4`=dTL0le;KZS;|MO^SfSNTm!|vta1sBdBY3|=2#D+%Ceu3R1 zXs%9ht|dOm-7_Bu_e8x-Gpw9%y!G=v+zzIXAx^z@8z+C$7 z-Y&wHTovsemEp4LLn{Hr}&{eXw~2rW16*maBlJ5F!Ryy(_JUbNecV(Ny4w)TnPIgfa8NsL`Of1 zbNAT#TWF{P#!d0z)%bdiTR~M4hMg^vVl@ZsEP0??nO5i{#D6Q-5VL^9H-2Z;NB@ao zI}U@>B<%0s>#u5=z;Q#TWcxGp>q17#Bis}ekIz2;&~BYwC&V5!9dX&Zlu?Pp=E@13 zBPo&~)ko&&2W`TS9~$X;Rx4Uv6}aFnj9YA4t`P~mgEG=Ma+ z|1Ed~vPH#rAmVqBI}}*>O09lL;KUlFrTBWQAE6~qr0jVDBo(;lxRMet4K|izbd$o3 zhU<|A`z@HY17jOq7^@DG5WZVSVO;`9@!vfc#a}mj+xQM){`NANrg+Vi#|s~C&-I@i z<1ShAt`{SmBanfmyXbXqWZ&ElF=oMz##wbcT>E|2i-uV51$yu`wSH|$*u|0jch4Pr zJs}|$#mUMp9k05T=WRzV>dT-Pvbwpi){1 z?AH5Mbn5o0b|(ofhpshn1kh=G8BSKrn&B4O&|1ZU)gyyuD^w{sfweQ)KCRD zJm{))mCR^8@sbICAF|h^in4h(Wl7LE63tHDB1=*;+FAgI1D%@cNT2da-gv;x_GI3Z z;dq8Y>Ts1HSq8_;v6~-m6O_PVL6>E?=k(_NdpX3G>__56iQ2CQ+ct2zIm!kL)rmyh z-ob$#1Gs?3o%tQ3*I^`Nqk*hMUp;!%*aYbuU7vDr(?d`m3T%VazTQibeorsgsQqaU!LBQdV&{jB z99kF=#sorEQ@x_VA;J1dN2FkVu4UFA$~4$)DVM8hSlf7@W}bnRBJ5UQZAJ=HJqXaf zp;&a-wdh7&{vKb8b%J9lJC`!YL%#h2S9^Ch@WUnChj=RkT$FX@($`m~FXR8AKEiK0 zO~Arb_YC#aFUynbiO-z>1ry3Q&=KtN2#k;z@%hPOezrqC>g&$ACqJK!;bJjieEmeC z2PQSHp)33*Xy~cwvy>%tkGs~#C$Jam)ATt*pysttA=HU%vwG1UdoUBGPsJ z!1on77A);KB1GK@>!jyT4L?{&ewTQMCj(Pa$Iz*zU)_*9n(|Z~@*v{Hy(q$|+r+U| zyA&V!sGoqnFAnFkhtMIhGWxqSAkyz3H5ATegxVBMNWGHRF#DW6gLulVaTX5TK6I}# zKGUJ+kSWN;Z}+j2<}z^j5iE7s&50g3*EC*rP_l`J7ZzXvriLCTk{L- zWlmMigE#N^D21qHG;e_00WRRIkT=w9m^__OAbduuVYeZC5XaAR5%I(6G@=73Ppu7T ze<)irAUBxrqv#%2X2r}98s=%g=)>JT&qP{O8vzfR>n8U6*oBaz^y@df{`mKJ=oGhel_lAJGUFlXu_d$ULRQ2 za=UW>`>RE`UbO;U4oV4s-i=#td6PUsk;VGQvT|<;CgED~vggCEoI4KT+-(Uu{fF<} zu@urRH3ysP8rE=?S`rwFy^Ovyv70@VI{Hf`1>6tloHv$Pa&QPDh9q8S?QnG$K2{l? zSv=(;Rg(Mrd!KMf6Szg_NeSKBM!ZB7UsqujO_53EVt%^xxWeM@8p0`lYuKp69wP z7k+P!J~$}Nrn~QWI-T{L5x6<%A~c+Pc-!(P5T)6L-~TT+t#LTSE8wLgT zg94K%eC&y3H5{$aLhp}XC*HU-R(>l$DrHPibar?z9PbHZkzVM0T>m}RV!Sjx)Q+P` zS2j=n>(~21WphqOp-}Rhj)8+DaNW?Er((YvA{I7FJzrS4HjoTLmsI)m94A)n;|2lY zf%rXf;5wnJ#(A27NS&fVg%KhdGO&x!?3eX61~*(3XXLp^p}5{(;M$>+6}@{bV?4Wn zL>Gk4YQgeLuUGxD((q|g1oah3x#O1t;M$;*n0!KK_`C0#$p?ILnZ)Kr9MUh6#FAlz z^)5I5>@4|q;97w5SteEzv6zzY`Whc#a;U9ExfF8to$(^WGk|3JO2Fi$c_2a)7=O#A zHNVzcG*so24Pk&!0)3TR^E)vW)($6Iyi4z7AcQ%U1_?0d72!1Wii^Nq3Fqv*IUV* zU;ZYh_TD3TNX+o^R?jDLF0<~tj5BbR(Czs?Do`+1eKUhCWyCTy91IP@Oz_!@rJKifoK?bt0I`j1`>Xa57P9Jqjr_l=yq z-;I}+KgYgtGmXFCV`z0eQs&1&A3FF~?l2Mw$KO&g{tEGA%1;jHj5_%$&B$DO*%7b( z;l}W(eAZy0Z_VEI>j0EjA_2xc;F&??5^=&gGyAp4)Ge&^-23GhS$`UHE6vbbLo`<7i%w%F*5x)HW(Bx`o z$}H7KTsCZ#7a<2k^JZ^K=c*O)(tgxFJbUdei0z6=DISOzkq{y0dNiJuh69e7B>}dR zXv(9~Dhsh8AS(^B8?$6PoQ|IcRZ=U^m%YLMhO34Rv$`3uZdC5=cZeeG0%6o>Ir}%d z7>Ptxg`cZCDu`ZtcOO%{2f67qkU95hDfhmi*r}ypFzlJ-RW$Z2I>ve?UhwvWn&}tH zs=*>C?G0>snaCK z?}tgiKv`3M3CAUl?9wHbfsjN#zE1e7AVV)24tRGqR4Sc zu1-)JmIvb7mg=QP!$h_>bUpoTmk*B2YQE~Ioc&>ORIKtU;;h!xG=8D&xRqW0oD4Wm z=(t{e9uv@edpxl6DcdPTs^c8t#ak(`*KJLDiE^MV8U`uu&~@zc`Y~EYQz>{V%AC)V z8JzW)_N3W9t3!->{tH_)TM0N<=-7?^F@8#=Gu`_6N~rMcMa!z!54j^p=K$NyZ`FKj zwlFd744tgoz$$e4y zHm~Aq7i%+>-$X{J5}(UaogR7vM3JpOzl#`ib9L9lSW@Z+y*g zwv&}LFye6)8e))@oevY?RNPVmBnz8lMq7q^9}r?0ZT(zTJRA9xUgnc0ByLa|))lyk zV+e-?b9fg1YVs)vvQ7uDNC$b*&~jH_C4DO9aMAL!IxCJeD~WOf&J;Szf@u$v!rhMA z&il&>etAA>1~23c(VsXKjA}?~(nV|lXAE6`LIkso*D971icZnk8~^WW^sk&xSIDR6lzaieJ%?_@2C1ju zCs7K|_8#q~8w;z~!t35cmYw`vOr^j4V-_$3)q`$m7n#C_#qjG-kEtJHaeDZFoF*uK z%+em(53lB{vRT6rKnJ?PWO_ceM@5L~>P6-`%IbTkN5*sPY;;m3Q3TMLz+PD1Q8>LbNtMuKxjPHbS3 zR~5SJ;MskJc;;@_ootgkAH93@6Su*!wupbCnBMc=OQ1CY?kRLD&7>Z*omlUzB21dK zT1+dl3)p%`ai4O{ZSJ7n#y3*{rwrYDlGv$yp6>-M-1bZ9_kX)21c)y4o}Advy~2(Z zh+1F)P7%0Zr*I$F)y5GtiPLJ6k4_DGk9~`LicRetbmW>P6H$H?|F^mNF?dgKnZd7~ zC!Q||h_k&2QhmYi^sPgnGBwqoXS#~)ZC~LCA_vE4R$NLIL)R!}{vw|Ho@bTmVKItZ z4~97!EXu=zijpd)fRlk0Je8~n)<~kc(Pn>)ZI_-bxRpl{fY%I-W_T4yDzFFb_D7X}fP-51|v1l!s0Ng|9_A7{zQY*4ms;L{ZCzpj>e(cJW5vb5y(MZG#jlC|gbNen%_5 z95^xP4lt0^WxwRsFko(;yWJo2OrgW9o>j48)=Zif;_D611x^GyR3%G79hXVu5xWN$ zZo|^!aav+0?e?-|X_rF*P(nahgRzCCSrp9}pLGvCr95 zjun+7PcX3k5?hM*`9CFKoEK(#pFcImeIZW?=cXM09oOs8h`uJ99X18|e)WehP2_H8 zbV^i&lc9qc3ArejvcRze7r@ND*fmK>94Z*q{Edp}Vr{FC+Z@Zz*C+Wxpeb#nYaMog ztf2kX1|!^$O}7wt@a^-6ua$Y`^&??cY%msl1zM!)7Cpxtl*bI)9|9#g3GVA$v8)Sy z1G+m~vuR3c3=z3%PKi6ZHS<4f-oP=!`l(3l40p#JZ?v+Ghqr5WrQoXeHDKDaTqSdA zkc$xb<^e|!U28d>Wb&LH@$d-KseM|iAZ7 z-?!UcVvbz=qX{Qf4LjHA`r^a;d)sN_$bnBOIbE}=1h zu6j=UO-uppGNWZ^?nWF6mdP#>iM@c3PI|BOAaJD6H8L(E2?j>_u*TeHI}bo@;L0j} zHya`&ti-*55fvk_2^=wWSI_p@QQDd@d+J$eXD<1?CzaLPO+Y!C72M!lFpX>?w1UWnghPnyXT5mt>BmCZD%I{A|N~XecPqk>U zz%nPcGE-98u-xCJ=YyBj7Y=y&Tl*=^B^^-;e2J+i#3GC|r2lMSR8pWA27Lw zYgbdLn(0TSxw%{)JinR|&0Tjs)%F^I*=%%h)Zjuv%)I5on)Y7isP{H*O7Dj{wwpVO z@3TdYlgaQ3wo3fh{h?yUB>iqxBma1-VG)|f{*Y_(?Mo_r^SepYm?Ek5BowJHo2#He zWZ3-ltp_5_CwR$>KgX{hi7UzHds>V6FQm9=7fg<-o{R|shX^l=Ev2x^;fP%PU$Xf* z^?{1~W*s&6I+54Mj(tcodjX6v47d{qPFx1D#qQzX)mxO9^v7T&Z(myA z4&c@HAYJ0iY9@~Uwe295k1}eahGp=W37f&Pf&bf!*P#}i!0kb2*THb}^2;^S`iXEf zZ|`kWr+QDAa>j-QT_0C+EV~O_6Zi#PVT8gRp6HAYWm|otVRgj)er znPnLFf!hWyfG|JC$U$b%LZbZC?KnW5e(b8|*me))vI*zU@c;=W+(d}5$${>JD<^eb zc1zVPNYSUZ7sc9bBi)YBYDHpHFTVP4#Xvk6&kha%1w>pr!+qN-eS5A?f9Gj4?{0QVC*-@4bwFQrcJr*QCY z$%RT+oh=eh;DRwVkC$i{__6sS~1aodRD~W5Y{6iU^?O}bQmu@8{N>D zc#8zxG=K5!)Ep#L`x#4Tsq_&c4_%h{SpxS3y4ov{c={+j$?5da`k9v~9{Gcq)n$j2 zf?|!U9ol}AR^VoV^D%gMto%b=G5UxgNWte~guZ%{d;EC-LZbS|#{>M&wh%c{reSf~ z_4R+Bq{oO$1pPDd*!Md~cWFEvwhU}3x%ARyUtIeMikpOP77ZhGR7GsWZad6tX_>RT zVa#R6OWmAW!<)!GMUs^dxN+!^x6iAw5UHq&FkVz}-%-ZumsoOCX}46~l>Zg%_vs1& zZWLDU(SrSemm4da@P;LRj%SqWpyvX~53$AUq7!CvQ?yL@iKtJ~=>K%F3&37*r>Ckc zt-q*iyc8#Sf`T5?NvHDVE>oAIuuc@IHHH=!j;hoNmaEgZ)_q&j6IDK{ePi0$8 z-viUpq}=UnTj9owr&VzH>Vy}&ib+$|L`LiBsLkt?WfC6u=Kfd16VYBC$V~^ri0L)` zz_r7R{bJ>jg^0dI>ifPS`vCC_lE&3PN+vq8F+F7^ZWdBcz)Shtz!pJqzkltdb7p^o zD!BBlHtVyrM1A?*(Z`jb)`?@uiEbrvlY)tfOJ3>jlO-;2KN@Er0z$wlsNI%=&4opBlq^ck)UsObAotfJrB2d5F%y&=;=i$Fc;Oa1<^P2cvb~gJl*yhCI4g8M~f8{ag}{)<(!X zuY~UF9UmZv?qtlMH8_hiMB^U!B3}DfGdD5 zAsv(Hnd)P1ToafUv;uDoD)0$d(+oaYDa=>MK1a_}gv5dGq# zwCt+x%|mvho&MN_CiJ)-j;uM*xuWpo&TIVm{El^QzwT=y(kSh$WSfzxM?wK@?);fg z3~*V{mC)ms91sZKeN4}@S}7!Cr|xRujoAOeeW&od>3LQRDsUOl?M!{XhpXS#9f9qO z7r|fr_riw$Z1^4imv0GjR!6et3&5p8$JLr)Mz@FkWKo)!1i^>BnBv=kO%C-vrJOVc zL)Z9JnEQDHT}%C&%Pv}>H!tO>2_6>S^B8&~5yUl07fYu#rmi}eM+96la6YLo-xl8@ zJlaBJWDdCt#}|D!k!07~CM|NKxzIHv`3Y>VO9Yz^lq45Wh_(;ZB^chl8fi=>I&tNFmi z!P;qbHy+YtU*sEhZCqPfe(y&nIK&sb;LDIxS8HDQY!08BiGfZi>?xh!#8aJ6OrOOi zC46E}!TGCjLa`$DZ^!LK3Kw<2MFAIp=htX!{k)x-SG6^nJ8ARz+Y0Tez^B;(ZxFQG zY94rff~_wC^JkI^+6xQ&ZU5y1Mk#+`y?ZruVFD*SRjQ*=+IQ<|)3-3w6$V?Mu#bzL z#6V2${hx_x-DxwchCO=e3|V3cx>p>M*rO_Yz=gp2MS-V6A~TuU-xZK&47_8w$5*#e zOme$;Je{r`bA>s{4csf}8dA%~2&#@0oA9TVSPWO~zn%V0?P$cjyyWAM%%RDFtvL`n zVydnUpO+|8jB``sD>3Y(v!vuQjJ;a>J>X%b^Xn2ABKbq7Sd24{+(Q!`ywQgpf{lTE z{wAI&0k;~BPb}qz@0i#HIA7@Eq!bM{VwQe=XWV*kdsp~%A6+H4xgbgLu!d#&(1>woF{bgye%Dq8jI3Q$wk$; zR+VZ9%fw9AGS?JzyRvcm;$H@UbB8YRBjOiL`+2L-e4mQZW@j4iE#-=U^3=Wqz3N9n z_wis(#}zt}$HI-bGTFC3G4FroL2SI9)1$!sz}Lw9Syh3y=S0p6IA`E|Y9l*6gu?nn zNtB5uP8Kn3?$F%kgjV&_Uj+8?ZG^uRec)vP+rK2XS>1}S#cgkUpp_ST2*_?46b|@ z*XOA?a8ye;_gkK73qiAw$T33Pmi{=!#=g=Ld`+eV~Nlk7SXFV{-4GXKu zc>h!dw`x8bm7qP%^AfJC>OuFpK%1?80K!OxDv=F$^ zr~{l&xJVX#>0;v1kD;Z37UqUUOFE_+q0?XvgP?!C{cIIrX+sNqp_;u!e<+@48V^r3 zg1sexL&oL@r!`XpASZ?TaqRsI8erKVD9oKI#d7ug%VV~oq zjOc`4@qO#G{ti=}G3M3-oPr?e z`5v>>JQjN}+$3?+Fpa+CnL-*|;%-y7`w18Jmf8Y{{lpwgw z97|L^4PJ>4DXi{O7pOVSw-qE5qpipqdS-r5F!d?M08SDdH3>aIV$XO>GAY^AEkVzi zT#UE7cfn(q>%(GX96oOW+F#(rq2rfzq?R$zVB=3hO>(0z}t`hQuH4i_vUr%0vBL%N1O~ z&W}Y|&u7U@Ttw=#Jl*FM^?Qwhj<3OLbl>iz2Y~&|a2RGS7D*n*T!bf_P19F z@5IH?6vB-+o5cj*RhA}REe-+&c>f=VYw`nvdI9MbOH{e+#$y+*Tl7!FpM>q^d=^Ndx&N;}c2aNtN_^&Vu-x6%5P zIHWlh{f$w=AzU%19~FEfz|vX0Cce~xE(IJBbdMyMri>o^@>DvD@aQI@V5yA4yg?h$ zi0^RRqtcWlgE~ZNWcBnhVyu(AVDk&l59{xizPovg&)(IRQJYDY7 zg&kv|T-qfmf(qo$!~&!H#f%H@cTaC!$v?l^uE1l%LBIiDWP0oKHI5Sz3uy|GuqR>K zbJjp1Mjd=B^Z8=%y>xtYTs%%}1T669e*KFjT~~)lV=m&5bNc*sim|{oKda?vdgS6_ z)$0UB5^z)uL9pnY@ZNvi*D~HVOEVP7pS7rtwwmojYI+U%{W&HIpQUkq;Lt$r0vu2C zS-r*_3R{p8qJ_K8B|gjy^^M?(J}fn(Z<2a}TlW7gCck{?Y4bnfF^V7zkLTiA27isJ zX$!C}Be8D3zgXJFvXev@;}X^xzT0jsfmu-`L6``uV;E3qb>Zt2?Z|v%R?hbix!r{I zIIy&HAnf6|2!acoBO-vFvS=55C-H(Y%IoR6J;$6z_TJt3-piKzY+MBHAF0Z$+5o#1 z0F9v=V@mh)TfN@OR9aO^LxRumvbmeM`$T^ZTV`gP?-is1cOwA)ykp^4ee}p59X@6V z5?%K_M;>^`yN_f}Yo050K^qw-CkXRWrA-QqZek9BMgrE?n2Ck z36HhdD}lR&?iFs^i=93--QP&BcvrZx#mDVq>bH^V+Hm7v53Y#+s|W5JI%}$N@r=ex zqSMzkp0R<7AwBB`t%F-LmkMnz6+KkVMZldx_tc}y(@MD|E`Sg*nU0vOPwUX041MMm z0+Mii!fU=VQ{YaZTPluY$|RiS;J{&dwtwb77`C`=Wuz@vn@nagqVX$a7Pw>RXc9#$ z7+D)uSAR>7kf!zvW%Xtee42h+TR29CSXjaU1E@pjCSwANHff?ORmm+ZPq+ka{F}4B zHSXsB;rKYj7XIWpTm{>Q?gh~!xhf26=FKu*aW;f%;dg48^fSJ7XsK2fOlxs!9l-5E zhlthe|2%HXxnA~RZRXpWHeR(JT`!D3Hqn+9B|kB4Vd${~oxq%K#OcI39j(b%T^|t- z3z8}~MO_`WzMQ+7+g5X%E#S6*3&6F`Aos{_o;A~uAQF1aK;f>pLK`H8cbG{1@|&BH zF8st3%7y?KsCk_XjzsjB@1f*Ry$FvUFlCKw=GnkBO1-*PvKB^@eg_I%g9ko$xa5fl zM))B>AWo?j=)wL#qM>Z_Z4Js-DibNj1C?jg3N{dD;hKlpnzP zq*y5Q?7zE}Ea}vi$a$$ZxtB-k%QU!!`P?0mFo3#_(GWakJdX>;%tE;BRHd+=RK zqRFq9DZ|5_G3?zcO(1Yn&?&W~Jql|mXRPj*kz=3ep$%oALeTlyyBzB0nN;mCpbgvv zbmey+I1ebfM4ve)jkl$sPFpMInPg_EeQSvM_j2lEJ)9GdLHB%uyD-9gMu{{*X~dJc z*gCvRfS}Uo?J5D!p@mq|7$$Hd(DBDor;hR(vOeq&qkMI*g_UdjVy%d~Z!Jrn{tLZl z)ERI?!1+upI!Y0!zuU)qBH$B7`)o|@#7Bnp!#(++@XeD)vfAV903wvcO~t=~86}))ZPa&5R>3Zf7q{4B zLd?aP+xNqN)+u}eN9_|pjq%Z?ty1f-+P4tndWJi#)b;yPiuoJ1s#IY1kD|G^x#s5e z2;grbH;i(qoq4ycIp>`?JPb6h!Lm^o7!@kbx@DNf9{RHx z+_HLANB(~ND*1N&Y_h zey`d$-D5wAc7gi{uN>3Lzm`kwu4iv%(4Kx|be@w}r@uIO?-$7wtnH=!WC2dpTA_>Y zq;xmxMa_^RBVu5o7BuxYJE|I1yp*2(>e-_bTnYDwHbbYYn)c$jJnjSfs>`DSo<$Yu zg#MNf-&{A(mR0NdT`C5EYlLpvhD@mQ>rD9LNiri-H!>{lN+e+o!aqrdSJ#@BLt;L_ z)k8HESmLS4DsK=Mx4kRe1l!(Q<@-rV zwdU*$Wt(H}9aeHx6p|*RxP#w?vZ|V+$(Ehxeg1nyyI25ZW)vp4yy?^i@;JP9iqr<0 zN)6Rw1ICg#MXxI`N4`7JDuLq`!usj)`pR=4T&C4^?{oAsk-Byg>fz2?1>dQBU3YNA z%Ki*oK5#yre^@*vuf$e8+>XqF768&>&J)GAmoCKJ(9e5C6#uc zh)`%-B+X_V=j7VFs8(e}u$KQ@i=zkSU^`+qXv-5_dC#u2<~C|%-3RLw3G9h*`BDaO zSD%ezR?@llqsW0{X2P~iI@RpR^yKq;s?kEs_8$Yr{Khzm{ugK6;Q1##=fSFF;L_na z;RVvoi#RP%4EZP4_&+=-SrDkN%!Hc-kSYX4YKP$SjV1a)0qSh^_t3TB|=N z?E`R0(8U>Tx{P&oMI8v>GM!yg1^MW?WyF>fyuEm<#?pZ-?g(50a6Z!X#%PF`9h&0X z{%HCK!JW$%HCr*S6YV{|p?#i^=Qb}#cnw}iTg*S$V^PEM#>R8^-lFE&=PyI=d!$Nh z2~4;=ti_g>;r4)7I1>D;=@l)=eN3U`{&w>P!9Dj1>!w``mLN$(SMR5}KKJlSF%hD{ zP(YV=FYND7bK!}b7+L2~gLa-4c}h`pP~Wbuj<#^``Z_2s5)>COFx3|xnch~J(LxCF(8g1?r3JJf5yfLv-lubr}qjV1b{uHX73iF`|2+kwHW88?BgeLwPG;0H!jIv%HDnbN4b3R z5|ri#hdtq(2Fwc6NTYe}=KaUXTb}l*ExLY+o2kdviGQ+J@?lix1OM2aB|Mzmj@9^H zK9+x6WeijVli)3ogsunYRwDO1vj_kzS}cVvwVrU`Tk~cn8*#zMctrV=;g|n zj(3{0wAp)w;dfBhRxfS;GEGF_D^txEhia+~;9P+7*%0r%kUM|XWrn9els3sng>ftCP>z0cQ&xyF1&xJ?`nLEDYYQe?)T&8=cjL6n_CjX@Q?WI{kc^06{^KqhL!gx{BHhmPlNs2RHLtL;< zpInPRU7VOAhhm2oC==lwO)yUEB!|BbR!6#4HkdqXL@-> z(P))eDs}+IJx}=;w%_KJ+b%+Lp8;n8ox0WjU~~)Tf>n0FBSB)zH`%d&1QV3*4z>%y z=7jA<65#ZqyThKSKC%40$M-}e=32*8zs}etQf=|}T_W~*Y-Ixt%n9p4m!WH|^Ju5R ze#JNqN84tCH;SBkRM>kt{DCSRdy1uZH*ng}rP2K^>(2Yd%IqNEInbSq|4$+BDz9tH z=g+fog?Y9C80|iT?hk&>Pi(c38H&H1jq^MVp`^a3w)Yh3^i-sYf4EVpP6MX_-BUjQ zdy)cN(h5bdk0>71&?B6Te2{wVd;h2N3(1-1JBYxkL09%_(^c(Qszi08ygX~@gIr#v zHOh1ax1Tv`vMQ>~+Y#VYpkwSlKc%pXjH3RBsEvtc$4k**T=XxY!%fHdSDn_M=xyMh zK)3vP>>*!mFo!@I8F-0--z!%Y-H>#%UOaUESc_Wbb}itPpj#*+`08w}jLB9d*Uv_aX^rR3_j+wzc9LJd zjsN}P|BH*qt$telPh2c70OR8R;sZi*{bH9N_$Nd>36g&U#H26XNSAkO^4<9Q5V`%p z;bjG2Ts({0FrzSw&md?N| za~2Hc;p$n=5s~#SCZP>EPmEmJB*Rop$nlOBJICfY~E>V#?JT>C2lPTBL4zV z{J%QlmKd50e8IaXFFkHG$+uKBqq#+Lx`t}pD5OrU8t7X9peR^877iy9EoXjj(aOmG z@Hy3@rr43=SDI?IFI;|}>w&KKVQN|!-cl9kGoc+uuZqqZ6eqvGEH>Dco{-5izkU^8 zl5wg;nFnK8LHHNe#{6BVe~Z`hE;tJ%!hL@-dhN@ZDvxRLczLHwwmlyl9r&T+vxx~v z4|`^wIq~x5I-}R0m$hzGeCmcWVM5ng5NXb8=|6!s* zzw6bxh~T=805;AVa6Hh3I_gCc{QSUVQ9_DMcRZ&EeBhA(7)u!GCQfmJ$K6>odEokWn3Av5_Ih05Gj(=WLgfCL)uVgFqwg#okP!Gmm&pQFk5eYFbsav) zJnnpyorQ$brQI53Ci>vl7md!$(E=c}lytbYLyxo@ewzlhA< zALSkF9&IHAF{8c#m4nyxjOgHPg)>RKmf3=h?kdj?n`Q}}_^`eHivM=0rmiTs!Wl$X zqWNs=q#|vo7_S(yjk6~Tun<$`*B5i^lce%c+g1%ZraHWEQ<~5xg!Xj(f9Du zjZI>_QHX2AtdTp!qFMnC2fCrirN?ggL@b$PXBflkSg4$_`x0Yqi(u258QUyd-63#T z(EZwp*@(+4TZ`P0_oZ)8Q)rvdW#L~q6a68#A1q6IpbH!ZbQpzHRW2dpQ+w>>rR)+@ z?0jU52a6YMe*(==2e=1>U`7KCxM(~jE1z%mZjET&r4gh|3Z}@mR zJX1g*V(8RGK;c+Oat@pwa}u{z5?Sq7qRq}~^?s+|Y(We@1B_U6I=(wQ14=}K?XRzw zfNxA!@BxzvPU__PL#$`Cc*>F|4R=O&Jd z)wrkN&Mk~;kD(K3W?9UkYF*IMLmCnOTK}o!?Vpb_kJ!SkMex6kvo0Y6cL*KtNO)Iw zSn@@!#5>J4fy3I*fG;w;Sn$Jbp(WzoD104JrC2I-QN25D(Y0Rfdpy1N_c5~V?q zZjcZGK^l>kE=lR`1_9rh=j;ER_v?LrXLfdX?%BDnnVp?w*q$%3LxIyv;4LX|9weBb zN;H(E9l~}0JjaDLHo?ws{#z0xeOd$EX>E9zIn3@ zFVTNtjn#EVhO$3_(@>khd7fzPxQDypZqm`sGRR{T4}2%#@wX`!6&HKK&sR%@Bl!Al93wxm)brmZmZ;%y#JCC)G{uLRYaJFHXFM5n z-`ohgW{7fiEWc`pvAZUmPSfHqz#-2v4`_Zd+7Cy!i1eNa$8}k*%$@BTcr8418!cP= zwEi#%|Iizz%NF5jRC$>@T->h-HF3K{z^4+FaYVc8(Fqy(@lz{OPc^Tp6SxKF{`Ndl zDYP_XKDY{ucERZBxn=hVio;d$3JyZy!WVc2lOS`@m8&yXmf|gRFQ3$W6|OVl!I~<< ziXl`vG!1<#Xnya`9Jm?i4ut5LUktl?99|H5p63v2)OT=4B`?1rt8pDBkb3tW8@S)l zEhw( z{6%Jh%BIGU%rrLbQpV)62HZGwd(Dy}*>eZtfmePd50=x*v{ox#Ey<;C`&QKbF?k)A z2iz!h|4u8q$W659bV?6AClotmXS#}AZdktMZodtPCL-*I@zgMIo+Gi{Z;u4O@Jt=@ zrZ3k-HKK&i9KGsG$>XNKEI{Nuz%D^Y7zC?l#NE0q+-ri9?0fku@#V%HSlx0$f z?I*YGa$>^$t*sm1^qQ%E{YQzzOS)ns_arUMSGV_J{-6iCnR@&;B+S1zi(@jQzUC-v zVZ1O}3Fsg{WbTt3>`&mG0j`q`G`|cXQ?ezKlZ6k)2g$0kf@~e1F}}?sH=S7<)n3-< z>L`Hbhtk0Yb}F>fz>prW))z6B(L!flqiXfT)20o>P@$L$Nr>NG_=p{aj?fNv*_!%+ zSwG4B>eAQuwrQr1(}cwMR=};@NGp89s#hsk18h*%3e^2zU6LNFhyR2fqxQeiMwXi- z=qQjQKBKQI>XuM0`T|rl2)y;Dm--llY-OirMM#WZV0DZ~6`>J7obJIF{A$k=jZO^C zp^**j#bsc%eE0YPOPD}WSV6?(ugq}Gk6UQP7%j$$6<$>L)0R-dYQR^qb?7)w>hGug z;&)RB-7at>TZO6Dc7{mYGAz?P9TZ)QKxuVs;7)wYoyU34NrgUxr`SEl?S5|jY)F%1 zDpVhNYVnYNEUE^$T5#oJN#6`fy{GtE@HE3%mdE-2uCLt7XD2qM9~VsG9s9YZU^cHB zy1Zz~*|$$7q-w+@4Dh*r}bTe&MLR;3X2#3_G!3>O^ zx+qVLhq;mwdky5&qtZw9qJgUf&NI5x3}5G%RcIQOP(x{)ID<>l_it=juYsLxSWnFx z7VNj^2<2dA?p>!tlc-^5R*nArt6!VmEw~XM3`=pEy0vOq`17seu+=cYXNwuZxDyY&bRy82o#gnoZ8Xok8bz9z zzXq{mD}_E+n>`5}`aB5gRs`-u?DHHZDeCbz-!#b!nJu_2p zj|8p&oP)1mM<3@3BGydFD=qErpoeYCZ)bO%%HN12)QMgvzCgV+gfI9cb=(6Y{_{E>Moh9e9Cs`H_n|Q0xk(U9@dST(;y!1 zia|1ru#dw}$VGmjTvk}wXX^xs>g{}h+2I7}#@ zfc@I!*$qL|1K{GI3k|XIaVgWgu>96kSlMzde#&?0R*yj5$ksH5K6HzU-_nq%HVyf5O+SCxcBt2${61f3 z;t^xR(*v9jygV+9Cc2FyI78u9vNY@OxH*&YhdS9>j`_%u3QJmFmAe4v1>HERHXT*) z`6E|Rp?kJpySjH9mNC8#GEMDL4*kVOTT=$k13JYk&4hkde)P*DgN#`uuqLkJ$}47vMZS zrL9@^3<3qc{$+b;S`%)`HX~|(+_9ZYwY|=J?O;gDh~NbBf9DO1GxOXePGJ^`;p0Ld zO*&RTYJo{t5YBHp%*!p%t&>yaWtBt)Oe%KrrUnpTgc}RPW8I)=r>JH|MUJKGkoC z$1N&)_LvYj3+O}){S&<3rhj3+r^|u5_(kA^+B@Juy}qdEYW-xWK`jArX2AL8vWNHv zA!a=7ozyJ;k%h3Q`bC3Q_1{ln&vLSkTCw5(zCUZi!X3NZ&4DOQW9v0aW;A`TN&LlW z9M#`7VoaGK?+RI(*}y>^6n9XY{HsF_)BF2M=5aU|XW(op z=Q?l(uznPiVhHj*v1Wp~be30`J{MFQLw=vT-@82w|1Fc#?G7J;`p`+XC{UcsIVlI7 z`wJDa{Z;Uo){lOdCw_O>lXzkyE@};&E_6%$wSRC7^tqE&78ERoN3Fm9bi4m#2#Iaw z>6}!Qsw&J@XhZiS-=w2DUfpctEAbecPqH=94{jffM;P%+>8&4eJ*z$erwLta(tTd? zNt0+nhTHxfSqAQ!uce=vC1_iTlzdAPaB+=+dkx(_AI~L!JLB*~6Ek1%Olax>v%2$p zWg2X1=aD*Dk)k)iy@Za@kX7L6S@0_*;ftcAPtTUQ5&7mFuqICjSt$zN&CA1try6vl zuOg7ovPv!<8hDQxvc^AJ%zXRgVUx2?sM1G%2Ku#I;9fxYYMj@nO1+AY`VR*IW(!dc zr%_u|Vw0TUgmJz8^@0SPs#1n7SZ;F5Il{n6{TkJr{D(*6JgQB6Z1?WqVSB+dl;4>L zz&(e~uQ>LBbaAs{O?Z`4M7P}Qk-#4bqA6lH2dyncIw6v9@S*@+qe8zL)aN(m=!9~3fjZIEz{x>JXvwj;5T5j8um0wbf}eu6=-UHL5~AX}H&|?+ ztGtq7qE!YsUuy>MAjy$?qnRHki|!TudN%sLxhU%(I%KjZh33gs3o(39OM~}7Ex!)l zZFf-Hyzg-QYhBv3u6(taJ7(^gV#MOou>FGi43sAc+uu-Y=z3_12tq)c7;l+k?6X)Q zi$Xf)FF>BcJYaDovy zQRpU1W0Dy^YByCru((?L_6Y1DO1oc~e4q6DIb{v;#d0}tBG4I_E1DL*Fk|sFq2Du? zsMbnd8?v{Na8Efa?j`??#1ssi5OAKt1^mAXJe%I+Sj*>sk=+oy=jZ5Gu!@a}ltn9W z+D8E<`vkx?>XN9BB1H&&5dMseR19zT+%7A9cw@JnXxfqVoQtN|%mb9h2YMk-p_QKP z0Rr(4glR+PM{~6QPLuC5U4iG%{u7jc9ggbY6HmOLr>`}hm-*C-A~oIKLu#6DH%gQL zRmL|ihU%=orIJyn8wSwauus!6*}G6v6t8;pC)(Si5A-M z;}@)kP^5s;SYYjZUI+YnnM>^rHnU&)l=}AXZ{Ln6-6^u@@=WggtS)&$z%jw2eon^C z`+nBy+8d3k9#_Fd_UzcjxP_t@MR;LAqJkX(tTAN(3#${PfB3wTREn_|oI}J|UveLA zd|3UmWi>a=@vp#%U637YcaK0+Joc_7`cmOIcSeSZPL4RWbA>PeS~N`3l`7!P{CzLP z32;MXOmYL9n z|0JhGDX8qQjzVi!SBArldAf$PsHuj?O54nlW;W~r-}JEkY1=hA9L3xTCy${I8u1W zjJ`1QbgrU&2)egEcDg<>T76S=H#dhz=ki5qr-|7ErXn9gmnm1M;?<3n`IKae7g^_2 z)+nk4Rk(0o!MaMvDG;*)PCpPqw}V;lwr(W(EksNgw-L?c2lgxf&55+A2DQqudckpsMdi;n*KdFUt zZWlF4{g^#MvwX*vptvp&4ehpvIe8h4Jp^$?Fj|!zqWqzcWm8UOc0XuqBAtIg~|q_K~owKEOu zFD{_#&8%Yk5Ftw3`5X1cX3Zbp+qQ2{sjGr*?dTQoCyzoJfIEZkWb#Lw=w0R=T}+YR zxfAb%@Xg3^mq)|ND_i0R=i3P|b8`Zn;LbHm!|0e$+ zUSd?f1n!6xd|XP?h=a=OuYGwl`AUB9RqkpCqG!V9qjz)T!HmoX0bPI{fW$fmS6!c# zR+f5fh`<#O(q|+|f=3eS7_EOvHTYY-G5mP|+hYZdC7+FKxcITA4=aguj0IA=1=p!i!Z7@4(ur5s2_pb zg08_F;~(+lYMkcFBGNF|Ir~V`*obWUi?C~TbpojkAzR=!fCKwE5`7BV-@PS&Yk5ii zT$9!4*t?67|My!ivMu+O(k2*>uVIY(l7WwW%A5APB>a}^H5L*GbwSz}5O#bkpyNXqEff70jC-$QfsfCk{%IxJ{&_t&+6yv84_YH zufDol#;iB5eM~uEf6NKEdFcLK58!84{3(0z?8@?9c3{9+-H1QGvrRwv>g3?;IA;fN zv(RPRw0zRS_)YCHbN=|l72DdMU4-oJrV-4k#o=VFu-t#ZO+)vgb#ii7#xvjsUJ7o<@~PK<#S3+#2N-PfS?d zCc9~fRO_WfOTCFu^0QLwrc$;`MRh;9%h3(#Hm-mXIW#{TrsRLRBZP!3g zrAYMV5h$)3o`yrNg@wMnINDAm(%fa4-c@I>N1veg-6VlCE^1AlUm9?o;IO{DLR=l4zy$l!VdCNGv>-bFh|BH>oWPiTs#}#k zFBcs8%WZW?<}5bU1l=PNx*`X;UG-_f;oDhZY&<&}vi)Ak;@`zgA)0}_%JHCT@x#U? zL>3D6(S@CVr1}81f)SIn0!@r*rYYLhz{dyK)siF9wcmIye*squofbDw2px|Zb>Qn2 z{LK4^^+#Sd0oI?Fn-qRjIXE;}`T$oAosF728+npfwwTm7tHle1p*~HSbVEB`mcgIe ztRK~6Vf0i5o$RAH|2oN<%kSeStji&z*y;u|9Yc(D`HM^6Y0zw`;Pbo^y4N0mv6hnc zSo1jv!&ncvh?(ufpB^0Ty(6Vqz!5N&gCogu=$2=WC$$#R?lNVl?pf>2oogPZtJw+& zp3uBlHSMzyVh8RsbWTr;UB<{|F>RmZ^8Y#KqLK+wopzZZt(#o*!!w&rg1P?^=vIeG zge)o|6`wBAaj>hU`H*fbnCl%rbYCR%CNf=@Ob4zAx~=$hO~+chNmLd|U1Ssa`^dRM zjxL>>qXKxNYoU*y90OMXobQPnUkdGOAE$S@>I^>1G=`gU7SD^G9C4H_@7?#on*ZWk39Qo6(tIjr!qzb%UiCa^z2S821_ z9)(-J!cy;PXQ9hA$=2}aQK&|rh|w>u-v3QP%w1CAu< zW>v5|^+gE`mh>>*=VS-u<@xita#22MF&-52Kgk}1QD6deF`OvJABhIgU;4<_6{{N} z&wmOjd|99O_fR#k`5tSc9&mBc$u3+cC$s!`^C0bps_P3GvVEb^Q>GSKsnA^p)A~LC z8sK7}!$p1VR=4OUs%5OrdP;EqIsa-V@JpviC0_Gu+G#^d7(cy-?jhIp>rXFsUpV>* zkstFieRY2l@s8SMsL*=9G&6>#aSyn6z%s zLzwH{;T4#N5D9jvaT%a3Mz z#?A&Gmd7?aVJB&k^w-yqXZrSoC@>i@>m-EU*dqcL3XU4!ZFvyb?V06h^MT>|1$$8~ z3Vwm(_bqkmuHJWHR&0%l|Lsx}46@j=uhpDxuI=*LB8~3SO75Aphen9Y(7B1|1+iua zzY7}y1qQ6tl?C>I|K7{@gRY*tASvvnVx}#dvc}+NV&bv`vu9QQ zUq%s!yL4=GVqvrL`LDcw%Bj#5f0=-EqymPfM04dt8qDDpZi8UycAU#ILp0#Lpi|8M z%-$us894r~PvbHF@i{iFD4!M`@h4r1k;iBhFD-%dfR1CoUv%O?A0<*kMQ%OcapijG zNYjjg_1B*}WEzis0T}kUL8pYs^retW45z&CmtjQi!4UJ*<3jiNQx3d|1B9(KN|>>A zfv)kkX$yTwts+H7UwD-KOENV_(vVXrg4HR89)G08IWKTd&|P~ipAZc7;M#W^$kn^# zhpoQI#tdBu^15X8b!$!$;6O`+KCL zd4&h?U*wVw!xWtbbg^Xl7GKQEjr-EBKIHgu+VCI575*zQ*$hP-+T8!b{unqj;C!D> zwmHw{w-g$8_6R<;D%&_!-V1naDmUpjQXjKs8yN{liY8#Gp`~^Ti@%r5_vI9tPYqfl zX=$-HSy;CBdcIk)@(w#H*MahkVC&07OVfH_LE!j#rK?vpw?Kl*<;>L7TKWn@&X1jP z;5ZUE16aR(K>=kt5mWabh3z^fQih6;7jlk*SRR2c*yXf7=$$aNst=v&(%hAJ_JN)S zvua@G9l8jYTsk9mQO18Vz6Iw4uY@+Fo?u<_?vLyoL68u&$P~^>xre_M=Yv|B1{;aOWdhaRn9yb_|-Yz2(+nRJ; zTs-cf!_k!`Qfmk9C3MVZXLzPzrVJ`%t9Il*xc3!}%U@G_awwljSc<0WcS``L1|7Qu zBJqx5CZ;Ukx}d<opZ!b!xek)NV-f4| z$1cBJn6W4Z9BacA6O&!i$r@ByAA-{4U~A?TCeHr3L!0^M!vlIT^EG0A4kWpx_X-*Q zJ?O>qXqYgeBFz9=pQIq~d%_+m_c`0{M+qX7bjh@OZv8QwIT92G4JhyNVS)xlk^#KZ z^sO-OW{ip7Tka7;CSh#L#rsy=%Eq(R_#(5$$YoUHRReM0M4_w9o;;%r|2cuy9nfkgUZ%KMx@FJxt%pD_p5TY1 z-gg)^iaWhjd1e` zMk*s)G8iW6NqjRhM0FOc|HdmFLY#EtX}V5 zmho`+FgDYpt=Wtsi3&g7PslVi`$+F!P*e>ZH*{{ut@_xb{Rfu*yuz}0Eh|MRakn+u zRU6{|Nh5*fD;U6WLU*I0Q?54VNzYWp($?I3Gp*u)T}HEOkSSMevb%g312d-V(3P$v z(Zpp6mGl^^h*joDs*ewtTO2l=-O6`J6*O;)Q~<{coTu>H7tw^_SCytcPExhBh@-O^ zgm_i&5|I>!_Wy0GJ_hqKEMVJ(^I+O6tlrw4LgjVWZ0m}YquSU4txlZL)taqX>Dzdi zmu6xBnNZV2IUQw^afQCJp~;mijMN91=!2hmaXqDZY=}hk!@%d?8NdXsEdTPN?xEN; z!a}*EU44McJ+O)d=1gZFFlX6X*yH-SuUuiU&#Qk#;1 z!-Ho*Y_^=PK0;R>?9$o#TfXv8OtQC`?0S@mCN^u6-BTEBxqt%#&}fPKx77y%qsKG6 z7Ws9U0^`Wc<=sNG&Ld7I2uCbb2B5SD@GLU$Py>sfb4rt5R8rj6BTGOClg&rMHF!@z zag$Cc#|g7DSn#M@-4n*;xeRH$U#ICP*fGrTNKsg+E>nfmR)5Q`q{o2$wJ|{cRlfq~ zcgj7Nyu0JQP$Kfp&@A+8bH=u`sf+j<|FBtdR8SfkJnGf8bDZe6iRSO94I<0dPE_RdWd}ypmA4Q3byYrOUbmzSj{=e`z!>U^Bf5Kx#1{fYc zExo%TSEofj9!x9TviL=MlkHc7en@rdxQ|+<6UlG^4*!oH?&!y)GRc~q?wY<%=Qn=7 zi7H=loc`O^tH`={u)2DB1oa7kxAbr^bQVg+7opoCm50{JCK+^j<6LXS8PfG5>>1zJ zKIu&#!aw<6P$HO&=3zei)pz|C7loE7g=W$);yHtLp{%~H>ocN<8fvBRzFdKT+sRqP z0HYqE=lxroWB+;e9U?J_%gu=UEJPo9Y0Qa^ZveZX2N#@R3b~NMz|=FD!uYj03x;8_ zPlkn!LBdi#!``J;e=wW`IHLy_{Qjm&D3u#~dsj}ko*VVP@Q^gdykgVPRu+BSyL*Q; zxWJu2C#l+>;+TpiTX1uMypbU!SZttn{vxHFc8%)d6~6gH2H=jMn^g1CYC8KcFe{{d zc7d_-c#|eoE4mz26A$5Aa}rmR7jOsA`R^2WebtuzP9xG9;Tji}{!`xeU4@T1(M>dB zc=}{E91-t9HztQKLyM183U46gVj!h{ZkSbO z?B63r4gVM@%`@wIE0i+y9F-lrE!wyWxLN4N*Z+DqGpO|6N7m*~&IxP!gSwm0Ul!_` zI8H&)WjP6(z}*w?CMY6VHKdCbiKV( zl_v_&vu>Z_un6h_ZVb97nB3u*UtT#Q5-Aa^);h>P!mkrI^@-E{X{5&NO^BNg+z4=< z+f3^jt98EJ^u7 zUk_gsQp#VWy%-Pvgg2B3x0aMTRm#A1L-#J{b4|F7PZ!;o(~#G<3XN!A;#M8R3yO?p z9m~#X)e_)3p~K4Tl9qcVF*sN7dhyKZXqu5ns@*|Ad&0_c*o=i5T>-cb;C#PD8>`B< zq8A!ZOk!ToCHtnBMy|!XKj@f!-1~|79p)%(e(hlO!e@Nkk|bwYbf^7~sM<-q{V!4d zw%B!^Y8ckKU&IxV@qzMMVe|W#jUMu2aHrym^!uETSZu@gcak=7t?*JItHnVqfi@VT zG{gGYjoAfI5$(JfX|R2vMJsG>pp+drf_E3LiA9~buK&psxJKv*?`(g2y3f5KOGI9u z?P3_2nHdXO z7&D?K7`@biXW`Z->L*P3(Odu46Wr{J7hfu5JW56JLwv1xny6h`Hvne>YGEhIuls(s z`6W&+{Ui4w=?z{)=bd0BJxAX%+cOsYS}}z8z*WQAy}eF~n5^l0qQCxRP&l3joW65KSlvAn;$Qj`Bz)^j9T@$gQ3sBQnYDFgE_lK2}j4fM1bfvIgwhg!I(KLuPB&oAe%f4KBxmJdJ8KdQu#Xc7u0 zzYx70SzF)!V>i~p1C}->fya38AOG+(<6bG%$gd@%pSCcZ-}6`C&>E%~nyC;Xx)uzB z(h}e`X4E^rqxStf_a#21w9~Q9xUr|2WUu@^r(>EOnV3|rFmQ43T!pABwg#RtW(}?} ziP;1y_|}o%VzBAi8yE>B&}f%r!~hoq&vo}PDPyzbrBZA-lG@v)dqM;)x~c;f1Vhu#>mRX(8H~Xi4Ib|@` zJz)}F#gk31H_n-9ngHK84+o1q138(<7*k$0;^}CXh&8v-$xGrROow5Av3&4zor_QE z88~JrJy`7d$h+&;y={H}2DP{7ngR;0(Z1@zep`ah4J>?j%Y=hSzy*Ud^?fa|d(}K` z*Yfwb`anH?)7iOUtmlijWsXN@9JYAg(KE2s1%g(`FRNpfI$XLX8P%r|6iV0X>67z& z)=^wc{F1tC>*n_;DDN$7bqJe(&U(rS&LX{M18t)lOiIdKg*cHJKTs?%+M$k_(*x%R z@5FfeE6;oUH5Le|IXM}vk&SwXH~*pyFKFL-%CHRJIynI616?cPDOF^f6vodO?vTb* z0)qB2!^vt=wmUiTzC;>+bJ#O_LHBq+Q7ODkkNR(fay`#Uia8%QO?Iu7^NZxAf?YYf z#6Q4!K&NZ4Uz39qKG*vXt19Pd7N3mcbJAui+U?Cn21U`PAUWXNpz9#CHx#mXGO388 z&M;-Vt6WCjg_pLg$zFb=!%a1|a0HwSblJ#fD*qmtoIZ%xlTxwYR4)_tK6=gRmOg>$ zGWX^?OD%9t&@E;OyA3y@&k7Y@kJwt{+`mm((s=&Vi!f$j2H)~wS08W=&^=eW6-tvJ z{wNtrVLj*`7O0AXY8Ml)tBdaagO8}1w*@#m;5_|X>P^SBRI8%Y4w=|6**#wp`C~^9 zGOS*DPInm85r7S4Z9qzpH5qx5;P5-HyvbFn&QlSCP!-R&qfb6nahc+liGSb-1*KWR z|Bu)3^|~a_OM>}>E{Q+$`Y*Qwc9p6+I+kai&9an~SHPIv0@lvZTnj-~S%k#web9ER z_}&bWo!r}2^)p^{@h|2d2_KjNX9nHKozm}Wt=}PpBtK|-9`61)`fHt&U9`L>Q(_#( zcz#U_oC$EgMK@^IUb8!5+JP&TzOTOUe9oMSo&juq`ngv|F(?#!(>k?C3YT#<=LNwJ zW4ppu!%QPwNPyFY z?k*pHwtD7=hSOA2-b_cS9#bJLU5UrlmNQoAH#rtLG2pbJBlOT>_(F`JA@(MjvmD!v z%guULLq_?F4suAwJF-mXx4>yaCxy0gZW8)aC%sj=HYw}ZK4Nrt6b+*la@6b9c`b%u z7~#K$F0_nypaS<2x@ogLA!Ney&=19w zZpuHi`+jO(3(5!yp{&tyrz!0+!1XI?zz4nev$%8scb6ATn?nTY;BtE#c#@fhpCJ%>kK7LKLO{NTKtt?^4m>|vex zbIBPld%}YV2j8z>dE?AMzo!7c0@azJ-Joh?mg_-yn=%zo%|p!@XJ{64kNzC_^V@p| z1Csv`2pXse2;iM{gfdJ71kDEs2=~D6hyqrPLjMyQOM*Zatg1F; z%$2CR365ep{`I<GKl4GB_#_|1Xdw4EFhqVJ}Q?Ihb%``$5o%Ji=_wiHxrQ&S z+W&g&peF*yhJ4Wd*a~n@?f*UT3oW%I#^@2ZbB~HgMF(v+eIJD+F7AIXq47fJ$haKH zz{olNO3sE;Xzl6ajh#ILGNQkWbN@u`CGVu+7>ye`LGoB^1cz_@)fnerE{WKt56==C z3i-!Uv68=Y{%d(DF%%!zMWt>|N>~hAC^F zlDW>V#Un8w(-K7CM{lzY3BdS(1zzRLd9S)lBOio9D#EGo_unY@;#1S<-)Fo1NbrrX zw9SGOPfW0OXS2BNhLtU-U*AMl3YN|JJ;9DZQ<>o3&M*7C^>X0~CP)~dv-BlCe^DV9 zEVMIXT9QYI-pv1(x@4cMu!B)xTycW>9&nF<^S$1pD3EJN`6WKaFd(n#gtT}au z$ku#Y-l&_L69GP@X+b~PpmF|lGJ)3Zo}$FdN-u2Dp}lte*wjC*JVXgX^LN3Uu7e z#wZ36k~SQs9m3E3M+u1iQ(?f7Lnr++`~|PeEhe+ghvbl_zX+7n`uHdd$_0xGh3l)R zQz?NX1TVOBtY^t%YSpYn5p$J4&d=v#?3M zrb&E#^b=9f?T}xR9f1J+gO)Nb#rYV&c{u2MfB2Y`&)swn!>2$hnf*TMKG{84rZi9* z9=x~rWy4y~>)&Q4AYel*4tG)8VV`<@63&Lr+an!4fu!RS)7pmIgE1on)& z=V7dAMA4u*aHzm}RvWqfv^!P8-9cBSlIFT*b1rb0PGou|bhS42L)7qE@-qT5*pBPp zH@a+vIvYn0)iUWx-Q&cCMB^Z#vPSZu+ES#5RJUc=@(@Ap+9Id$aTY_D)Q9^@cma+l z_RUsaSAG)Vmx=;%MVan39^k0|9)aauC(UV@)rCCeT!R_LhNj8GI>^aqt*9x~)jfs{ zW6n`bz}-FqXHi%(F=kDCk!P!#FN}maL|^BeQP3CdoV00fsD!8)#0=bD=;FZgV$Y;u zCe*hzM?3Uo9uvF<XPHOlxto#=o1c!Ol{ z2kFh`RMgCKPxwT=0L~LNm4dp^Hv!+_g$-E+sb$$E-Q#A5vV4BhpC6u#kC%hQ$Qdk- zDZ`<%&wX7dib8MuA<=27S*CTFgywhtjOexMjkwQ(ptuw0;v4tE$vO+?c*K{?SqU_( zbj9-G7#%utgyez+eI&_Xz;OhfeWtFNVLWmw7qhpM2#t_a2WYX3U z;0~bM?MorHuYFx!7tJ`^VAt%c{6o3NOh;yibH9cmqN>juxIN%JC4FipI6m?W|EVMA zl5uD4&>V3;L#FcK>Yj`mKmKt5{u(>rkCrxO5%n%ba@J#i#)lcH;&`-3SACZK(MiQ? zaUNdph9OYe)+6xOn9}^x+Uav`w?H(%v=-`@hp3^{gP_RyylUPu-Ttf&K72P|?M4;b zRIr1I#`Ebqi(`f>aBGL_Nv3@Y)b^WiK7Jf~rUcv?beC*Z4vH?1r36j;QZ|{1onNS* zFrE~rI=*aeqx0Uef)B|R;CvfzCEL%0Jz6oGqbyz{lcP1yiR`uArwbTM(%1ZR>LCgn z-xBEdh-m~KcRS{gL~6FSu!*Fty)lvPzF{>!oIW!&ih5y)3CjEP2y}b2Tg$vSI(m@^ z^@0&8ffi2>&bE89u^dcK+R;LOIG!;AHxI9#fOO-dp*8-|-T1kCX;0R59J0;}oVugs zCcl`UOy6?>(>k*tslTZ7CWsR+R*PEDqq?kIHFfYK)5y+C-5JGF|w>NHwpE6#H%rdwO?5t2n5DZaW-*p>T! z7-kH|;58n9zf>yg+RAz1!O_m?SfBhU?~GUt2Ayl3}G za%oXHjuhQ=71yU&CqU10#CrcnSSbg%A?U)28lF`q`;}!4xBi?9!Y+O}h?6gH^&!CX z*^ic~X-AlG9f0odONP?=FjgVug7O6ct6r`!!<8wdX{^!#ehuG3RzesQ_d_@FQYx@e z3P}oS`^f88(@CY``Wkm1;nb~#$8n#QXar0d_CgoVfZOkzSW0i5$W>zQdX7xDk1lW{ z;>7jG-#5rqoHqlwZs_vnN^VGN63WfB7=LMUlFzXUv~`pIrR+Q1Wk|6<4M_m56FL>@ ze7=E31tU`1UtZBT#{7c~9$W2^wR(pU1lf(#)l|U!pagAi^yr>{@`RsUW^wAXkbFrA z{B>Q_d5c=ZeFDasiBVnnnmbAxC3w#`D#$ua`y8uf4dbZSTVZSH{({g^MAWO`I@N&Y zwsZTX;QzJ`RJ3>Q7}2!!1T*MI8j=e^GR2^_YG65L)>l`gk` zzyz zqnn`C{z{8ICXxbSmB zQd6pODht*Jw%{YbN2R!gFpm8S9s2ES2Wi(1mG`8iKdv+~kJ}#PDkfNawRY@liz?bR zz-6~zpeypxvoO%x(%7x0FO~5yJ52ufgf4vW@JxI2jmo`2|8C$apmQq!ba6(|+^dh* zF>yBB_>Sz2|Fr|s1`qpL^5k69ZXbf?9s+6_%4Y|(a``&R7m&Z zr`@!&4=@rdg^uqXKh53vkKz|+7w<#8-V7Y@&~F+@DiTvh$CS|YtHBAKV(8{6^hC8$ zk2ks`HCMDlV{&9H#!^EJ$_clgH2P5~&u9Wy2pw&DGIPZ#2`Nsv+@nv0=zB!;6Id}V zSl8@iOSJ`eS`@(LLuaHok9K_TLpTLxaMxCAjT`^n4f}VD)z&WoPE}N#zo>!B1uo!g z3L}*reOt-n^5Jhx*N5K*bU*#F#~zVFK5HlAFm%H~-~rJ{wnAWRGGPw4YVS?@7i$86 z_aVP|C=FyT5lGC9KeaDEb1g;U0tIGLg1%3KzFLSYZhT;2iJ)oBME#^@=HJY|T{t&Y z+~-FdB95xSrNau&uDn{u_;cd-ckmZ8_{SqGR)3_R^2R{E%0t`EB`7vEirI(&Ibdi&}xa37(YP6<;t4DG@A{-V%2O;XSPp6Ied zHKk`4hmjkZS2&gvaLK@VR*F{ARFY`?RwAY{EeRD%`@}NW-Wz7x;asSCJsawuGmel5 zUStZ~o~0k?6r&e0KnfE`RMzK}ikLw_N|GlFvVU_*)?V)KkN>t{E0F1 zZ6Kg_2krxOPRe+3%E$2uwysrX;n=>T6(lwVr4$Xz@{1n&os6WMz(vEep!Z_(;715k z88h@WCccMO&^LYF2 zrNo}l(ALcpBZoOqS_C|c8Lj8G2}BVQX{#owJNm`QKCY~6FB>xmX~f$lj6L7|11=2K z?xBKh4dJG)5=E(IGrlS!39$H0X^SJoq;A&4})K29jYDY4@g z;BRWIpV6R4e8&3m9P(|7eVoO~v^`p!p|6t)`-= zq{{zq+PIr`VDEoo;{Zw+8&kiJek(GIuKoLGJswSIN2a#lDS30!hfqXU=p;(Jm z;ve|a)R>$Pf%Aly=g;=>go@<#74lT)*mMZ*;gDtx1s{Sf#;<+b7rsXr*uc3%SDi5s zGeQz3;hS=06GcW47hEp??rZURH};~(jQ5$wB5Ux0Ij z?zeC9`<$;TUosLsqI;0!oN0{Qlz$(~M5BUt99S($*nzW$PVy6i6cA>vSNb49u?|g8GEYdsOoyv2?^gbwHNdRXFU6SA?y6M8qzl2y` z!MI(~xA{-1IS&e)8BF&~8*LXj8Gti~?jk|&lX&5c&EVJ39gg>8gihqB$H&rjd~dW^ zf`0e^;RenWI`?OBHWs*@kF;0H{u-9wj)Y)-NHWqtdt^PrTjhJV1M^YF!1*S}P-3}f zD%jr%Y)#i=IN?MoaFH>ty;Lps6s`$iZHF7#+WXT_w8T<{3^}c4)a(3c9kK&cWIT144D2!8@-34ygyX169E3 z!TNdra*tWTFuHr-`dZdUD33{^@ATg$PWQFhn%PPL&xj*%I?(-n5kjJ`tHn-;oXk)# zq=L^!LMOL_MITuFa+tw4ghQtazKUF=@4kHX+_5HcI}aVRWykywz!3jq5L+ zI71=y;@6?9Tog>ti5(!PYR zz9gBvlB@3hQWSdIZ&B6yD&&tcjwGDfQHL&peOQIfwlsLKz)}9)=J-Pf{v0LA3B{Z2 zhDX?JDMWCRTopQoV^7k|rigu-i$>A6Ic?m=UAA zVeZU&8Aq_^MV7-0zM)6){G!Ubf!=R6P`r(RQ-aQQ1+B|+{fQ38j{>zE*EmvyQHIPY zL2VQK{d=8FIo9xhsR$jm`;RHiEL!(`BEFudsCI2Xe&J}AXBS%*&Z~vi3C9uuCl8$G z9&T)}T-{ zo+_XS`)nT^%t-1sx;UwSJ%b~$XRz1cosXhzCg^zk;m2FT+uQo4iNdZO!PSbN=Ntan zg9ziXz)69l`Z`Vrh(+~y_OJPWuSa34^>7#C-z5H9ZNWyvKgGULV+&iK1eifl-rrfm zt;)TZk(fRH>poit4cq84HU@qi@Bi_2mvLD zaIO!m*ZiG!O}KP9A4)x1$xbz6pnF7$fCf{>7qC?x;J)B0QtvwXCBONdD+28q-CbBA zIw~!X1|m7Wxw1ISqy=EBP!p~klQL6X&Z6$9lrnW9Oj>IKgQr&tbA_!4=t~;HoBJ=m;~+`@R`Ml(82EBGq4J~vAfVMKoXH%F^5pL zba!vziheu;|B1=HZ64!-)Sgh7eDF|$RoEsRj=(5a(<;;&&7YMa`v?L9nYwAa{Ui@Z zamVp@3gMay7p#K{U+fysIU~(pLLxd%!Ka^mIrnTicM;yN&zCd!&HD!d_Y}H6Ia+EX zZjNHATLbYAP~!);O2&61t=U(-8Iz5)?G=9j#}1t|DW*Y4;Dy?ej5XI2Qg+lrvj^`& z(E{|C|KV41nBqSJj+GLF`Aq`CoMkXUOj&s=b*IGElmP*1k4w$7VXD@hj{}J(V5^N8 z%r#KtF!5v^6!5W)>s#b}bTwN7*B?qa+>2~Yc`&z0k?Cze4X~eyS40;80A!ausex z%d+O=1snr(3x#O%!*cnrGYTz+%iH&7#o7%Pe$@y*{1sh7byP!fxGFWn4W^10$MZYUX5aT7a@oiriv;srA*jQi+$c0kIAx!@xa+ zO{n6jD zQuVQqMn3!VICjRd-;`PhsBq3i3LRa9pyP<`yjXC|zxGvDqTdc93ME%~)ls7_^c5xT zUE$&(F?3Ytw7AcuT3A?w1(NobO9!mvtsccyk4zVR_e;19M&JXE5W3+MB!*<|ToswM zhgNjFH-;ubZzs^Q_^n;Y_EylW2P1%c06IZ%JlXf)u$$!c=FBHgW5kLWrSZS`4J0U` z?1umCUS81!3=eGccXuD`HAhZes4En{aMJ=Uz1>(TS5C8NLKO=S+ zp*#P@DLxZBL{G?h?&YS>4x(YgKGnBmo~ihnOQbK-t{-3DCcNfpw_ctFT3}qNE6?-y zlyKP}9n{s`=~(P~izuu{u9EF6+wqIea;t##E|XW_!8}uJY!oh7#JdMpD#o9WBp1f8 zR3eL_-XPXWwwwfTus>0`QZ+QJt6Tqq!V99Iz^kfa7ha$)Y|^f%NjK1g{qz@CQy zhP>3PU|;^3b?GaKmuy5j*qfjI8lp zsBN0H7yt5erwzorhOW}XQWND|H?wh?C5sS^;fMGH!@88XEHX@HXW0HhImch~%7?fY`oEiIf-9RlZmwpHJ1xajfZ!OtWL zuLpZah~J8yxKN0OIz^b0Z;BFwLlOtz6*Fe@pSI7-v$lr}PB7cBs(-bpocBn^%rs#i zguX8n5cmwD?LP#+F6P5U$_CBfT8Sk3&nGw<#MAZehsTuKXds!sJVO`W@&;}fmM&T> zi2vo{wB0~R8+EQw)RP}%XPII@Qw%!NyZZE09=ru^8#;zg!;8#pRmUPR@13zrBwXsm z2hJ&vmuWu4tp5-)tcNN2CUnkR<$9V|a`N9EdWuGAuS)!OB(Yw8RLM;&?kNBBvm6$1 z>(C89v*OcQ8b9IhD7E`gq_w_K^KUL@a{5T%(g7v*gT(-FtH626Vj1>7&|x-hM-f=? z_LHDt=)s%E?8Od#y!lD-vp(q=?0w7Nke0}Hoz9*)D@SO36q)3p@9Foa7Id3U{U*4h zqY>Q_?QtO9BItclT*GY7GrMlWp15vfHop4sR$w9ICY8x+ZD!x7c)e5A7Pxs>KJP~Y z)XR07Bgjf!-50*p0n=`Czh^sGwolLY50cZ734xo1F3)*L$!g7CD{%k8`f#2X2R2bM z9X0ik^usvyDMsA?cJ`*B^C&J5ewZg36e-hs7Pv)0^~m~h85!7IaW_>)LP^`Y0`Y!9 zmnvCPgOG@e!9tl~oX7F{YpGDI-r^tbpkL81_9z{;w1Jxh&i!f27z*QDFy`fxL$Sn8 zqIOx~9XwV4EcB$0@&sg0+`s|oaVAE0=GL8Id(mn;{kIJKHfQo5nydG@i3CTDTuZoh z*$g?r(UwtgqnCcxZ@+BDzrMriH$|6XxS*Ylb&^0@q#@?OsbKsx-3458_#wE_*S&v5 zi%Uv!@p$~U^dE_TQ0#b`q3DUgU#nDt(5HE70l*EyI`Cmw-niK9zk77}?>x@w$-+rT z+u59plRomA^p@ecawl*VWHp?kUMSAA!WZpJOny@s|ofC#AC~nA;;uacV7GEkDUxUlHK7^TZ{OT(gDOz=f)*F1` zy#Y+ck7lK21C}^8MclXUv`G8w05*f$Ov1hk$Cq_eVo@iZ$4NgB5N7RzwYd2XTXhDd z{9dFyftg|>91_$e`XzQTrdY?2REY_y88KV!mXLOJz9L*Jm2!FT5y8Epde}UhRIhMz zAB9A-URL2+XS{Fp4K2?>UHNd0)`L$!HTT;CxNpF@OQBA+GkYnO$xmRU%7rt18qySc z(KlPtiB`CFucEyIS*n~^GCx1~$Y?(#8TGB}u)!MZ-jDD546^6E{FHM7(Ys)X#k4O^Z=oM@3< z!7F;UWey|YN?={PP@IVGRMOU`_DL}xd`?VGG+>~T?eZhI@4X>G&@A{AxFYEOGAP|4 z%EZ4)NR!)UYkZXOi)f~;B6aAegXbOcT#98Wa0SpUPy7A8{~K>8T=UQsG3)*yVf4m zOK*iY{R}uvj*(i0;_WW}erqr79WeGqi!PvfBy7OEN_dOIDtF9g1GqF;K2pyd@=aE& zf};YR!-!Q$n;8j*ks()?$K@t3DJkf2^MOl&uF0P;`&{4sgX%=#7dDN53L%P=#vw%k zM9fq-l^Fx_2EZjj*GQKT-@i{y5jIEK?2>V}=0QWB{p8Z{uDg&n_M&+gZnGpn=bFv_ zdF;TkAk29&>y0sos!GkW-#$ku36SwT%9-HVQ=cKpJS*jYb~os7i*4ifTGNgluH6K~(&eI&Qynwb zCsuoLt#8Wgt^{8(RpXg|FShlN2zoKo0&g;b&`Ei(-utBQO7+LB(^nDy0Ao%vv?Z$m zyrj?JvB>oM>IcAmg0)b&!wr-wb)h!optGTW_3Y=X0V7@2o<-DG=y@Fr-HA}=RxM;)DWyu-SI7i>c-d!M(OBRklwuZN8AFyj2yws{RMzfeWhoF zG>UQ;Oqvp;bCaBadk0&k`6ES&xCvdl9kzd@B+E)B**oJ5YT1G8T@{fzORlfr392_B zp`;ZtEO@)w8Ohi~{NvS=gYO0wM%%~OAMOzxSCWjUzV`&tT;Ol}{)Y)+E4_N=LXbS6 zia^7xl9)MLFXC$}^1q4C9%7r{0{0r0uCH#p+^KD1NwyOIW1O>0?MA=e%n+#Z;NkQ5HqkZI5tw)zNLx7&sf~bV>f;hz{1?dv-whsG4(_YLoaSh6^$3Ww?yTZzWaMG2pDATe_ol zIT0k(!M5!BT7|Tq9fM@KKsw1p*~jI?AyU2rw;(Nmb3bjj!;M*+Lno9>N}W{c7g2v8 z?_;DeI=a1Oi&E5308WaTF}?S+q_iiS?!03ud4p0Qg)uO-6%u_RZ{V|y6KCGMZH1Cq1`a0ajzipJi}mG;`3@;(EcUn6p{Vsd{}3C3&) zUK!7+6JIRD>9rnobh?`P-k+05=mrt(y-<~_{?O>qI?XcjzpCfBkJWzE44e+EZNm6N z1m+#`DUNP5mf4M?7w@_1NjnC~1uzX|UzWT1b2yR9FI=_QV+jV+3p<-ySV z-xOR8PUm)6kcTHHd4gWz*RE;Q+0ws`6=U%EYH~1fDe_*eZKnd1O$F9rInH)(dZM12 zA&gLyu94zbT1r}^p(=~2@+l$dfMpzvl_hE+oDF*2Tle$YVL%oz*_WkQG?W?KT374Sd-WH z5#HmW`>~xi^8`F41x^Y&CvtbbiLs#?)i?4ZWL)1`7i~6W(cYMiW@4t(k6I^T04D)m zZhElB=KGLkRElH|E7sId&p2{X(-yl!USrv*-f!k`i9(bZ+;hXK(HaXZ&b0)!f~LSX z*xT-2%px{6V>y2lxAE2TBGv*fhra5}=$Gyt6B5nAx$>Q-#xhC|snFr0Q)I zHz4pBuNZunPzd~NCwpC5LRr?+VZjcn@))?|sSilfX+x&=v^mWxFmc(Xz-0xA!9*#3 zL7OA@NmD5Qn-$R(WbK5(R712KGYp=Y12>wpO!p29gy&$QMuga z5+NqQ@q)@m?OZ$UM%a1(**_;!)@J3XmYF{7wJ;c76-Y=?{JceM2OKwaap|(!zZQLz z-N!YoDOf4g_`kNy9i?f?u>Fc9ewi-`2YF8Dt_He!r3-&3DKx6v%wSyFUWXCWXX&={ z*s6Uo)vmZ+1dao`GmaPo`e`}WDz6E(HyK<=LwnAt4*XmNF|Q7*(DGVHfMbJ>^IEnF zx57s%Qe;GRINYLkM#@|CWr_PLo7EzDZk+2la4f*N&(34dbl7h(3o%mgCf_~lB=*zeI@*G8cm6yt;2y!^y`fo#A}JjAsKIjJjQRnt zKN6B;3mti5@*DoYoaQC*fpvJwqpo7y>kJc(ARZ+#nD6CHTP=zERJ$G{zNnqO@ttiR z{YWj68;h*7A@p{)<4y=T3Ru2d8ce;WT)p#Dp4fGw#Xp;9i-*_`EN$)Er}~ARkJ=1@ zBZIC%_~=jez@%F^m7)Dm{j4;9bN<@ z7}`oID{3eH^_u7R8WKiLZIlBG@EbPnu)~zo^}!lAY*^R0*?F#Hmc}DKY_mu5TSS))_r3T0Sd-l-L=kp$kQz^b z!-91+c#`KD{`O@Y!Gdw8AeX^9^WUqj6#uVBhWf;I_92QmA27hu))hc;OWmf~lnA&Bo{IQG&OM6N5Z*@QgAdaGuQO?duX5e|L3iYic!#{0cut zhY|`BCUp6VxGInGG*SFtS+RWg|~t-kVBsGE!&zXz?+N zjoA*-v{aDM^L=pnTOybhV+~mj)R1q_b(_o3)__V(Ck2_j_{#)4S+Y` zSGJUWVwQ8W8~Ze^J#DkooS?IlcP%dgcY&hF+3N#eI9vw3A_C3Wprc-&E9t4L^zk}r z$=2LrdYhrv@KLc4W~Zql{mV6&v0V^>=24pKXUQ;E2)+wD&LNCGI{VmZp{}O*yNMTz z#*(TgeiOJe=qzVS5eYlgF9Nd=cdv?;J#A>j<9jg7CjaKcZ~py&Ki>&-KYobupnOVK zx%=+Oxv_XZ+LgU(Jvm6a`O)El*Wn{$xbJubovzNyoX#y>F}qdEuiuhl2)w}pg}=A5C-lKbcx#>D;Fc=DEAEU6wrS#5XG>&Mk+1n77zzG)89MFiwEvEaPDS* zmTe<0j8tt(m!hla3h_(Y;kInT}r=_IF-jmm#=|VvSlg9~Ew063A?UxjhtW-v-zf!U!6mgR=vKbu);+`jm!KqB zuTXXUW<_W5lw=jF!}CQj_090(hcJ)*30;fumQr?hu>v=VK5pFd6tPpqW-!LqtmMAm zi@TCIR5#!zpreUx2(D-|#&Q05JljF$b_Plq>h0bf$p$PPQVVPqeXUAHP7um( z!at*8(SMuVmqLLX0?xfLdj0P+x|xTMG+(xZ2VWd!Iw!3(>bN&sAO&DZdTd znjbKaE-{Z)d2o|hah{!)r_~Q!A1oacQQkX^VQM4tesqmtQRCEQ3A3GO?U!6?Jr*)4 zrqYAJ^+0#mQ6$J#zo_D6}jCzqGq{tXks_=&+zriKjB2iZz1Z;ub zkEMGq+x>gXXAbAEjW7(`cWda>W$kB`56K0v7uB({VanSC3uxiIWk|4uBrGl~Q>?Nx zdTSKpOWd9J`X6@G=Zky&q)&lsfKK{8g711Z!_2LvD?a9GS@zl=jB32Yu@j+hGQRxS z7AwHjLFdb3SpSdutKwuLLQ(dD=kPPfGXnKbsjVhi!f*50Le~i%!M&YQ=&lW_URZJ~o|!D6?viIb^R83ddf)cU z?4}@10E2?#P8_&m=onp$lbawN- z1I}xuf=eUM2+;9%oN~*p32(C{r&* z#j32U_joMGd{tD6JI`5PO8LGs4d{u3gWnghb0>a)yM$%*r_evBptmH&#I$irN~}cs zY#mYf!ovxf5>EcoVejj{?lLx6(`4rAry2eGu;+-SNP%9FMqMM9n9o=BWd;RssjyXM z@9~Qrg!k^?;u^b`p(JSfD=dX||s%C!1DSc0x4MSbTil>E}$sr%+ z0P)aW3!_=!2~C`qS(MaP>z@dx=wVsdggl;7ij%i_P5RFaxLD{;5Ci>a6 zxyEX3Sxv&yQuuHE?9e@?`0fb+7Y!XQE?xPnvZt0tBd1?aSlyPLs5#GhHV<{HQ{=IH zLT=!uaU^u4An%1|0>kt78~_ZV%F%f6oy8)L1*V z9=DzE&4Vq{4o`#-@VIB^Z)`t{&a&eay>dajyoxxcti9Xv%~Lu(t#$j0J;pB}S`g?h z?pz&`+yTl_l}APnMAKWw)S7kM=&Efy;@7ot!3&#+U|%r+OqU+wrTALf9UnyE4!7Zv zGIg(fWY3|k=OOO1(c$yNcsvK9`NO`4uBks>x0=Uzn2ql3{pPE`e3J;)0!gARZP}j9 zx@dt6aK4}po^G!!je4)Xwg)72HvAO!*ctTXzBqpTfu;|uzOi1F%op}OZ_xKd@Q(V0 zaz7oh&DrZGThk-#O2lZq$jM%09O8}&!aj}#@jk-7C%b?xLx_YTe_w7b&pJ7!S)#LZ zYwC5jX1Dn2G2vTNKHxsUHpYq$`tH$ua*xyS^?8;60%HPiSiR^9W{85Xm|)FlN+56^ zu#H1ig&G`a9M6|Ky@mK}2rqCqw%s!hsqn%U5`HVoB7&UU4a~)b`uz>L(Cyy;8B=~i zzQrbxz+WZmg{j%wgxvt@!%GgLy@hSuB9B^$LoIhLd7nsofV+Ih3}G5!&O(Tns>My! zIrRWMa_I`%xP?UOqUO1=d2dU7Q84UjUuOON;j7B(~^uG2~ zD`DyC^-gdf1B+e1Y+`+9wg}~)$&5DTB=}j~S0Ef?pU+dC1#hX5`o@BDqZcZ({crV{ z)EDmV#a2vRD{K#eaE|aN%h@jCHRnwyB3?;uwtk%U)eLh>K&g{dnnBj!58aVbd}6hA{jz77R}2-BqU8 zeCeu&n`3gJc}`E5mg%!Ln%OamU=5m1AAMWUNqeQ4M!fk823L=3Ox;sO{onpV21BSRcr$-q`Cr_Pf72Siov4vpPv=Q;i%?(3 zAcR$=h^-is?v(xa=_X^a9*BqK(4#Ux*z5X1V@WjmFVclR_A^r7g6f%_lA~~mR+!rv z5`p!=ib6K6(#QD3p>F>W@X|jqNiIiROln|CcT#SCS0Sj_0!|;cog8X#+nZ#+-!YH8nn??t|(SO!iPx&w^e7ua8lmJEE{?^S+1tT{WM|N86T&tHT$ zK8px>8->7W6Jaw4%Z538OJHcxbUSp@q|Th6N>ftSNA0#i_1Pgw&HVwCCXB}L;@qYs zFL!dHpwP%z+ReTM-;J&X89*x}-G?_=bRxDax$_sQnlfY0zq~cVZ5EFMa z#ks)&j}9}tb9>~mZ9V7j+m@GK4BFqQm744Lp{k%<{x9Q?;W=k>*1!KA9e(0ojx?H^ zP_xnS?%3{AizwA+BzK<4mupEIChgBdN%+6ZZ%QStElSf{5)))H`?fIOfgV}E>{k#CNm}?wO zbOce*?`|UPJ~qDb%A()(-pCMscTI#p_EY`)#(dkQ*w^>f$18}+24KMZ|9-%jbl(I0 zf0E*t|0Tto-d2`W>5ERaZRJV0eQCM(S#zz5QBZT2?sl1CJ{H4KPw2m-_#=uu>aVW9 zU)iNA%8hT%?LBd21n0Z7&w`Hw_pXld;Es+U7&7RPx`*68Ry;O+{EsQ?+vm^&r(+9Y z|3T`9+v@J(z6ZYmdk+7UnDkFrwkqkAZ$55|BykszHN`sGuByr&J7KHV^0q%K296JQ zguW(&T8DzaCL#3-&!RV9<>R(lzQT%p$=+;A7}()zEe{+obT$jegyQWN#}6DZwo=$J z|A4n$@)9IJ_$8t}zxTma9`0mwL&tVj^EHk`;^Td@y0NbmXSYPskZsU5w-?pMo3#nm?$o6U9=rLy!) zAs`+lygQ4whYT2Jy)9ARr+!Yc(ZlQhc+AUoAd=wKrynLiV}2k2M*+(x=PB4^i5-}p z(y+DAcI1=bq@fzF`%D3;#-iPjZ3+AeS=KVrMTa-v4HFc`I93X@U91(OV^2XLL zNiRwtHW8yg|9*y|Oi$&1&-vQrVQ zA9-Un9XdjSb*f=Pi4WaPOhWz1oZ5h(pEDVo8-=@DLqwR&$)IIk%;obuCNcxyaG}e> zk5`pqd!joXL(?3s(OAfqmlZ+yWq>JR_c@hN=7WF0VMDhSYV^+wPt?KTz4GT_*`_J{ zvg5LMhbfrJ|b3l$igr~ zz<_SxWIH-jP<5wy$dIy(nAy6A(MV%_UWS`J^4Goxg`hNWXwX@gd~mk9YorJdy9xXE zCg+#vGg8HRy#7z0s?!dpV~jF@Lxpaoe?h4W@wD5-9hmI4iPv{nu}FBH$8eC zZKF|zYnh5|6TPGL@yZwH;OuWkm=^zr z&da^>dx{nzeJqYR|0`*%+compCk7A5j6V%eCv9p7!ClWi=;rEW#cC{UMMw4C>PAY* z7+`xokTm1e*Vr#s^iTaN2KRV(pd;6|ZBLYxRX>+#2%#$ZMP=OZ*=6Xou3%8tt5W{C z@)2-b(A_>n&JRy@S{MJTizz@ptDg{N*B|jviT9~T0(v9(HVSYX(0Php{`Nu)l@Y8< zuK9;SLeEaT|E4DYOAF$A%CEJp3hltHLFZ_kRK0GVcaDDjk-UNZFt~u1dFr$2FTB;E z$an9RVp@P(0nRhIt4&i0Tas=qJzOWDtnjB;8b(X+ylvaJw$36?17)(g9G*m2AOuHRW514f+6d47O8l9f)%Nt0 z_!_o+N@TZtd{qlZz|DY>X%%>cSR?8Vr4f&n?k(SN(R`#vKl{(4x6XyhD4&Mc9!>4D zC0Q?mXfvRfCb1dcU@pr>?gO0iX9wCmLZJuEc zJzH3uqCUt#Uf~|;Mg1v%aDy@&Tb(tzBJl)7`w9DA;17e?KrVeN&m()EQd*-mQEOxu zM9zkfl`M>@{3jZ4g>eG5otnvFg$=Q}-A5_k*P0CiL0RvsM6bo$C>S41ty7o;Flm7^haQp=_s`n6G&=&DB+yz7{;Cz zGdo)<*-v9nJIw>4^}x0ZmC6H~-GRZrE)mal>U1TTt-n3_ovCgkujO8N7PxT*Too(?sH`+zydU(+ygXB^$E4pU4` zj%MvWeJaGZ*BEBfFBASUF9Uwf7y%0;Cw^$|MBa=>)m6$bBu&xOe5K}5--W4-!X1X-O=DlN zyxbn%b=Jp4S5a6|lC1`BC1p_6VPbrVMy4c7O9p)t6-=(%EUH>eJ_Op@i)4!AJx0@< zeHw7(yWbVNq9`Ik6&eA)EQbu0`8Xy%ji`5 zf&*|t<|qo~Ge(!sg@0a6zb+W4Lgz5C{l`g5&eQ1PPksKLOf?mh{tgRu+}$_NFVDYf zn6^d!=^uQ9899uL$ajpldt}P9#E}eUS1Ym%b5a91D!=8t&RJmOS}g_l#Ha zq^QOwoXm4wdK8zvqWXk*HN@Bq!oeQN8EB2byRqS5IawiIY;A;TJ&zs|TioDQBT2IfS2RtWw>{Zjb2Zyz(d zggz4Yxn7|BP((W8ffH;iU^$eMIlQs%VLjsXWc4y( zf0N;VjZrqgv5xszPo^cw`#X`eNWAL{UrJTwB=}Q$;z+r36=WMxw&yAmGx|v=QkA7& zMSETUQOY4FNoDeR^dAbMNxKOosovHW+n1BvYtLke(VLv&*GNKD)vL2k|`W}`y?W4+FYEwd_oA*{e9U}LR_ixT?q^|TAA}R&KXCixa4pUMV z&=jY?`8u?1@8N)t@2!B}TJYDdm2R*7MYB$H%ee&tB5{mw)VI@(J!y|eW#q-B_~5r* z!b1J)9`uAmSKb=U7R_~`r4u9B{49de?ovO5cq4dDz;)jl#|sN#0sPiWD~69+bm<~o z#f)Sm^HJ#Et`e~D*Xq_i4=8S+c+d=FS3le+fxtI{kjJ5um? z371gEu)z1aE$#8|crKdm;%K|k9;MeW;;MH~v}2tRBySH&o`tBGenc3-(D00)nzvlT zDfh26LK7@&2w7K6ziSQ_-WJ?m&<)Gzr=Fz8AbH?|4((BB=j8rC)FLmg8RR&^!6$}V~6>bzD)#7V-nAApR}ewWM|TP zJn?M8$EIu?)TAE^zGnI+f?T3rlob`1hr^&Sg&+bK10Op*OQcdNyl|PNZ5-}_^nr*h zQ5u;}LRHWAKW0;mZsx^Reyq{ooI6u8hjVUR`@%guqOYmm&4YGZxy@j zttFiiSG=G=ECZLp^NNJjniwIz9JqW~J{|*AE4ThOc|r}RzC8rCXhB~5AEG;sWPimn zoq0Ry;fi1$boTZ`5v+8aWWz$AykFdFW&C{Dd=LM{Cx`RQY5NPZfZxF7K*uL+CAoOh z&Jm4kPUb{3m2q49{nwG6oY>&>Ua{A9k0@|i(EU^Tm%uBEGMsnoJ?+;_D#zBmr!ne0 zzd7}=;V(+i512ZCflf?Jxv3xFCn5{)verc@0}6s6typjli` zbVXXyT{huz*RNQogo`Ow%;~|TfF~f##72j#_ z)>!b}=KP10INv(9@n0%OTqYBL9Bn3cxlDCxJ9&`0OvE1q=lnrfVAWdrZtC66dlkI$ zZ#(p#S8x@NGKKPS4F5zR&f6B<&C9~&jsVyucWh|5{5!VtB06_x3)hRbzosd+(UAZC z>e(`BsD7In44gl7&i3=kGaQ3Ou9ye|griZc^V77pau;Lwk>54GskCu#1KZ;66Y{ zAle-6{}kCj@3sC%yz~QJS4j_=o8_7zjSnpWth_^gzr%9T*^*XD%3bPb7}9$wBJs! z1v^{8WuRBkH7!&MQ@C^-_AM>7d~!7{d_K+hdh}Pgvn9g@@%c9&IF>pB=ZQTgqE)+l z>_zc}U^(+vFckUjGEZ^8?0a>7s_7ZEMPX1YV+dlJKZzg7-^Mm0PfRK`kpo&z zu=Ar4RZzp;Pw}o(WS>um_H?^SXZy#|vdX);gP$zdwa3xta3rvVBmHPhC;k*(YtDLU z^qbV(!T3F~Ks}e(mA}@FREvy6@i0R)hqaY?CwJ_nGW{>A%d+U70S{j?>7UP{jETRr z_FsOEm$HUuRZM|%m!OR%nk{U`s&c(Fq5DP`gX;J$V7>Y3@vcx@Zl=p1q6UI7ShGp} zp0UAR^!)qDlF&QsM1djJufcAyekDr8zuHJQu*zIPG(%WAG57?By^?}I*Z1Q5x;!v?3Ak@wA&^ zTU69Me=PMvX{?rnuXmF5Gtr39JK!{7Z3kVmZiC&QYYA3vZ?|vIuhdvBFAU>%cz(b6 zK(`rU)$tWU9pue>`&n#^<0Ji*+TZ8mcu3w1NwLTd4cp(kV3mq0k?)3qXsWQbLxmMy zHsXO4PGl#)JZaKzCz-7(rfcicm~G`_nfa2R1E&nHYCyg8B{(nDl;{$37L)tS4QiWD z;B<)7s~Hnra#_=8@O}YBup7dXE8;!LLqAuZ+VJ@E&63sXp#!@U*5nA1rr!Pi@ih$C z@8m(EYk8$h`Iu4p8KnYJ9P&ir^}E{VtTb-hYz}P6p9x=w7J;kE!to3_)xSM6b&c2# ze>YM(4_{O7y$T!&FS?jy zfdr2Z!3~{`rR#aIM^+;s+)LQVWJyGys>Ic#y=_I)$4&$6JZ-n<7p0}%wJ&s)whnpL z0Vf2Dw>)e~7S?*HrLcW`pF<+@QLaAWw-KY9U_7GqY=H}AxEv=4-Rk(Gx-aT!hru%Z zZVU>?M6a<;t5<4&oYLf%oCjhtT>|$Uy0p~=ne-s?A&{=@tU8kFICr>PXXeadYawC7NuIG5ow#Ft#l*d2&l&gLTS9y7%`^R+~MkMdf zYxLl$L>v;gbIXX?U*B1!u$W1|$qpRJN#MAl8>L^*or;#DS|AR%G^di!S+D;&afh1WZkAmG@5^K=%q3(Z$OQo>b4`&~p$Z24R{ z_TQTx-_B0c)Ky+c0C^+aC2#*1y4)BPM;L?}j zsd%_7WQX>^(YlZ(pS{mumLMWc3&$JGf**l9xFct=z0;b>=-Vb_W(?(;T{Tk|n>v#* zed!|c1QZ<}bx;L*EYyXlz=H4|e~$*MkTXHP+q*aMUI-Eb^aFq2*M~YTN55@@Vm19y5_PrxjA+_*2KU@B{DC6_&Yht4VTN0P0$SP;*qYQH|@PJ5ADC{i?>6zM;ju z14WYW_^aP$%t1IJ_zyzYQ5z^UuVbnh35x8;T^S3d>iIGEo^2~Vz3?zhzGe_O0$4oP zV}6I9eqY$=Om))tTKWqEv3YRyx${rl$X4|0&4$K+!-wu|a!`GV9^ca2^!c&f1 zB`kWDK~(}P3@K>p)e~^T8yC9zVeO3+OB@x7z6hDX(E9cX@}Z-XAyV1n8tvKtS1>O$gRUv zYt>1Ds7e{&y6YV#a4D_jngOo@FL$oE+SI9+-gWEJ-q&I;a=#R?V@E1*769%Rx}qJL zj~P{LO0$ccVhL-~!e5{AQCjlZSVxR^DrvvGRs-$^y4%R`s$Lc|*0gP3Z#fb+!<6%# zGwo&M?l7ETDMK85c$)bNy8A3~x9Hp-ym~J*irU|MyDLVA=lVB0#SiitKW)6w^aJh! zy7bN%vNvNEQC3;pkF=IrgZ4jQDG@Gc>tB=KD}J{vX#w0BbV>6~lNNtGPLv5F!m&8t ztiG~|e`_n}bHBhT`iyX%ts1x!=mMO#b*guLl$@ro%A67{ZSP~oc&1?V;oX#g_YR9P zH34@7-3LFZOZ3e$5<|RB@MJ`&XLk`**x|H>zT)tJ)I=!(yi5OqZdzqhTcAQ|eiLWP zZ`S9ietTx^L1)&oLeR6(TRJe0logcQ-{h_ZKhqHrP7&-TSqR z2mjfh_^*P25@in)Y{ON3qDYX%)bYBnyNWTr{Az}A*gLm>Gk zU+7k8#&^Tk4L>3O9A!oXxDDuh)3zq$W_FSvCJ(hF#BJe^uWCsT$tkwsYwr^6-y6FI zZVkG7U&C4DbToh0*MEw0-*i4KFWE3OnMyigvG^@lS3eDh)fM2}nN>4idf~BsFd;3C zE}EysOFT&EU1g~(sNC6>FDd_jto?OVS5MUN4S&y9TDn2HySt>jySqCjM7pG;I|U>} zx}}j2R1lDEDUno4Kzz>8-+Qn1KF?a$_0P>(uEXfZnb|XY_RQWhXO0uNfL#X{O_K)S zl0$zpuO}SUx1~9}Wfdrtwbh+iRu;@{6%8C7$shajLk|zW%*#cLu0EH*aiI^}Sgk2!&~APN6EB+&L5akul+HvuYcgg$^EgRb=cLc7WVG#KjVQx(VY=&q)PD z!-TSNo%>^Q)z1GsOdXsd8BAyxhe9M@AZfWOetxMrPb0H+4<(l#3d)v^FnaBICO)$I zEq0iB_zXOLGlO~;P`A^Ocrn}SkNC>g=|eHvm6`Oaw$0G2mSeJMBTvWyxYhX?oVad% z_b6riZd(|*Cm+?W*!aI-TKJ-*UPt>If(|oRJfzM2kXi7^N^ski+Ogn zCie)xRk#apYFn4;`LyAmW+*!Q5v*G<4{k7rxC({_)wPktJaOSS?L%^%>lq&!+aU*@ zq?QtPXpWvheID@0J53Q?SDQd+D7b5-%r>d%Tqkcuuc7ZD=d0d`*j8#}@JsV7DOE*m zL(_KO{ogd~ZyopZ`dW%-!+j;6)oK!(pN>c^K__BI(ZGdd_>(QZpeCyCa{?Z5@8z$P z{P*?}By;rj6-01RQNA}oLB?UIg@cW1_jber^RZ`}^=&S*+M?$o^<(=JeKAC;&ro$k zpoQcR#MS@a)OLq~oZ`2E-k-BM%V4HV=VfVf4ZLZKlM)Z;Lx zQUVd~niEsCiyueHgf<>iFYptL*z`fJ58_M&=7Py9D4nc}c+ZS}P`QYu)-fmBSfSB# zNyiM@nsI|%55%RU%*P`qBKv2Z3U>5Z`M5P{Rt(|EQ*y4?$$T@P?}Ap6Z$U1A>h793 z&EOfbCugbc_o2=#gIKuiL~)YaR(L;YquH{fX&FAOAYyJ1$jaflkRZLmW#gYMruCz8fFz zf+oO*QUT|%j+601eUpSWo*3Jx=>c+$kQ5w#USWyuyL5U1tZG6TG4EE;dzjS|6?}O$ z`{CfrTww6J9$ba@B^gwkN8pxzuscx!XX_c2qn8vN4z71+9II}Wk*gPAZf`&-!tDAF zSP`^n=i|2@L7?Aw!3{~7J>1A=PO^Mf_ETPys>+iEVf?rUK5cO zxya04*$>6KIO>Z8J3DQN_Jc(*!)i3pEB+Px>f?LTz}CLTQd5#28ec7~d|fFU-jtOX zMvkjV27>SIR)YHsGa-8_23wt?MAlbvV5rw_S$25+<^fJJy%{*AZiG|ZGli#oqunxPJQpbx2BJd`MAZ*6TMn=?4T1epprNB#f$RzGnX|`6c~9 zr#luC>7<|&$mK${b1CIUa<}H3Knfty_GA@}+;r!uu2z_`z&ydk!f)w?VyW2>N8+3k z`()bvY%BD!Rk~A{053_`{nnFmlSO~e&i>ig-XNC=aqS;Pb#lmae*5dQeBT`8H5RMb zVbAf|%2?2HW!$3O&IY-3h|5QZwem!~JygfQMjBBmZzE#YQZSbw$1oZ;w0>u|Bmi=$ z5Jx-tYM?E86J6s~fpeIXrVwd=ud2%UWOe~wDt7TDMG?ro0J(s+4>(Mhcn0=(%7L#h zDirx>6=^DF7r*yuyy}@6=~JQ(LXbcPUk6DvK9a3d`a5NwTpML(i1gMpWa%^^U!JzAkbbhEioU?|_^TSTOju`s?%go4rIG2Dmkz zstn!QtnSVWYE|!&>mRhm*#*)dCjfDhJr1z<%XKrVe}3vKk}Fp#OpKvkH=YdnY&qOj z5W}I3XFiCdMi9rSjOnq*3bC)bV#p2pslUF3C4y3g8F0B%!@YD5ay$@cHKd4$FLD%^ zr+mj|ToSUeCoEX!d$9SkW6`o#OC~`AVUnk1vlH-+DOV}y4fE*jd35K5k zVfu6N;#lj*>~k)P>eGgRz4eFiW82kwH{=I#kQrrxxKuHl=R(CeNrF>V@IONvud!RYh4&<01j?L!N5-WR1>veHk64g62#ymb$zQW&M$e$E^zJHV-rvP#c z5GOzULuzJ&S<3MNlwv4zEjfjO?)mTpSIR)3D+uF5FPfeS z8X9Ie28Km9HAtZ)3!C1gH zI(1roWwupNTfjynf#1fbp>oS71E|V4b9>N16?~|XX@WS*=;=wf)vDbIG+yC-&yBYQ zo`fQ~9VI=h=ZvtOhFD4;-bpT92`mVdg(mbcuuGP zi2q34ADhRaEb^NmV!lPb;{`c%h-=!qzfHZa26TF2OA{XHjSnFF-Ze!#~X9rpXC%@ zLcU0$j>tCDdH6?uwYMA=R%$<)u9Ji5!Q7Cb)?-}=({`SorMNoc3}@IiG4Y$^L9`t1 z%OWs#(rZ&zS_3%*sCM}*S9Ztn_q^v{`gk_AJs{q;CW1S6_-j=ZTU9zwz@!=|s0d4hBh)gIFhW5vZ=d-_h%scgSC(+f&zs5vwO2tn`~)Kzqu7M(vC20NFZ zQH1QiWpV`)i%j#W?#*$3&oZj{m4psrmq=i1*98n8+tR(Cu1|X9`|9wb6)6lbOwonG*X+(EBb<|4&xS9)Tjr{eZX( zxqy8cjEr~%Kph5KY!*j$Q?u6XHtwb8I8SPsdgmZkwI~vVMAR$U$x&c3cXZdQyl@X;;Q3?`CGUK=LEP5c zZ1xl*>nCK_=tY%|Y(HA!!$f{4MtopSG@rd@P_F>FS%`xv^jWZkV<+2K+vaC_^&zH< zGp9Tmt3briv;Fn#YabQJO+#ExS+gLCddS)Rw_PQz$`!I!;ckJCCy!K%j|-)4`%-H` zZVKYE-&swYui?i#aBsVc_YW60$y^|CLxla&xe`9vW=yQ>2HAuzu z$-&xR(Nqhkh9PZmBwOFS6LYf}Vf9DJ(awZ-YXx?CA;@?*2RKDn2BaQp zRK9&);43}jpti)8KakyO*CWfxY!E@C<2R8GDO|mu*EdbPxx+CNH$?<<8-uh3*{<04 z?LOgNIYO+1cZjLd-pB z6Xv81ONGOignM3L$RPI);?SEUIz9+FS4sy{YZ1Mj5U03%-Izj9l}9bH=SuFK>k4v% zkQAsoPgTro)vE|iGe6AW?s#Wm!UR6S3)9hbQ_`7HPeCdALGQ#Rc5-2@N*rNZXeZN= zO`o!q0V`qcb);nZGU5s*HnA6&TQ4X@aCcVf4{_?*W@>{NZ~O0q?X(G2&hx>rN;7eS zq(!a1c}VxVLFdGb=F9SML$xeAqiM_UPGwPX+G*9Ga`Zw8`R zI~C^_3MMws!$v2N{To9KG;I=#Zb%jI!jkPvK&}Ilf~G&V%jw~aMSHPhoP`r}v-GB?2 zTMH;ffQttic<_{xFyLn+Pwd!nveyo?%iE3yq&F5!U5dR3rEIV!(Ath$>_^*Mv{|*- z9^%mQ*z@{Zi@GG@$J^J(vIuchh>?N0H9$Sf{qm1)l8F3{VDUQJT9^%dmHI<@=Hm*9 zkQh7{yeEy2KUoLKfTm`Fe&>%MgCp%S#KQjE$ky=nG@Q`bK5Vle{)6!Xe7U?9l!4}# zqk4mJ$~!B{p1$8dKNg&^wR*@!MX)UtNM-svtcHQP)j*{pe*AV{d2aa?!R6gv9ZxaR zjatgX(HG@hJj7R0hOB9?L9PlaRVhi&oM&E?);>0L=?x`j$$PPzLso?qx#I|;@rj2@ zVBr51SZdEY`q9{3_;UNsNzc%$l0!BcfklEY?Y<7}gCW17fO#;ta;Q`}n}YjVQU$*0 z3DZ3Kx;@`S`bpR{stFD20bhBKI};Zm_u4}^T7FGh5%JZ(Tvwta1HQ2e?2NlhYG?KHo$8+;-s#Y#b@Mo%S3NW`Ku+-p} zS!IeeLV6r+H>ybK{e#*04kTTeC0qjp9OxI1Q7`2ott$Yvu35%m!I^bxl7^O17PCl! z!PcEty4=g47>K8*|Gq^#4Ca>yY2DdR-!Ta+ZJVa2mP6bY!^%w=;g#w>nSMHI28Zjn zzO*2h14@yStQobz?3WwuL+gvM$91^!WA5uspF|?~iBW=mb_!c4qL2k~fMy7b-@`I~ z6?2uaYWRk4Sn-$%O?s^50F99q&IqTbSM*=jlx+G)a1zamww z^PI*ue_8p{h{=iqO9SuG5`>ric9uNW73t(GXD`nkH+0N7e;bPW{oBZ`wYkg*=MY?-z>usuJ6?*(C1rXA{Dan2xEybfu2nxSPZBDoh#f*863m$-X9GCZ{GtTrMGx@!Ihj?RK4cuAbk2$V6r8$$F$;1L zP)A7EPff)(HZ9~=vnyLAu5WLN^xG7hzGoNR&H6;E9R>wi!XOS?LDwRyrk2}+`5P*_x*r)1b1NjSj#f*{57KM2pm zbMyJe)v0uQ8Oxi)?3}r0^LVe^HC}wpXiF8k$0Go$p9$kKsao|q3TyI2u3;bQa9%g@ zIPzPBn&(-m!!zW;nIQKBI1*Pr$f9!bN_ZIuDnKDS(X+pn`0CYIN#M`CT)qn7-kkY-AZa9 z0eD^^fSe`7dHm6t>|6a*AJf+GKBwf$n7G|iJ&oO)i_llUV5ZE`DL)&>cS7z&A6X9w8{RbjG<&w? z^?vcP=S;eWsBqho>MNL^F{FI>iw^}k(%xmY&FHi+F=#4uFuXV^Rc8ZVu)zJK;~x)& zsSLq#12X6I?%Q2SIV|qvK9D03F|oN`)>d)ITV_|LScsswhS!0Y{e`4tcpp5cSWrRw z*&l6hM(BW_4YH-M{oJ#6ilN=Pc+#XGzq-_riB25;7+ zY$vzp3==fzwBV(H+MxNN;4xX`tCgdhGyOi+He=k2OY&osO3swDyw(%gZ}JERbJK)$ z<;KI^;tvG^e@huEJ-nH9$@sYU9oUe}-G+H*am0s)CUR zVce-Qxi0ZGn`zls3oq`^9@BxGD#Q)T;&6}tu22=kS7rG1UDXsB|26U2eA$k8%+E7+ z;;0djQ--)E@$+*AE0$1vAC%deLA}pPEok z7Qh`(|5ToY2wbh4KRpkzdA_ucfIU?`?Sl`6o+Kd-yiILn7d@GL2;02>;3YHNj|>w* z*Ixc_o3R1m4XI;8ASVHG!Snh7#O8d}T&aWXlHN*nBx*8dqX&gnjyPYwepcHuF8-e! z;!MH4vOOwE7%r8nm5;BYot3SfHz4-cAtv2NIDepoGu6^QjlNW}SK8+0=CrB!kpJv# zb0rT&13Don^4B4r`1t9w!k4&>JlyhLk89u6goJm!XKYP(y!N96U2HQRASeW?&3Oo8ZQkzuOFJOqyUCO5yIa7#zR`a7Z zEO-^EpXbJyy08c3o)hHwpyuJzJtNOkrTE%1$Pj4Bbci(8DUH{kY(I6;fJ|n$vHJq# zcpwhE)}h`%z~0Tu@w=CPXanjg7rAm~)c6Dso)`Z5W)8Hm!Ub^&bZ29lRTdvUJGP_0 zb|F<*DTq=sVeI*!MD6(QM56_AusI+uA}y{(tg$Pr@HY!z zhpdGyL5>aLmI+U1 zuLPlqO62n`RFGqUI3bM?Cz@(Y%TQU=bD9IGc?#2N#O!n0WWQ#t_m_C?&{=Cbh)X2k z5$-gO2_6-D{Mday4#9Ol2nS!S5~Gc!A<>+XmJQ@+AZ{g}*C6$x=BpmHAAxVtc95K$ z!&lCN@|vQp;^DyfzxxAJ5XWO>oc3$iQl9D4n12+(n~}Mn91wLw&&kf|gCUl?{~d=P1e)LsqKAJ*tI`&jA1P!itIQYp3o4$wMrq$hsD|vqRfnj1iCy8i zKUgp*yWIq#oor&Ler0{fvv>mdNNc|`^emY;)`}+(xRfr^49Ar%N(6tQ@Piy7#I*}9 z;VJD;R`nySn47R|S?u>o23;o)B`w4RXa3K!eG**;uI)3X;ew(Bv;jDX{W6CiEPC99Sa@jkL@b`Xc zY>4x%7_d&eIx^!Hq-CHHq4-5!hVm6VNodBJC7t4v89%hp#e}%RFLoE(m z8e|UAN(55VO|~gNukr(M;CojfhYoQ(KULqcuw|@O?VH7UXn&xR&YRxVvXUI;)mFux z9BqsRIW&m7%^ZN$jtWY(+j#ZtyrP;|_FB^xuk?Bv2Hv&q@ggD+vSiJFJcmq~tJtt@_)1X` zilxE-+89)>C>*WIQb%QqUZUsTTYY-JZ+ew3bIECzv&1wBesqE$3_MHSCG<`2^2J`< zkJU$}vVyFyoM>Fx-hO7YulqgH7#%5g`WDL4-R*@U#M6fc0DM6vUo0_wj?=yfMn7z2nNo=ARFyjFs(JIGUmG z{|zG8h-!^WzipIqI)AjI=#r0~sfuj%SsE-~+ds)%gx568K#|{Th|_73Q6^~j%zLq? zbirXO<#YB^0jH3V#Wk9Jqv3O3OBcvpLfmx_t0BUQ%^*TtNwghq$d9`Z;071pfTAsZNzu@IxxdILPnnPP?UTYgiAQq{Bh(2gn6rwz;aS z7-#1dZVi0Qi9ODGQKe@_s?RxQMy#c7MM4Me-kyS|6-t^`aU^vMqi2dNjSBki`iz4Q z_}VZ=ezO?fDe@o=K)bicVDqIgASm+04Oq3PMVNPY8FX~bbXI&acQ45ko>5(nRY8ZM zH-}K|N`9I*#K>A9O2$&)CB5Z1DH1t_$+dAwbMo%G$Gu9E1i1r<^EZ?@`Gfi=Wi_NF z%PJ|3XF{8-YK4af!NC-}Tb{lh+O*k+q~OMfKYb|FbY$e7!yl7hsaA*SO*KEFyh~0E zs2|)DgQpO7!T5;pQWfv+1>ucDKu?Z7%|-0G>(Non@~#__ihbHHuMe~!--e`+jfr}^ z9=MBUZX{c^jDcKC(;O|?qvmUc9k@MBc1Q{xk=}x8H{dDsj!QSdY{GU7(G@{H@-Y)p zbZiMa?^V0&q~hU50myAY+^J0&tzoA9AwpNs)w^kRul72FB0`>M%ZyHq40dy`7?4{7 zxnSE1q$dUn(?_af*sZmnqx1IeKT1zBO>|nFKH9NIW3Pq`AQThidl4+^5JQtqZ?@`Z~!L=W-)YKthS^g@y z>#edpYk)l81*m>4*v(i)qI?YF>^1kfygjX`LM30`D1BPjl~xw)^u(e9xjBe?w__SZ z%USVdF?2Nlx$~UryX3bv4-yDX#25d_?jR#UvB+77b2*e<-P+4~^*lmUL3wY2Z}A&S zKHdYmjg*bU83_^mJdm4)I6{r=+ViWnU-t>Y`Z`NVg+ZRHnR|6uZDB7wAFMI3L-D04 zh$|Y|)GKHnjM`4>z#8CG)bEWYYa%9YmQkB?^e~Vof;Oo>L7eo&Ykol!s)Q5suY4*G zKcis5t1`z8KKJZt+`gEhd|V20A3!c3r)jkn+vS06Av^CgX#xd!psi5zsK&IhK|}^- z6m1Z6-wG5I^uF5BJpDORWd7q_L(?nSunE+`GXh(AlQWrau*Q#8W zQ5EJpmr^#fwrqN-AKdkI9i=%62Pv(X#39#b1gc)r>o!SA`Oxxjc}TP=`Ft5i$knyRzK7Ke;7E$rKlS7i_Mz({lKqLhU<@Q5drK9pYHAN+P&!&w<6cc~V zJw8IJ)0bY$`0ii!(8)V=LCy`1$P#BG^;^6?qg`>7?a0`K0sex{_u>>ILJnd3MzGSr zVbdRmgMe9!MyBcX#KRW|d4R}Q5}Ct*1TZ=$8#<`)DW;W$I_(IXJ*U2Br>isInL90i zzevvgBt!$S1`s(;Q?4D0`OJ2s#U&jg+gi~D6K<{MK52V3_l1iMb{ZjC3~=Uj$Y0Bb z0VVqTlthm{=)L+ADYu)}f9-CfxbZ00^-Vuu&Dr|ZriHp>cv>EaxuO+I3whSGGWwu@ z2iB%D9>FO3^kxCUEV|qi#^j?GKGxz6N2!Yo^pYCfdU>{ZAyI z0>FT*Q@3lcu&|N_#;dfA8Q+f3grU+6Gs9Wl0wRa=@UJ5gitRS(XvMl7zN@yb`w_^3B#pb)Dxpr9cX^)b*h9b`DBwxtAYm`IQ#Ail zxKX=#{@8C9tL%f$4yE`^~(cpTrCKqA-t<3qJ-p9^kz}Tv z!?jlDUo-@Ga5gT#RQN%sG_WJqBHDAQHyuyv6}H+9Z~%k=HOo0F9QF(FDv_@~qYf4@ zN{KLeMo2j*R;M2~+1A7radhXRRsPFu zayNq|7N(Q?l0dP-hAr*ui_yHoSdKfL=+`zZg+sVRHc$Cc?=DXpuuJ^=jb1ieetYlW z=!^$1N6q+XQw3fj9YvD5@N-@;-|>4`iI6iz277M|A1l$;ep5VspdYt|2}AbA zykOts1}Y!$%@ot1*u2d4L;Aj>XUb|DS1n(Bl$zkH;V`#Yvh#cTBkjsqyKByfwS%(4 zYXgny$F$z6HDiADGyIN;H9!U>MyNaT@k+(P#WL!_MbiD?LJ06FH z0gO5a{k!|VA&YWjI9YgA`~~gS;7uJ?=vR?KiQixZJSYGcc#9SIbFKAn)P$9w(b#Ew zRm7w{|9+|`TcQ`7>StK}Sbf~)%9B`3DQIB_;z~Z$r;doVe5_Nw!S^wpTx0%t_BHTn zzr$BG4@D(R9t05xg0clC(f_|YvJk<)1LXSNuD4O0>pcK9TSshN0aZ5PV^2~Yz-`M^Mf#?^wCG5-^b75+mbp0|F#GjT4C@z9R+P_#@! zippc_|CT`m7&8zI5u?IAth_T182UG#NNwPvzve`HajR2h|68XfIguT({nu!};5a4! zoBo%`s~}6~AwDRgNykr{8=)tSK?jn{QV`6HTu28VnFdvs2ywp6G9?L2z;S=X^Tu{D ze;xJu{75x&vpMe18_fM~>yp;1VKPy6t;J9xa#o@8b<$w859SSP^1UbLQ=#V5m?R~w zsV_gl1wxj%C)o)PD+fbo)%s9u+tjP*^JeU`zOx{du-ZENX?F;-e3Q2E3w6q4ocl)P zqKedchvv=sTr^7|vt-iCXrp+fkL~wZK8KD*M=f%y;Nr!FNyOtM1J!}i)A5qQGb@>Q zpO+sny2=P-tu9Lxi{glWj8?%7v}WMQIpOp z;_ZyAmNY*vEk5lw4CbNhCWt2A$#h5IEzI1s>M^~wa=g9uaV~jY?De`a(KXYGxKBT{ z);izs>YKKs&o=YS!t1u>)-dW4ta&0@?HpeQ+WzM8TM3l~*N4W9SJ>GttKe%?X=Z*& zC2Z`6#bYY=6Z+?j%oQPvp;U@8foknt4tN)zy~SLpGr|BOxVx37kE4gLtdozGwX2;i z5cuG)3iI(`qrhNZ|5OJB2c}@>Zs%>~>){Ox{s-WoJOupz{W=~7ghc@09|n0`WMrRz z|7QdmRbgQ$STJP|KW}#{SJ=~kGzvCM+s?-0iJf;K?AZe=PJ9>+GRzZ>h(?C`5a!|G z3kyQE#YRV=0=!X4P;?9ty?5b~D7aIEI)UysI=)uEem+3FIHI8LQyN_>9~U1Q5tFAh z>UIIXG$J%y0bDl#44;OL1`JJMsKV?o|D|;NtT8IkpFVrWMqUNuzORBokIPD!cNGlA z^DhZKoWUgTza;d4l6?P?&;v^H|4Tv-C@JtS2|b{s;J+mFfRaN0lF$Q63ja$&4=8E% zF9|)Mr1iff^nj8!|B}!HO4|NQLJufu_b&-OprrlZT_X-50Y0 z4cpF^Mudw17h5{e*UkqK2S7u&@vyZcr^CSmP*Cadb-)g_a^RqYVc?R`vgvv|*|~%N z494_a$yGUsU?l7S8sI0w4g-G&(1B+;&tOb0dhB%c48pJK{EbW3J+W@n2BpaBDw#Y8 zl4McH!o8=w0TMXw_`|qsrxGez=0L+S&V8(oh#zAm(Ph#4bWg<|+nbLIu`_PDi+0~5 zVlg0M#W|04b$`&G`5dzS_JI~z0AZyH07AEBw7+-JaWGRPq1g^V!p(ER*;0o8dn9JJd8-{(EP z3)4hVR=@oC*<+XR@V4okf-XCtIbTP^H`;<25c@xNn}2hkt>U2%U+?pjPLTuz34c7v z59v8wFNNfuh&j2@{NJ+MFeV+t&hk%p+bJaR)k;4%-|?Ps@5EnUAdKWv63AoIBRo_9 zM*pkS|8KGjD{<6){)&J7HPzPEXQ^C1-3Rl6Qsl#@ia0Sz*at! zfMY2DA#fuBR)~AYxciFJuy^d3z`ZkEk9FsE8a{QE-n@n z2G;*io%kGymiq1rq?IDk&@LurMhBt|hy7Ao85l=l|3ny57VcwK)` zDy`dizD`5rdvCyWKLt0MigPiEdbKvy04rs$S+ndnlGLO%B%e-u{7`eVntIu7Joz zErnhl>ALZQ0m7XXopr{SniyH&;N;odiQhfbc>A5dZGo2;U8A*m z!v8_)#RooAr4f4d$a_{mm^H=6LbW83XS*!-8D_>phP$``#qbo3S;2y-+x{2tw`jTV z0RuRUdf?RV+N*>*@r4BLdqvF`>Msry`vx$BDdU~9++SEe%%Ygp(;|`xD`}m;%oPc~ zZNcR5ZQg<%veLTDh_k+nGKwqTxj3cJe_ryxIU-5sr~uRjS=}72ucM6n=VJ{-wMxpn z7BjvdD@~u&Q1))$lADSHj{u-R$}B+W!VlG|)i7bCxaXlKzE!k34%U1k{u4ifo`nc+ zBfo!M7c-(2%v|>@CUlDH7m`m$8-48yB>ipWxXJ$JdWpwk;)+g|z!PTPs(0X=83r&R z!YRKBJgn;HAkjz;tzGLxNf0~dZBt5^OTo}whui=83i!hjM-aJE;EagL))Vq}cbj>e zcX+Q5tdgEl^*#t4NwDc{7E-%0Zhry$d@ZQ`#To9lxG*hQ;m9*Zm#Y;Z(C)-&Myoy#J7A^AO=} zoCxL-Jbl4x2|R<7a6;uG5BrBLvp)={kDuu^`!Q6#U!;oE_hveYG z8qSjfi^DZuaX8uUb42N9ovEW@VAg5fHhZn!DP$`(={_n%EDOYdQlNvK5%T055dnx5 z042vGE+6dnAtH|U7CK~;-mW%9`|h3c3O)WU4myWTq|_h~2j{VX!8)E?K0pAT3s}J7 z@Ew`L^tsU^YE*&BO&08H98yHfJyuUdJ%tqR4p;tXK>U9yM9>`GN<7l8OKj%!VEpW< zM$*v3*Z1pT-i^d>hmMDU$3OzPrPN&4>F-lGNn_*qUY$&skEF{}dHkSYnOo2PW2pdm($oAcv*$+PPv34? z&1AB!B&Av{$ES25AcOn_8f1UY%JtgZw6TL2Xep0xvH0zfLNaA1GdvglPH}J=CxJ|; zFXO1vS}m!mKPYNcn529v=_Oj^CYH8IGmcTmFq3(S;m`nN{a3y3_vZq_)W+ZWH#Z)> zxAMK9)~jz1w=3qePNIAqv_TAH|5rU~T+Bxs;zH_QS@P!@q5~EpiWvzc#}wZODH)}7 zD_%qZIRd?~FyR~08ga`Vabyf*O49dZ)Ra<9tH#85Qm#=7m42B9K&}92#10bH_H`TeCys;PN{g+w1oFuLS_%57*t6N^a-+UtQmj~TH*XessV~_t za7tR#`hv+B)ue!YaxSUcIELj9o2|LukL0)XGXwRhxarNSO9zJiey=vb9;*qZ+5rV{ z@{>45XU66E^JEEu8scLjUZfJk?6DH8~BgZpLVvt?*VGe2_at_qxs;tko^>aO^lc*`ytls!fq z;>nAuFCE5g4iu7KK%MnWWb!tHEyUw-19Lk+Z~TzD@Vie%(VVtluv&xPhx7wQaPpri zOo*&Ow~Z>QDV&0Yq6Al1`@Cj{>I}Da3dH@7NtTQcdlP_Su(vizgX?;>6*6|0xu5PX zh#51ulV)uuBXoQEslH0=kE2R>k~r;#m9)B z1&C7uW#oS+4K57!-pE&7q4NfUWAk$2IqHEzT|t|8GfOPH?Mj=_xOH z?nv)Y-Na!Q>z)d|Y&1@eC?JON##tNwVXO#IEO}WLiW4Qe@P6;%UHEt%y zFbdI4h}GyK_I^=Q-bnz}an!fzKjKiOXI<%|CDX?{Wat27L~ZPnHR*ex;a=IunEa zm`huhLE;2gMtB16e=e zvA1b7Ppe5841N^o=3ERn1bww}8e3%IlRfuOM-S`;>fqo}U&}ZVwr5(lm!%66!;4!? z^b&Q-_6rSPG^c`f4x?s6K6`ls_5XE9#Q(e|1RDM>ScdMSMr?sd9JBYY z8IHoe07aetUs45QKqF{1;zTQIJxe2V!-FUGd(;X7aI^$ISUDAH)yG=KUr^Dw@&HZ$ z%{F5B(~fm3NpA&~(d2D6pGLl(TnLd=0*?233=pa{ZI6Lw0ZUk%c!{&a-u<`tLIkFo zyPw`KdA8XH?)fiy!0`+0eLtom0xfVJ5R;I^Dr3k|TI-)UKkBg;Fc=kGNzCpKDz#rt zP&#dtWCB|MlQhpJ*f6IZ5vfd}?x}&}=PF5>U!EKhj{6l|YvCEI3P9UmNe@Dj*~-2~ z-wV$nqPQUB=dP13br_S`ImPnPoyQHo0op;m19jlUm}0~{esk>U&e1!~+}a}l$k`5L zL+mcctI)as-9x217a(t%EL z3()#WUYmB{xo6TQ9;kL|y*#!xR>~Pbi6l4fC4Zsl$=T$v5p=fAU9UX|2+4?ED#U{fxSh9DURt zF{S{$0qx-z#0$5f7E2-!c~44e{I!7Pnik~!a+;MNUPj_AJtn0eu~#zcw}ovcv*%uV`VyT)ND6n za>N!t3rGexTDVS?wy;ay$?vbB6=s<-X+*ZmY?Nhfbuv=Kh28x$nBL~}nt7BD3aVns z>@VTv_meh9n)7p_YeVJ^WBh2Z)VQ*-E1KI9sTVK=4sG@597t6%%zx~UMn$~+GqJ8j z{ZUZU?rSStS@cLgub8iC&u0&K2M0I^IKw`v!*h28=mV;a8N1s9JFC)om~G;g!-P?t zJW_1*!hvA{7a&d@RS%a;P1 z6ypc6_~iEuN**`!EMN@G&x$lo^N*TBxog3U3A`xtq#!fIU@6Bp^>VM5j>Eg#Od>1> zcn>GxhBQFym;z-P&=|=zeB#hf@BTC;Wz)~p(3fiR;&x*T$hZT>1yW#Pr(5KS@yC}K zuj&jxV@y&??=6;0ByY7;2iNF36R=tV6aSVD+6j94>e0ly$$JT zn5P~-bmpEM1U~$mqh8(WZ;H#^6Uww$L&B?ZV#OI^=l5ZY82R_1iK=Y&% zHrienUXk3HR1mPHOgaBMlm9MLV!GFoy{4SVftv;R^jDvB?NcT*v0K`G*x7PN2NyFg z?Gv7b`jt*6Vs`0VMcq>Xlm88#_rN*9;dOyLK|a5;a^|-kdzY~n3Fm!g1q3x?o<(TD z)PI9Vf0nk(Xx-DVDa6b`WI;G@Hs}spOuA zTP5E|gp~p_e`jQ4l`S5QR`mN)M3R8PC~em-ueK6vUxh~-2vp1rk>|ewX8%fS;<=9~ zRJ+t;CCD#|RhWcdtk#vf-^&pwzm3|ryc^vKeEEx+@6>~WYnEQ*FrQ+}RH|`tu`Oq8>(0sj9L5(|;x5hZZS}W|~;S_lQ%>TtK ziqto~%3 zR8kI<0ZRg)GoQ28J}R)H*`KzAkxxlT5r-G(P1Tg>&95ERM+}}b4PGw5EY%m)ly>X>V*-Ukn z+kt>k_5DO{~hFOAa%qkYr*3R+814{+ztiLS8VE15?398MA%Oyq}Q!>mo! zJ+!FGQ2*P)?s$fqW(?6WN#ZhMCyNlDxkOaw|HN$D5pMsu!=MMOkiUV3EF#m+B>rO} zapsQ+8qb}{teAdExyA)!&z2JBL_JcD09N6MZz}Ym9PQ*56M~;DZqWLP*bWoy7Ln|+ z5}(;blA(-V7_El$wE}CPlNeSyZ14YMHP74G;X$(8hGgT7yu=p^KQU_kW<4tpwg_My zTI`Se5Quf0((v|w=FD{$A28HFU|_Pa>67YxPZ~2b z4cPjp=y9VR{d7!aT_F!6X#)ewJ?ispI7bN9C%qXI#ONdufUj^KG9b=T+FSQ&ttyJB zPuQvMRJ}CnD^LPHwfzKV0GBqfDo4wcJ8&2U|?1sH#q8{UnIA$+>_zeZvCGUZn)|pH_ zA=nF%`~9w!{gid_xy(ArryCTCmOpo+(+;14(||p4E-U#s=aW(9t>i~N95$;c54hF7 zhs8I@rsQ2mw5OX*Sr`eI1N(52zcCUQwg=dvdgZ1A+j=O^tA*V|cpsUbc^4^q{ZTvi z#1Z}md?WuGo0ok((&Rx^X^k!w3fRcUsfV_Y!1a;*7a%NlO1K;;-}3Z|K9s05_2^0{XgU6M#a+rU#%KudUzgzH{Thq;GCDN z^D0kxgnnlXwR-%pxFT;ToVi4Si$G#UM9 zJOs@d)cNo9YN^&KiV-mr5`hyqPaiDKU$&QyaeR^piLHTa29s~7Ri-IE((~D=y6w!> zYKvC~aQfGl1W^6Yo4CN)f8B4)(}yM9#D89!_WD{q^_gmHw`_iIddKGQ{V&^_Y51A7bo+wZ18xu zRz=?SlFZ)^Hehoc^&}V1AfC792XGE2`8&aqTZrKIzs3`_b4p~l9wQ#Hz~geA_-$3A z;+OI^z#bjA_^WkK>>hLyByYH&83q_#ZYlYWCW_d$Z7O4-w$50Cz6{%-b?5YyDcFL|~JT!EbrE+#|Te!m&<6q!>F{%CQu5|H$s z<7RZjeuLb+oya})6)!n({h!ec`(Fa|z%TMtNSS)0;~TP{PrIJs#`^g=$M=%GxRWNH z`Igc=Z5(09qX*plja5XrZqA{-KYeW^TYJ{;0IP_;mVD-bkU1LuD0?!(riBl<1$zSA ztHM?#0KG9>&>J%Zy)hju7z|9pfIZESU+Gl+FlKtIs3L<+JKTZ&PQmC z+e7cuED$8i3{ejnl@FYFY|!8Hc~%ufdcUPPAP&#kQ7P zp+E5`pQLE4X>|sEqbi_)UK}D<+;gE`mc>l)`yGokc;ncdgQPMDW0AU3dm1W_FS9-w zqyqPFM6Z7#-6@rcvaHYSn@0lYCkVX_qfla5so7FS8H1T$iJG>BLN#}uk^$|lc>)hRGtUZKErQC z05oX22W{+w*eJ1zWL)=flc-dq`jwC`*{|>jaA-zmTkXhEY)z@38qgG z=xCSH>FDFX9v0jwB#)I7!xtB7##dw7%*>~(P86QI1{D&emsBwZ9=u{i@ZAd_e^RC%*#)km-4eYe5^j6H^@I27fsOwoBuoc{EH|+ zKGjY%xi62|4}oZlJk4+y9lO-7FGHk!6Z z@dJv8LZh-keT`%-;q`n?mS3dyl-AQSe#gSK-Pk-@Q0)CP$Uo3SCVu|;XcW>$)Xoj)IjwVRR zXL)^-8;;aq%~R^ON4iXUr z|6TB#gfD+Ag$^w*xJ&Y{>IHzL}w#DzzOMEv$5MA{0otgHSebBmUpNc*x9Oqb z^gtSd_;Se4A#cfhM%;>L-1a3WTF- zGr|TDjdg$YB4>m>5Y!SH7gaokr$XwHUR~1{63dZS&8#K*<>k$|{(FpahSQ@WN=pbD z=;1@7d70AxE@mQVFNzNOd$o4GQG0!m+$r)b37+o<$#$Y8sPt$Dm=Clzff)4Fs z>8UBz{ZvsY$CIhGfV$YreWp0L7r9Q|)b9EDt84KQJA(dFS1U)O(3P8(?G?C9t13nK z^Rt;04R6hP$0zTICK0|H{UQj4i|1Owt!9`TfR}i59}4Nkm0)GpZ>G(~N&k8qtK8`v z_m2pI5e-_h3HV33Ot}AYYFByman%QfcQ}XhaZJT)n4xbScx~=f@*tQl)+#F1UQgRR zcV)&NTWuX^esECwEW7!f*J`DEiwk$Je((&zeDN|sW9NIL+o3*5eKE$Af21G0U_6ef zjpQ@KIA11?w^3r=yQhI*xloU)Xx@%`P0eD+e7l-pz0g6k;Ig=(VMM6^G>R6JDrb2U z!HRaF9#s>DFLQi8cT}?p-aIY%X-(C9dv1i%?$O5_Io5WUs#}Qbs3NJk`>2zCp#0k3 zFVo+({q7Lh6N-uryiy-hq0)G3@eP*{!G^*5W3D33O03I`OxL9n!qh2~zh_azpQ1Ao%_p z|IzmF4F9df^GrGZ7;Uw>GL_U7T57+c?q9`jXZ5IS1#uHq>9JQOXnCFzv@z6+v4K@yx5`j<@AoOx&wiOYE+>ycnVD+-?-F z3gAcFLc3J*TCUxA+q@9;ibR%^n`!Ix`lLx|${pRC-8Vi_Ck%fuZ$k)NOr}UEOPukz zTVB`|fBx~9JL}7->B&Fyf1P5**RP!h|GtY5yck<){`bAX2%!t;@7a&L7gi|}FZFNE56$6Ur9k(ccAwik``YoVTk0@pm+XsOpps16Vk|GhRH7?xQdi=HBe)tUN=0v?WB-EeYTImt>>448Pl zB+EsDkQCNH1auc+$?aFnAOC1;rR_DF!|+fTBgYn6G{0WR_a%N%3vu`2G0Yg((s`Si zM&6M4@#I-&l;!HfkJXedV>YV@9r6YK zzyyl{H_N-x*!KwOiwf_7*=&W7LG{7jr3dKsg^%6Eni(U7A`5G=u<4xS^RPU$MayP9;0o@<&YIn*0!&&G`WO!3%V>w)z3@(vda-gxr6l4KuL;Yuyh9 z<%IbgYM;WWSN4-Fy9zFexnEoK4F>a8F&lf4lGm-6=O&55cij*Q7b8tT z!SZWl#M73iOth}PShXB3-|r>w3!5HxNobX1-fK%nC|->Cqio2+BeqWRZhEXZ+wS@# z4YC+7MT*+HUxkuHt`!YDKq&n;;!n_;>7^ICtY77_^xf8Fd%6CW%`)AHG*XJg7&qVa ztusRTQp`N>X=xI@>8z9amYkf{`uDSz?HhCtAYYNr4d()!9$bXVMMphGe#iaaH=-j{ z|0}m&LLqFLyU|Z$-8<@)K8^Dv|2iD!_wh4kzoC~Ns;7-m`>)(4@%&p%Z#C4DYsJ3i z5I*xH#WPK37?^L4tD2RBFZ*n?>0t&%Sx%5llbm zm!t$DWMS?It;-Fc|FgFBHR5E7+_LjYx}3iu^_*X2s5t8~w#|={lI^mCyrXG^Hgw4s zlbu=T$KAibyvA6LXC%eBE1F;**6@tjT&p_sM|C>dqN654=VG$+KWkfaWW!4>AspmH z94{;^xZ=g{Q?av?oxW4N9`lcNfC*`i(7kv&<`;zH*5dj$oh#EZ_rB4|aG6pxs>&Ll za9+Pf35f39Md+cS*0vUSlpJMreM+kDeMQHeGN(9}rD&jPdzePD^u|F7;l z8;%})x%w|dXnlN6__xv{?H=!I*2Z4D{mX}e)G0R+2LC<3MMnZMWnpt{M>`kI{#BKk z+0^9h+1ZL^Z3^M2s~_s~5Qf5#AhE<@YWzm_EgpM{?tzRt({(&kdWKXZ-K@Az2~IBS zE_Mhb)EC9FiM!e#;}4@=7Ji7Yd`!cheHjFyCsl-3q_b7tblCDCj8QM|O5FR~^3)0KJACuDI-@}~eN0|I~5iO>?_3hC+gmteRn-ip!ou>bM@bB*L74t`5vz*-`_@Z@+2zKA0m?cDT4GJ#w3i?MMoA*rw0y*<92aV--#J!> zOrw23n4>-w*6wiY|IwOgHMGh%?@x?9{m{3Y98;y9o&7Q%sU{lo2XPNluVO_i+KW)`5?poB-UuUJ7a6%6`yDQ)A(D1k2_}^SnJqN}s zJ;Z}c6|AS$xs9^EfN(bdSBm9>UAo<(XeO%t?w$(z=rr%Q90)7aHEba7=lUJ2gccmm zNW`Jf>gloZ<3E{h4)IOD%D;r0ER3-J?-q}IxBfx(*(mzXnvh(|-|gW9eGp;u-!0yJ+xOioAnpjqVj#U#!NoMUGEKL0Gca@^#sBPEp{xnw;pNBk7XMSX zb_?|^*WMO%o{;$s$Kn1h zH>^WA{&(;AQi)bZtMTRcJf^NnISCWQch0`x`K8#|o{EhVQaylhLiHAyQ$z@73AKyo ze?n)Q?BnqL*HCRW;Y~DSAo<~j!@?+^s0KP z>x~>r%GMfe+y(me!~1)qEC?4gsu*bMbb7mC06Q?|%dIQ}`yYQ!CdZtuh>I*ss<>$w zC4ab-)gxU0=eyz-1A7FAd$Xynr(c0RrV@vl&a3C|#MTV$O%{cV7Z7f!i})po9THSs z5Nk>6{*cOCGU*5#Q{*q9O2gow|H%^xC4~Fs(?2^N&<#GDm#Osr(gt;zFffgo%9Bo5Jd`iZXD!56dBAJ^aD@;QRHwZ+Cd3KQNW##2bB;- z33u8ae1Iq_xU>790f*bH6G;u@1mFW%45F%x2F_Xlv|(v=B5C2A3P3khWpr@92VelY z26{Lb1uz0p3~-(d;5$Sy!dX0kS%_kSGmHR>5XB7VJ^|JsiUrQh0{ns~Ryc1AunSSw z;k-7$0YtIES$BX_GVT<1I3o}MnbZT&=7_ujXDtFSq5qWw&ZqvY#l&nTE9cjE*lpBd;I?$- z`hB`uF1#Uu=B%GfX5Q3;!oQE8E08xr?jlqLkqL?SLahDZ{zt0au7pfpOlO0bUTL3g_boo-b3%xuBdWtCaOx#NOA7gc5hW3`I_hftM0gfs31XHe&~g|h($SMdJp zoOUq2!t?+O57jyC;f#vGHR$&_z?dGd03zrfKZ0>k76IfCCOu#k z%6-3>mj%P65rCM>DtiGJZvYbUpfN23E-eAlU<{F=aM=qe4JHgG$H5<^!64yMAy67j zI9$dAN`r}jORPX?Fp+Ti7bp!T3NB3pG(gWh8ZMgyv_Mo0T+#<Bbi2gbpLmVklFZV?Zcf&%F^hR6iCOcj(~ zlL(j4g3@b};PPHjdd*9i?3iGbUh@hri3X+DB*W#}p!Av)xRe}}UXu!!xpSe{#HGO{ z_y7bxV5+;A5vRk20s%~XRA0}4OBn*V(38r9%PazfP-SMp1t0-3)Hw4RE>Q_kUyd_x z;1Znx13u9bG8-lzsv1&k43Rl-X;Uc0CKoQd3Z>ZO!6jj#6q|gwTrD69-L0p2he7%aH?jyWjqE~yLB4~_HUnA^RScJu2J|7S1TJ?Cm_Sr1T#6g8 zfT%K|e8!bK#4WQeMR3tR*l5LFKs-w3iH zssSzx61;_|PjJzapctYW;eskb1w=K$#a@CMRFyTu#b|>1%PMPu4d!gVsIt#6F`x0E z4XUzMxX@5&ZG{{81ulXVwYKsVF3=RUw$cU{kBaKm?QmhMs9xOx7u|~L)tzubu&7?$ z1rsXUfa=xVa1phrUfly1c#G=Qy>Rils9xO%6U9pg5ClM4;-Xjg!({u;155%07jNek zb01@=5+tf zpQGdVfjMVsG5%*9KO%pXe@L)x;1bT1v(_DP zF3J6qL{YKbActzzKRLDD-1Q^md1gUb8vkyZi7;0Wnty|no3EzeIgV>cCj4z z|2qv7W6$i${C}4NH!$Bub1NI_{i>~fk@RH6b-TP|+00@*s z{fRT^L6-ZWn)~nfFKAvVT{ZN(X0(7aG57d8Tfcun<*k*ow!8k8Y&MFoP|baNIN)A- zjR)%t>+?=;HSZ^P?iw%id=`DuWl-Gv@6n&&1ypn2na~_D5UWt1Ucny^nhe;fUHiUB z+?qY78YVn=#_S-U2x_4E*nJixe~7(OMqx(SIzJ8~e80Y!mH;4|!C8&)8?>Zo8qMj(X#oEUIxhtL2@4}lc zN@`yQHVL3lrn8Nu>jbmZWEt8WCrihN@c~ZS6RC0RZb3S}Zx%83YeK;eRAvA6rL`JL ziKc#QPjlg&c!v!?OS9Vz0;#Q%*qwM>E-0kAl z7~ArjHg$8)9NeXf(7_1~_Zuuu$b1xMGQq;Esok1shn`$5^Rpg$GTEI!Y`9@zG%?3X zC+%GT5CX*eixCh}+i$R(W`nOu(-ET>8d2Nwjk<5=PambyZneSjFuH9Lz#v4uFIPNM z!)i;6MQ*<17I>a7Iqr0;gv;0_?7i4LYZ{hL)wi$UDs&}i?z^Inqd~8Em@N%6HyXQ& zLh%F%Oau!4cvH=r)IR7N0tC>Npko_q_Y_%uz;bbvznP%v>l~V z4F%ak6h`~g&k;VP{q78g$xk0Hb- zKIWE*qF@E>oP+}wv6F2PV*zi6=_E-^hCaUk8IUF?;RN{10i2KYmLPM zHh~Ist%R=94iN=fJL&{#SijyeklWnWNc`u~7TDTqncgH)aNrFzA&N+Z{D9}Y(a&T- zR(JVsAO4$LOg+K5Y#I*fxPr86nVzNjACXObzd1y%=&^8rJ?KRC$?{L?f=+}yjNyjV4jO4B+JYZJK)p>PauklDuwLDds%G-e|zc7p}!#xzV>U=vkLNFEi+$A zoBDh|g69xLeWp(y{deE7Mb>4pINpyrAyw>^&u8&v!_PmCr)91`8~{P6k&Pzn(K<%O zkUO``xJ&$TbIYjP;DEojsZ9%wNkhwruHTa&>~dtI{hTyE@S6;qO@lgWSwqGGYXpaY zHLsH~ywsO&`s>Z24TrhJH7>->Hv*bcn~4r-*7E z#6$H%kCqxFZ8s z^o*}<4lm+>HxR{S%JAbgGC$pt?C|R3Re{$h7|j8p6XDK}zgrklD_O?#fP9Ez?klSB zvy%;_afXb_eHk;)MmQfx$~z?DBWihiWK9+DEt}$p$36KpjM}1-R-pDq^kIRmIRAGx8Ip=^HrG=gLw_nP_BR~kV9qA>oCWEY`>U7U`WBRH9Bk)=asKTjmb>Ac|9tDV}Vy=o9XH_d^Tj56lS|PF^8P zpN`mnN+jjIaqBgJGI}qTX}A=(Tk@Fx=H1Ab^0tm( z{Ibfp2NPO}#tEBpmrCP3(tq~8+>i-1c1xT;wXLV0Wg~lO0Hz6{{>f8V&D%xe)he|q zV#xG&?Y-ez_s*QA*VNW1*Ky5m{JuJvhpLQM_oZA(A-pYh3)mDlSg|0K9QS5Cs>rVlnC>L%Wh zlzz?6T|b%|By(@h#3Rto5A)SF%Q~w4fHXs5DZkTJ8GjmchDW%h@*`r0YW- za12obQ8!<{G>hjwvKg;Ys`%bVJ3sv7*xbe~v|-4VBbuzP5u8H;yWrOduAKXB<7b4J z!AW-CS@v?X@2LG<`{G7OTr|<`b#x7&69Fd6iw+=UA(cvQHmjM;_4a7#oGtv$8h^=i z>`MPp-42OWy&W18fJ21p>B4O-`bO3|L$%jcS91c!mb;|C9oO`Yr-XJ-#=l6iap?m1 z(A^awk^U4Nd=o7=-^JuPVdj>Q`#m4Vley|X-Diy<+(LaFfCRb<(UyrcoflcEP0MxL zv1f!jBqe{HM8DSESZ~^6OqpZ4RRJg=>ULIZxN@w-rh9kHH~nutf=UVfc?kY4V*8sv zR?BQKr}_aMM2QWa9sI0s#i_EDt&>JKW@Fw>@UrK7Z*XD|?2Yr4d&dwkqpD5Z_0e?d zcfQ_t?pHw%>0li9^aPW=^1;wGG_QJ(O1mdbfc>)C?ws>r5s0qat4JB1@68;~+K)}p ztYM*@j}_f{yRtsjq`D@^{1MI`-De!ffPhZ8`Zv%qccdXB0^uxPDdYzNci29!8{B6Th3oT>z9JO7;pKvpLBS2|<1BPY#Fis)f1| zGcBfLk1s82XkN(Rl60T}QF3koJ4#zTvOM$n=l6SOF}{y&R?$?Q7Y|FbBF0oi3M zj6CjKDbY*UFrQ>+PA&;JvZ54T5mT_26B`KpR6NJ64y=eUI4|A=MJbT*emQY&UW?E| z=1zl&0{z@X+xT6RREcjtKRs}6c?Rr=h`8gFWMniNy1*!cOK492pp+FIm@&y9bGejv zG$%Fn@n-;VA_54Wi@&J+PyOF3A!+pf{4@WFpih*_JfAjn2VJLE#%b$L(ZjmifZOG} zr6MBv@ZRi63tv2e6_qpDc-C1>=h%+1vP|#9MzP;on>6r-YDx9cqrMn!W`3%Ei5LEN zFq_ySw?APL-Fe}-|7POR0aeH^;0xVBH9=FYhu&SyDx|v39UFirUR;Q%TYBAz>Qv^9 zt57S;90-Icbt9#Agm6gC*pbj6Ph%zFnE16m?UwGZvaW^T^X^d$`B zqy^DMAn$fyr`BI#`{or2UPF{FM=GCdUQ)}6HdyY>T;AZ46%B4B=Cx&yXm8hOHxI*ba9L1vitOjO#9_hRreZs518ar5khUWhW&ed8?g{`Thc z9GbzE{G`gxivGW0yD5rOlVQsZ(ON{VUm$ zI0GlHFWNt0eYl^R%)DDk`n|ExWb5Vl_)@OO`XHEtD9af7X`4m-^57bCEb+3s@FlIx z^G`_0HSx6>qo}MdIy$fnQ4ee$5uFPjG@K_feZ{(-SvyOh^YvQ`?jMrWwcdMs;hG8H zCq!A*%yjY%I64L!x3vcy7^?Qfkaox)2L`>@D=phm^||{D{DvrNv=VVyc{~qMwN&(^ z@+Nns8FK1)to&1At;R@eWVoI-_zO`sBSy}7BI==)$91kBzYVuD7v?{^bxyKn%KFgl ziwHMoF*t&#ha$gJ*FRvAn?86dr@u0wk8syd6?pM??JS2w)SVI=p?@4L&0kTP%Al_nF34oK&m57&eDPlW_87 z}0)KJ}cId!p0(qRNud_Wpl7f zvYdX^3bl>hm5JaXmK9a+S>`73hL3NvXOhlUe~<7(?pLHX#((uQl2O~(-MZw72t3)@ z+#;^a1{}}OJ$py_-3K3OFJ?1cu)ROb7=hZx?rxN!y6>c@X)8UY2(FyR$n-l57P=We zPIRoNeJN?fC*!tHVS(Ju3+@H^vryu&}Y?bHMrZ(pn*C8RKE5lpaFO7{uO56TaI z-_O*ja`QKl>33zEgIF)NvkfYZN%C0M2S-)VHg-egQyPsuHn+&4-;XC;3VYsT^I6#c z<7c84tal4$*ndi;m5$oR{!EN%oGMsw<>UrVX=!^~SMhC5YlH~aD}vYGY~s@&6>g!n zvHLb#zi+g77Ha=U>Wx%BJC@$$&5)zO%`b`bYEp9a5iws-+t{DK#r5;1J#Vc|ihob@ zkdA5rxtfwi|M4o$>v%Les*F^9)HZg%VxmN4!Ek1SD_88xlGjV8y#9sTb>GpyXY8x= zt0=u*619!pKM3mynLnF()q9OQ_bjor1LddH2O0y5uL?KltfK$GWkzjd4{&;U%*Y{- zwR5u2PcuF;n7wiHrUcJMeUwF)V)WhoETxNW>~VpG9uto0ud$XrI7+RJDa2 z-rajHCssoo?Fs4$3++^D#6}`?@N|-VzDwTVNoF+w)|b_WeE*7QNSoIHn(yj*!~}B} z@F>c@e079nJCDn|DHY#V1nkNA36bI27PA$0&PcqmbpT3tqmQneYzaNHG zil6cuQeq5|5ux3tiJ`Yl9{TP)3MgeVUzD~*b3^dgJ+I_qOBem48-h||B4Z~%edmnW zo0%PF*vdki7Z_;A7**LiLGMqj${v}QyMa<-qMT0AZZL^Dg+5eKFl))zp3iHUro0}m zHSUj5<7c-*`UzHV&%4Fa)woltPe`sDPZtEBn zf;1RzWW3Y;l&U4G{C(`>=hSt)+sHy8&hbdgF~WtuSg)t*35_TXCc#(w@RuJVLQ(u< zYV|)H3Km}SO^@n=*Nup$bZ={#R9jFQOyU_WT0wNW^OEeT(N!_(Nt0Jm4qY*{>Owbt zUSZdtQ0b#Im?UZg`;;b>Z|SWAyjyBHjA_ek|-Y@~c$2t+9jBU|vquD#=t^ z+e;4`dm6>cE1Kf@65o5kZ=$twPIkoDGh-{b{!vSe$Hk=Z8f2^yA86R;wS0PyS--1l5;S zmXghl{R6lSP3+IUQ|MqlJ5tuXMZnNPGgPNjsO7L*{t48PLt|R1`3D0Ux41>io6}^) z%YS-A)a}RS>}!{$!q~8uzLp+8hm;sYWZJh}icA;E`;m-H8b_giH3zJlm__Y>Z59i@ zDugukth=F(A0OJt# zTCMlXX2EdnM)eS-b_36YH)PaiW*t^O*GN7G%zQ!Xvjo!+^@j0af!W)b#n8ZfQ1w`` zBGm}Jco-o?gCjfS_lXDRj2Y5kxRKeDUw?6gqCf6?j4|Oq8}dTf=ccP)1l|*;Z7ei5 z`*rjHlm?SC-!-HD1<@(x{h$sfRkvX_?Mhwhugy^o(p+(js2g40VB`PH1^+)chzbQ& zyZzsD!Cc#tXRZ&=>uI8+PNM#K)TQ>xVxcD;B}m9aIEV4elG$uH-Ec|CvD;@^mC zt$*q>qbnolv~6QE*Bzc#6yS{=+w`FkR{(qD&|EP8+)Of=KH-j8mM-Uqx?&0)zQF9? zzUHbMGyzf%3DG30z%luMbHTT(5$6B=2&EkzpK3(*D>aN0Wn^KHe{UoWt4Y`NzJ|#I z&QW7?TtPO`OD%bx8%7fejGy9l>x+2uvtvkK_i()Wd7ED14e>vK4yD_n=9h&h39oAZ zOlkLs2f0%5c+))bu8WCM{L^cbpKy3PpM%O2;838(`y#!n<3F{_%i)Q5OBH`pXOGF1 z#$%eE3nl6~ehx<(R$Xd0@6c85+uo%-D7~IHNBHe~Z{k`0X&p; zQ@lV}=l!aD?fk*hh;@JQJe^3P*JMoZl4<0}|7y&INFY$!P07KTtDj9cLQ>yGM-e7|lnweI&I#Yk>M#Jn+OBOVipjcV_ZKZHx z!x}I{)lw$i65ew^+p|Ptli@baa+}Z-_8~v}o>-E{FS;#86S@Ilhp2M?Z-?_Z?+UAw z;~VAIjf=iMo-;45I>A}_-Bo*&%?g4qySg+IrYR{*?v103`@p#?e z-yGld|J+u50I4?I$jX(9h%Y=PxVR*foQHgMdRG+nMf|AwBxlR_ecw8XTGyjgoACef^O9zLfWSI^?E|6D~Ooo;QDNHYz@QKL=OZ)^jW2}k`#7hbGj>~M2a zBK}oUEAQcvggtAGYTLfIKiO3HbG}&b)oO6v9`Q zngs4qK!+Y`D&-Qx3K~d#&X=!vx%pkWO(kwrIz36Mtw{3v>W#x^WRP}ai2Q(c<=s#z zx9IV6X(g`2_}lv{0y_w40B^{n(Dc;K&#NR^7u|qu%ue%|g;X zlWQAFn+6BEH@Q&SO>F~_0P8bvOF$#J@8?E?cU&eYVn#fxDiQZFduo{ajt@$^spHwJ zew)N6_x##}k3(;1s6Pz&IG*fa7h(^Oc5L11|KbG9p?h0zH?vDB+j6i=?1;0P#(VX5 zeqVtQNh6j)kWd;kBy5@hguD2%2pkiVCxK=BfHBO$dNu>xBQZ*zx*)M1*?K0!8uZF9v(a z-O!DrT|#0=gW*Ot^ZP%vq0gLku4yh$A?V1+yT+aOuoxX9@5lL1j)dpMA}9@}E=V3w@<5f=TREWXR_X$>?Pwjmc+UF)Ma}eiO;ca zPu+8T@Jrq#KSUtQdh+ZjHIxtFAWw>1e>6 zonSv9=9Z24$0y9OG&(RD9W|_AFF(g->O818E{alOI;rl<{Czze@OfB#qD8pLs=_ra z=@>ciWh?p2V@hx!{3}X{>C#`t7UMlL#UI_J5V;pZe9IicX(SL5cRa>&&dr0C?gPr8 z=hV%5XWy8~i_(Jy5u zB9HL?2M9A?aNL`VIT+Ess?bWe(y2*Ov5L}Q1_*H-+cc+p+ufh({*X>Ry>eiJCrlYw zSoM9qWG7m#$rh!-4Ca@g5-k6l&<$+Gh+VxoO_BEw!zBSky-$;wH=|rHqd{pfLwiD+ zo2@dkA}0*Id&7tCaQo4-Opn;BEuW-I2YZg8DWWu(;kv5KYja$o7L{CYoOS8IOCmRF zrt{uM9~bFl0#{XZlfV?J%D$OkuZcSw%zt9ksUR%yILu3L5wVb_qpOxsv}##<7D@%? zE~{*WwLP45^u9PURp_S%&B|SOZGv2j1HF9~(u_9&i-T`&g5`@U8@(Q?GS12R%b4$A zXg$U`{dDYTf_EV~>+DzF0_!F+`5#uDuho63QeapHKZ{%bxM}!PQkU^;V|7 zb%jaidZvJ1C?#f`ts~&3;EccgKy7{DzWE)^$u3W04xO2E%*2ZEW7V}jloB&RI-K&f z=CA&%A4e|h$PQL6hc2b$+SVK?y5A#N%^E4YC?)25BZd4y_3iss?Pc$OOZL%391}e1 zbB-cEi2K^|9Y=KfE%*n`%_bXFFe>pGl#lOSBQxj`C|`d7Ccu=ngb;nBx0Y-AmJUFp z1WY&=bF(Rlu3)oU*bYyB4{6+?UgZ&cCHh|4@2XyV174l4z=04oz@|j?>gfnAi8@C{ zr~SEBe+dyg(gT9!wI^BI^n_6}uYPGLAzq_Ym>Jyouuh*(e=zyYT=uiY0NX2}s9Ndy ztKq7FGUC;PX`v_;W>#qiPm%Nry2>@>#eCb;v`=!at*hfMIeL&Wz%Hq$r3gxe`5{HP z(gP5+Y*w}S~n``v)&8+ z>|OR}j2*bO^|e}5fhZMb9$U|3_~Sx8+jb7NzrV-ZV3h_b+!=~wd#17tyCvyDMU)D& zKueewXydTE6-&_HOi0P`b^bYTE>o=_d54{$h%XNN6yQQt+v2Uy_XI*T;wpE{9mytE z?=$FqT*KCCUY9+tNkY!7AWFf_%W7L{{e>4~-CDMrW?U}rkYAC+k-c$NzVesZSbyo! z!3NuFAVdin1}(ozTFVRD3E|bjF^_BsGoF6R8h`V?L1HaIi--sDDrE?y#TX)2euguZ zfB5w^t=h{-*(xSK2WLaHBDP;|nTuN9@?+R1N|Y9}N*R6|M^SmagJNO3ivG(QQOpDJ z;A6_dU?;@=*$of;6qFXTMnJ$^{jrqXew|}_3=bRb%_XStBjjGaAa09|mj8Iz4 z`X5AS5TkONE3@dFZtbn18hdVwsEjnxvmgg-pK%dPF`y2OFh7qav8)LtzWpt;E~%+9 z`6HQTjB9Nd&OWZ5q+;hn`R@VHfv62ln*s7R|3N{LG zI2KSqW&+&E%^>y}9muIT<^@h7PkF9_?D0R{NFk#Y-jC!Pv%{Ev&roIpza}w7Wws)M zK31PDs*?5I71YsMUl&Zx*3M0_mO&Dov7uC$t*^&l?prMCao*};96Y6M+u?er%A&@o zqnk%A5~y`Iiw32_{FdD!_e%KU0l`FkeqSsm)Q1w4_L1 z;dBWlGn-g$Nq+Uz!4svz>^_>dwMrRHOFq7Jo6J1-#|}{}VbH!>x1UjTf0*3M_$u%W zRb_vItvj}JCx6DWAU~gcwpWW%%;2mcY;ERk`ch%_F|nu@1YB0xUx(@T9@oWE@gD=i zB-n)O&Uxjwq-Qx!&rWR$D~1f8g@F)CXiVEWIaMc6p=>*X)q!r1p$ z(rFm;#g$y2LzV)D$o*r}_jhar)b=cXVEm-c688V7z529S_`ykGh8PYF-?=QxQs5w} zqc~+p`|uUFr9`4*ux73LyLyI)BV5sE1w0W;B-cApmI8+_#4|9$ah zC!LLve6CT;Q8@Nqi`WchEqj%;)M9wEI=DG5;N$;38!Y0Krud(Iq8BTJ=jHk(4%)5O zIk)roj9f7e(j?T_5=vEn^A*&&h>3~m^7@QY-AAW z7};A{!8&M9fe|S@UZL|7e5M2l-ivV_kzuLCP|D>$YB~^7kH+w~>GcMMm{()l4u_3y z$YYg>kD&c>oWFAZ`Mo4Be(|y0Xz~$4H2V46$U$*e>>ZL{B)4crvfn*~ObDPoavWs& zUb_7Z=G0x-y8Y7k)92(Ktj8PNy`|k|t(a!1(2Fu5KzHo8BkkFETl3C44bQ06=^m^2 z601Z_;*;cx{hW+^eQ3E7dKws`+WOe*j#Y(2_eC7QLrj@Bi)rl=PnW5R*X)ydeQ--r zCIp!E@k^(|%-?CR>$$korG%CIB4lG2yWZXr5!dN_Q28wbWkP_p-K;ESUl{gdH7#z7 z&HibPW>#((`Y+PogEH}_4NrbVpiBs`r<_zdcV93GW_dPipA)f{H*5WNDIBsqD`=pS zh*Ou}1?$l7!eLCTLsm53$9H|cJNcQ#nM{$b`&&qD zDOMGrFd;~q8z*%5P`ME_o?->X%9f9x@DIQy4k z0r#`-9VEj^KRazcWIw=-ye69PB`H8U;;*%4C+=FMTBCb$R5ILwYj*$!{_{qsv1acIF6Dj-dC@zn88DkkrR?ySzm zL~Q08Puw^iO}aHiIKNf?<+H#afJKGif|jeh;;sNh^U|)=R_hFe}G)h#xwi zck1OY$#Qi;`GNo6`R#l7EK=t;4|Dq_!e9DrqihIBcGz!quq0t_;EHu6nO4Spl!)eg zL2!douwJ{9>GM_P43rH4DUbW(R-1c18#i1cnZpOTuO^4^7L*CzUv#>{Q0b-p!V+ae zKvwk8%KUX~MIPG0_^jYcOFOUbcYYP=hTUTcDZpMe~W z$$yEmA)queyqnv)Y9!;ZVDt7vN&-oz&2Yz~=T0gi{3ML%h%HHQ8+!Uw-Q6;R=r1xg z&pVy?muIiVyYs$ZN)1!^bbWivZ~OZFN+1bQ)HdHs5u~4W4nngLKabwc`PwnczHGyJ zFmhTDn(UU;9SCG0ibj2^iz~}Y6?q=Dn@bwMv-iB!T1Q*$SA!5PqYZua%N59gfE!6$ zXQ)$~chA>I{rPdq4|^-?i8a<5v+KnYS6eOBSne*mq6`S=Y?N+1$UXU)cr&9VW2M!K zq_tIOG5;0849z=Nzh@%RLMQ_QdffkqueXe@8m zmJ|@A5$W#k?gl~P-S^+;yyN+B#`(U-a15DyueE;HoYx#RA8s(IgIQS71Y`6l!@q=s z^WU1_T$r9oH(?QpH-NN&Q;qcV`o1ZBFp8Dj`;=hiL*5gR z{=ZX=jQ&&C&c~dmBkjh9Mh)!Xa{u^9EPkw%o*)rdr3sE!LXZhQ%4>4^ zQD}}9U2Ddli8s||bf*@_|Ew@Q!XY~g(GX~ZDYE&0DicaAv21AH$;u=!e$eKyfX-T7 zs#JHN>iWc6odIYF-oqb(jz2U9GRD2!2={@4y1L7{_Xj-*2~%(m)T##x_FXE1)5uPFh-FOJ``gPCAW|L=jWTi<6y>gPeM`9p*D2OHJ~A& zp-Su$jUfCQ4RzKn)|pbXif^lDuVi&J08#cE|-BMldyx9Z3=CEpFW!sJns>c09jHZUi#_)RB#;cskw=>B*T{#4AeCvX z$PPRiQ5*4+M~>5NXrzY5d{IL{0?GJO=<>W^c*ZlD#K3m6c}a?=t#sRGb07K~uKIK0 z2$+i(EY`(8*SlUp z2{bPK4O(iO@Fx{1N`%qg6?8x9eia0j0#(McsCI@L0u3$EPC?L;?#A=<;ZtRDSQDDk zgsT|)4&`(UsPbQxu|5zhye}|4I6B91Fy|i$=11}iPyZ{_0_LuL>bBZR#RJv-S7jea z*{Kz;VIQ;3V1l-E)UkDr_8Uk%Fn;RLWU?9r!pjx%i)Es%W zc=kBj_{TX&SG|~FIdovcBcLH*m)5$W_p`V9;IS1_#Re72|F_gD|2pvtO%r)pv=>it z0H7h@AYGJnpLv_VWkZ)TTGff39mqOy;7nFxP9%q4AkcaL3o@w42UrPmgd z#Tr3TlIs*OsK|ZGlA!;7LDuzqz_hAc4jc67v2&&!4_jG+XG;ik__e{72{B}3usK8_7AsK}3d z@WaQ9!GM*ab4Ax*y?t5RXn0YmK;Z{sK(64`#|UF!P*EUY$k2^czvT)HDhejAYOxg2wnp-}ZHl(TXr+u~8Xz2+B5^F9d6M1cdF=v& zibB`NJ(_~~mJ3l}I~6%3)TvAi+-&lQ`D3jQrnShZ%#xscpvr_%azmA}z=uZ?26^4P zz2Dz;T?kdkr>O*5Bn|V?pnbCjJ^iaPk*IovmNK(DO@7Vr`4qDB&R2mYsFpSq=O5x$ zL7D+Lx*#Y5m4P_XqHM7Go=?OE9AUb*1!HEUUlM_+NxRJjr;*Hj-;Ynkpnl^2$=Jml z2)wwbCr2Ap+~mgb*?x4aS?$RnxS3AmA!omzuuMY&jSvIxc5zbnl=-km#5+;_%!+fx zCP&8fofD7`8e%ZhO&dojD;^|`(FT9~g7fJXwxAGNBGuPAOFbj6(uX*NMV-skV&wjK zpA=3HNMj^6OQPps*q%Eu8yl}es-95u&|zm%NnR7LTxjuEF=@$wju^>|9~y~3*j7u5XTy*FsLZq zVBrm$Cs_j>G15m2Fk>?_9O1&~joa!?*6*DX#V9|Q7@tl55%E#&JgfyeVq`8?n2~4- z#(oH$tmYt=xF6`nA_s^=X}uMN%J-)1lSKh?7}-CJN5)WRFC`ik<;#vW+ej+?ay>He zWU^z2c+Uo%rba*xBbPEo1foAAm}mKoz_7G?Dd5A_jMqIpFdYhqk*6Hra!!Mbl%~Lt~`o)v^hio52qjT^Ry1fh%#2AB>&53RC z7k<4mRJy^INg@r;??=SL%S(WIB?vI`O?Ji!7V7l^B9P0#Cw0h(YH6+AK;l+>G?U03o!VCX;&HoWp$u z9?kOMf)b)7d63kipn65os&Q+IR8g7(NQUGeAk-HKaXdiovz6P;C*%%d{ATWavMP!@ zr4hb97BTcK&G8(hNCE+b20x~ntOLH0aT|YVXgFAT4eyqb8f`{VkVWFVl?xu{bONc7 z{Lc@K;SFXAdmnUm@iW}-uYn7s@NHX!AC1YVZOb>bQ^C_6UqRZC!h{SX8iCh46qiZ( z8gf~aB}m4^<(Iwb8&>U{&kmFbs`LYsvVjH~W8x^2Oya*I8kOR;Y~)edG6d9FA12%r zU+b)b^tmCkuj!N$uoFig!w}0BqE)d`5POf*#+bSNe*Acttw^p7`8aB*6Ky+iC zm6%+dkW@^3!_BwhY^ZTIk@J1>x%;qpKKXtVHuk0lXrQrBib}JmU**B^nn%vQxn^V4 z+R508mrS39eE7UqiCSn&m4zH+vKS z52TfHBLhMt^lU$tG=j@H@2DyoTHE8JQr53^gQe_#$(dHb18Hrb5x!f^Wmkg#nupxs zz7WK3y&|Zz%ve3_aE8J@J6;TgHa4yW%wH$Z?8~B@*Ye$rSX7jx-K;iv-;QJ3F5+)!=Jtj?Xy@EO-@fAus*)b(c_JFB{DrF9Pv9mUFbk@%A z6=pfZybAC@y7$03;Jhkl?aZIxA!B?^O;6RQB$4R}#(WdF`w_E^pB3;xdhjAu^-a(^ zx)oZ|OAe8w6cq1Tb6mWO7dhg8c+a%KVhBVqo^O*Cj$e*`{mj{-c(A5(9ZGxucl>*h z=lY)yziTFg@I`mK{J#`=UuTn1ad|9PdRa6$=xx* z5p~d}NrTY$C0np2JNHG0_K0M#Kn5)nB#6-l2PAJfx=50%$#?uk7djqBR`55iG95O5 zXH~)e>_rZJvI7J$fxav{I&U9v^PXEJj2T)e?yw@{6?WzDP|FRGzx|OndIW-)&%doq zCheoi`4%&>IxqdYtbbi>^u`w^rh=k~`=yu;bwJRhAgH?kj`tu|+^@=OhbZ4`e-aq5 z{Ot-(+!uehYmr4c(Z^gG)mxMWLLdcxMS~q|F54WoqP-$*S^`0)o;I)_+C(~42i_vN zMjcOU7|E}h4epQ_SFEZ6`K z7!lD3Fmkif35hbPyfc^O-tp$U?<%krsPljaGL#$1{I846i3ioi%UzNK?do-R=k2nK zgC5Mb)V{%#(k~!@32X9kBuB-=y{DOau6n@@2~V8LG7!Dyd$P#HjASiV4Fv+2a4D`q z+YM8mox=~o^As5dt6Bvp*C}`v>SA^ug;OIaqKGKb*y>S@Dp5OODq@fF*%co1-3Jdg>_Y&E(X53+JUi2Ow3w6;E; z+T&VoP}Q;Hh}+A}euZ3^^&yYTM9N_7!4*hm(JxQAtxVoHJ-P$b1uah6D|o zA*)*gjYcfAq`i>+_Z zB7MsF_`U)GOzQ1^bBDp2H!a3&8ess&@g>xc3R)LJ(MX3F6M{WaoD3jEF=_)X@!9RcWk;V22Sen211bj4VEvXt- zzTFV7#^BbNp#uV#jAw3k&Wx_6?-?z^egidG%o!M~w+8#NyoW_ z?(AVFB!e3N2&lLo{vd248-c`>`%&}knVF$Q^3J}-j<)2NO5 zhxK+<&3q-je*!T~zRKJ3dqjG7+cxyXqXZ=6m2?B)*-)_Y&5K{_y13dMZfdHoDFuEs-(yXCfp$PA5u9OAR zQo)amMF|Q?Okp{uOPoD!Ab=_T{rl{=Eq4B1O}^Zn1y7>oTkBqo`>Nu|k$5v~x7-Lk z5Wtj;CF2i(qyDC6x8>2YCWuu~OQGim52q-?9z{R>-q_Ru0+{l#3~0)9ts-UVZ6XT_ z&c6o6;qKE2`8<{`_{WG7M~=!X+0MWq#FuuwQ8jEKXF-)zKfX{g5S;Q1 z262OCfGYb&5yNjkZoMJ~PI&3sV#GeR8<($qK&y|N5YSVQuyrK{E&i*r%Auu|#j-jq z9POKW{}A&!6`IfLrOdoZ%+!;o#F}StETFajs;p|K?@rrRs$fmViVmFxQFvT-bDw&b zDK*r>5CK(vK0^i)!)Sx6Eni%Bq@C;@PGh~dLzO;f$gY)ESw8%z`Y0?DnrK%!2E;Hm z9?BP`8SL6L#TIsZGW8(?LT(PZr8(cc<1x66Lk(P$6bA^Kye71J3G3sT9z%IT$mcx~7Bl*T?;NeN4Dsmj z&j68<{m*N#W%p?HHy>_HLG3cAdi@oC_2KE#pgR$P>4ztv=hQY*Yf@yV=8t!$c7B^8XOd}E|FT!75BqZuTB1> zE>%BRTN?U2Y+2W-{$*VORrEVVF{KS2(uzlmpm3mXzW6ig8ysn8uOq4hQ}^erHxOop+k~bFIa;PpORGAaXH;1KQV3I(0E(%Rze->54D_^_ zuwYWCipLc(IPoZ?j!`Is%G4Iwt6P{10L9d(*N8{#Hj>H9TQ?0!U*19*k)fN{1JwRU z^Ih}pVzx;qKruCj=znmFnvoY;Wu1zsAf-p; ziTatsB~P|v-=~h5qY1E_3E{4;#G5z`wdsNvhSxs;HpuB@o&!X)wWZg@ICh@+6T!eD zj(V2!Vizj2Q?pjPH5Mws208PrxQ=9HnZU&R7aMvHDfp`|Dz;@-uZMG0fslTT42lRK zjGARwl?ga|>@BUncNuQzI?X-AC-7A-J>qTl5@?T_+4lj2QFEf1oO-X%np^vw1Y+Cr zn5eqQ!9Rip%ic{H9F^VA6>o!T|BViU=NJ4^qVvBi)@CPpMh!qqxsaK-D=b_|L_zlJ zjWSr_F+q%wK%FgkFJ_BkYBPO&QLJzn!|>FPn-KnVcJa#~QadtAdXrmjgAWBUq;kf_}z?7R?(BA<9|cgo;)et7gGGKkz_ds5Jzo*Cu+1l^gm3I zoZ#Kd;c>m6CT3K0i3zgEgwk#+jf4zUZ$a+yo0S71nmo|Udox)4EF#D5p99QH4YFJG zac&vX?vM=`n?d`KPi^7K*fn4s=*bgRXhp>6A3vq4#Og@6mHZSXg_=vQ3BCfIKt8p- zq%CKchz$m3?0iZ;HYkJfbz@*uYt6QAR;Daz{pAGTTZX3g>Wa#q8m) zRmbz`k6zS7PI<=uOtup}Lr=mQR z_K{*0_mQYr!P-0KxsMvjb!UgSVJbC)6TYUM{HHW3u6q zBpw|&XFbVfALPN)8;2ldayX;^ZVZP(N6VC>y+V}yM$lp0NeTw+V&EkZbh0!-C^Phv z$zc%)l^oI#aa1E%Lso;Qxgd{2Vpbk1l#xld(mfbv*5gv5{J0z%Km$=meTh3>Obt^t z4jn-HsZ?THPQao*-72Ee*-2Gp@DqM^$eR zk#;;@^jU3ueH3)86~KR1{|h1^2W~2-%iHRENbA@Bf5%2>TRzr+HtN%e$o=+~WuMfw z-D|SuA?hfIC{B~Io|iR#W^`>6vu*m5>UG1?>(ZHh_y>~sZ}0c{ost5VOz!9}3v9$j5`RE=7N(iqTOZvjpjiQR)W!EyY7%?Ou5$XSi61nN7e7YzGDjTV zO^U(Xb`vlgyQ6~GAQf$t0*xBID_435@6KSWj_Oo*x3Cjp6WCJop z6i1$wLR)=UZ_5J$z9 zlMSn&L6lJtQCxyB3;L2CJhcGRm1h?_&(~xEStlcCL0-MI%#)1Dm_R@ob?01_d4G%9 zK4^g6GkZJH`jx;i;L#C!pN;7@Wo{+%q!pwLoS^rmzWSC%`iGh)^^_G7p5_-RuN)NN zV;8qN2ZoC9V*&jjjeiyQ2k}|MQQWOZF&ZEL*MnxxRoB}B*+d)f&Ym+JL0S72$jl-+ zWYFSaz>`YXpRt;-bL8XifxL9Fd1WcZHJfw0HIaT@L=;<($i;8Dh?MFqA)kM*2@GwYMGuwlI zv)A}+W)u)dJt_N{^1M%#;q4n2VHQzpAcDF;fBzKRIb36TN`qI-_Yn|BJ)0@^xxW$y z8}!cF9ODfN?Bg`<-$*}3`HXBQi$oo=@h(Z2HjA@W2 zI2h2>C44~2tiM!FS^CE>MWP}YdwOuImW{?|nA8okQ+nYLc@!{~1f@t?#5vk3V}frt z;vI!*$~D&FdDtD%sDA;*%xhh&CjrS&eTa^OE?g;p!f!~dve2d;(PAN7Vc_oS$Nx(_ zbaO(L>TvTV5u`}6 z{ezuV6ALO4gBF86y7V4tyRMPl+x;+vHUDhsc{QXh2!;YSX~F$fqpD~QW8hUNu3F=^ z9%KzO-kyhEM5!3%()24~z)A(0U*W?_A>ZH>|H|Bn&fhD+@5Z-9Vm^C){M9kP z=u`nR1*B{+2&2lhMcxw8Ouosk9g0^Gf(LHG21I+9h=ool(d&Hj`5;Rw^ky*PO!Q`j zq_a;mtt)ko<|+>630{&PR9gLH8wRtW$7z%D zc-B`|Y2LJ#Toj5}?0d05p%pN{*fRno-+ItuBnrR75EH}JzdA#yJF}5D5<$x zi|a*rR~mq%ydyu{Vn@~0j{r6EfK!7k12P1#RuHh%i{wD_0i^W@GlSn0FWPqfgwLXh>-|~5OBDq9bYQPX8w6E}=cDd7hwRh(zr7Ftf3*yfLy`RdqJ=P+^IEl? zy}pn3YuKxsyP^JtP@3`sAXyfc(zhubD>P$AX7_aRosv}NSiRMBP6vn5|z=<2Jf zQa#mWruWy?8p3SsJ}u**GAhXX5L?u@VU{_KZDPHNkX6Eip+{@d;}(X*m$iQ`a^~vS zxdo`||9m5GPKHu(92zyMnxd$eTkPBY6n-fTnCnU$vz#?hf$N5RK;Qp;BXAvZ^vsPD zVA6>vaP%WXp}i~@!xm=_Cf%c zPDEPbmx$r0WJ^$uZ&mq+g1+6cvWN@+cMQkOOcgJ{UI^19ejl?MjCZo6%V}0}W?ma) zraeI$twS3g%ttQCdBFkfg(zOQ?!8y?1PxqZ!{sq$rROZW(ahXTnbvuyys7nsj1jvvQ^QoZeN^T9RonZ)Gdtcw+@LINf~Xhv%n5okLs8P?a6UoZ5`yQK+sLdAFqMbrEL< zE**nlm;Y|=kQ>$eO&7nCncG|{w1={N4V{U@eCu1x)QdgWn~4Xx{GUGYpzD9<8)Y4j zixiyxmnhA?j!J2y9ZbE_56~Nu*-j0sG`aLVi@cyeRFD@U)v@S|=QaQDW)*o%m!AVA zO<2S4-8*7R=vw!06TMfRDqjk5{9=ZOxYflZLm$dTP_zc9_TiL&%lUH|L= zd(HrYrv9IM63rXQunxrLz`R5l7c~$9HSjx4yP5q* zn3MX4r=x*SOj>f$hc(CZL%08|S(gW6=%b0WuHt~An-SG~+2KwlUZ zUTUnX2fh}kX2)Tk`{W;n6MlG^o3FUceoO}>oYQ~ZA{7+fe}o3 zl_5^z;wqlf629g-(sW{gzA#xbX0nH;pFfta5h0@Gv_?|#<8`4z7{|Ba%S5Q*`7nUK zFdOO_TZhjiTYS#%r|VuPpiYK6e5jd94XxN+MR(sNXK^HL(oYDv zbaOy%Qy;ASaPE|@hi5^GP`F8d(xJ_y);hIiINr6C! zE)8ygzVJ9vZv|0Nv&^VV*|PBN3efK#pJEbV|J_)56?71N5pM?Q3-7PP&mQT+3$r5# z>E*E|??1Q7Ad2?yiuWB_}Y%c z2)&~|za2nd_-VCH>~0*03-7S3HEGvpSwcM~P%0Lg3lw?SxRowh4FLKgAVF{P?QJSl z;Vdrxv$TBei|}VWJomJ7INV>!QD*tM2LOE$d|NbTC_r3R*VW-cS%WPF75ZYKgyX@} zN){Orf{<^<0nisAtPtOCNDh3ICeFfw3L{nLQY$zH3ChNnlUn@tdcF{h<^!n=VIMQ< z0+G6>kVv|#5sh}{$o>p+nW1u%>0QGcxpL0RJb=E42z%A>)_W;sjYazY2@?r%RrLBn z#6y}>LLY@b(L$iB2eiM6p8j~D1)oJu3dL)a)sc(+dHJk|y|HS&U#7W#AnSN`0kpr0 z1YlIngCn2ds0j zqu=-M?C}=-pfqa8l4lU4Lq>v`Ws|0n0wmrTX-`v~ic2JLjRgBa0zACFqZ}8WfV2l8 zFpzz!6Gr)*)+neXYBffL%qaUJClw_$`2orb{5pp}iM)Rw0|Z8@<;`hPAi@Iln@&#$ z8`uer`-M8u9vfj6dX`l~qPtjkfWSyEnxFE*VBLkrlo7it{LUNtt@X$w!OIJ~OYtE? z{)B29ATTna6~x+IY0X_ONvdEHAGP6cx^)5+N57mlCbA0c5Z2%T0wXJiuz&X{^tWzS zr+8y>?#LNbRDUEHwKYtn#?GoXRfr@&VC1kowW(@xK$=2^DJ)g*+*#dimNg|5YIR}0 zWPc^dp$!BGjQmRx#&Z4AFHPt9w!)>J3VoUqa*A@#heH>XiXT#RQbGWMQ7HUWuQj(zn8d;ooi6G&Ld*P#x4kP4!Hw$+ z+X*v^XjEWF;Rgte(!;m%URAaPa-6Mz#R8hpsBdZvKaDrKrOokcHLLPIgaZUdx%3I) z(R=w=NGE8!#!tPL?OQ>eJJy4PGoj_K4#iw^2+#tnGWjCEP_Mo41q<&N`2g<8ugkwS z`FW*VrxN9+Vbphz2 zG&S#u$30OtHO$rXK9TiR1GS^iC-QYYJzGm3m+8u@s*yn3|9;QZ8B$>8FfV?hNq>4s z*A?J53RUz9oZ`r=V>Lso6pmpI1szaBaxaa5j%KqNZRNU1l?xh1WF{{)?0|PsV^lkT zycT=m4ZH( z8Z7Qvv&gP1hCk^V0Rp4bgXLh%YsoPui>gXBZ+4#9~lI+s01Qvam%Ht*iC-PVBR)Q53>*9qm%UkKu%0fEZnz~Fz=qD)S@4TLKvXPwNvjV>KT_w8?a~O@2Fds}5k4a^>N^;ja3_-KlxN2R zM8%3)|LTR*@9#=<W{?QbqZD`G*p6;A*}#isU7em;l1GV>Y#ltuuskS~8zw{lelgh0M*a&eY$&9On6bn?e}wGV=noJTJFVcWGwEvl*gPkS zvMq7D?1l+4A|b1W4?{21aRK7B?!bO6d)hPZOPk8fx+7s(RWvIUJ0+6&pL>Z+x;*Z+ zZ{v6pzk|#nC!>Qg=Zr6Lr0EF1W8>ZDjQ2~gqg9= z7Yx7LJW#;D@3SkC`?Djm%F#Sn`&i3sOn_1t_LfQwZLZ4yOVUh4ujl}T!Dxfskmn0H z6#WY5xp}fukK(~X17R6PVZ3&z>SF4?><-pq0E2NqUW+|e+`=$m=`#RodOsVKfSXq5%fu zbC^lWK~ofU__~+q?ohU&CX@X>9o8R8L-r;~r=n@p4q!08HqTuC=>w|o5?SkfFPri5 z^KQzXH^KGFZ77A(7oxf~!cA$*l>@n*EBTm`(Z1DtKpseesQV?DVN4T(X|R>Zn> z3IKum^5#2nfB7{1ZCo+jqgZGd(sjNn&4F+=EdJ zVE)*;0|X}gh-NQ)r)eQkaj5@sv(RGjEVK<5r-G~7H5Tgme!sF8ATVGKw0`qJe%Oz=+){hiL8u1^%-7#E;vHEq zfvg0>Utd(RsMcDT;Hz{kKQi*2f7*^p5&sJin5db(zdr3$ioU)OCp$Ve?Nt#gOHK5A=MUpz`7DqH>!cx zk}9!xd<};I^}1M2LYqhHFR2%IwQ*YkLj6~5aXNY7gxt&XCJJ1!sxA2Hq|$Ow7I%!5 zRHSgfq$2$ahCo=f=uzN!8PCeaE)|Ny{@zid#EpaQ1J>f@4~diAj#i(JbO)b%A!|Dz z`&APjn~P_u14ifzyv)B;ve`~=Lv>k`WzD0{_C{@%IJyCAI}!^%Ghb1H5w4sm&7b3U zk@3NLs_H$Zh+1~5G_{UU+29Z9$>-Z#rW`k#x+-5Hol*+$(*G}UY#$tgT~WgJe@ zJZ}N^k~}SiAwiCTl9EiPfyX36;r?5om|CI*RpC5Oe4a5>qy%6uDFMf2ecyE?f0FTc zg5BaHvwln4eXaJjzYR$VcH3>t=rXUu?LE>q{Q+6Jc2pId7CPuh zdopXAH^5%fM3skAozf8`i=Xac_Op3;%8XR*lv2CNcS-KmF)VPY0QQpp=0Gu&#GR?T zFTY>ko%D=vTpVdtwr%_{mook<`~_qS(tqqF19Kjxgv!XwD}~5Z!-5XUxXd@(($*+( zvxw^SkM(d!Fu-0ion82ikeWdQ(Sf#C0jsLV*g_(I4#02du+!MdEU>Sh0QQmch4O5F&mdx$I&Ak=xJ_j`BVoSmn-oh!4h z_H%cf2n@+-g4m}0g$j&%t3HV!Gg`<^Jzs*3sNfr%1KXdhNgW%~ZD((;6&@r}ndsK| zz>|whLmmiwf$UX%cyx&u{4v}96OM4!%H9D*obc+#1M98Hab7XO4_!oCfV~tNRHH7W z!n+o}T%Cqu6CQ--B0gGBcV*1qCp-m&Efc~4?4{_if7Z0BfGXqU`yvGq6OuVPJ}d*t zpLD*AodwD5tk_wAy%cAo!v&Sev54c}*ATtYCrAW^Nftq)8AW3fJ!N4@v9JNE$dV|L zH_!Fw+*4Oe?3P7M$lNn9v{n7Q~97dlQa)lkyy^7ccsm<9Q&VwXx!D^eah3@k^xm@ zxqZwozcn5nYjVM`bp!(RiMN~smr$@0DbZQx8*9{3 z_<$<1@~1I@X+P@k0ZoKR`*a)kyXv~n9m!-*9Nu$up#%ym^?)j}Y6HQSQuVbs>a{NN zVdgAFY9d@h`Ve8i%%kes&(dkB8Bj%5yIBk;pdz=SvmM+C*>@$ym9k5gGi>lBvdR+* zHAjGSK@~ui)jYUQ49&GWOl6Q6t{E-P&j(-~wSE&1e@xtSg=%$Ak%Y)1fhw!jFg-t@ z(%Ue4XP(S(a$-}gq$hM?H{T8Q=O+e+RIR2jsNugVtCQr~+R(cYS_G|CiP|@RR)kmS zf6lt|vi`eMyTV0bh6`ER0oki+mL#RCfHxyER5?Dk{eYDI78!Bu8#|hpIGZgtzd_h6 zu(YH8E`&T6Ww7zML}AY@&!#%{vN5h$yBBq8r{OS8{5hc%P(?QI1u8{hg+J7o4LFN6 zl0!``XJet)eNBRv89#eHQl=LLRFRDp+sS0{IlScqriwx}`J$>bqZXDIEw|6oJz~Y} zNBq@*D)PsZqHdMSv==2!9bH#@`_rPL0mY^DfGYB*z)W?yOO>!~UH_cdn30Ys{rM;z%wSMDOczw)mFV3Hpo(l+iJFni zuSgyK{-ghb?aW+WGS!BQNscma&@$OblFI*|RQE}+N`eOi7KLPWXsQyniU|mOtu0{ODSuCja_%e3HkKuAa z5O)9LPC}`9Ys40u>5h>w=<&bQp8DV|xbsIz;nOq?mygtYP!3jH$Nr<|?vMsiRl??c zxeVkn?gD!KS7=?LJnYd}17aR4cKz=Y`H3k~$o1WaV_EV=h>TibqcQA3uyl~=)oyk^ zoV?%1jxZz+W=c5%3vp{0_eWwHYX5X+_~oD$u+oE9c*SosL+`ra zN{d1?>eLt}o0Q_3MbM(mfD0OD1TFwQ5e7Krl~WRh;8DFUqnJyLt~ZBr?U#tVV+zE_ zgK`5+z@qctK8MWV>ye-PCdXKPr78+a8^DjAdrsdUm92Aeu48hdfIy~qa3I{Gp-O-y zE1?N7^}JI_cOIsfRi&J?mL!5q-t?mlFq7QJBm#wVESrNY$+^eF{e2FK(^h$T79IOx zY7{XXM{Q0Hm`U!Zy}d;@3p1lqB-pVh^hJ9kYg(m2>cy;ZEn+2@Wza7IG{X)cBCYT2 z#`&DevR}2BPCakI;MjfYyT7L&pg`4=#8&ABnqdcLFj$7@rQF}N3C=a{Eg)nZTPj4l zqwxHI7zlknAn2O`QOpq9;n9Z2(T7m6cs8)2wqoj+_HzCeOVzF=^07T7#w^=!x;)gK$K7 zbLBxe?_A%KRyio=1(BasDvSDE>!g?YZ&9?DBxW$=uL^k(j-K&wD^T#8c?`%LHPPTx zRj1ucIq{%)2D!egBKJk?tp!1BqW>O*V>t*J+HWl}oxW}N4JsEDi;%e9nwi;%KOjl@ zGZBwoMSxJ4fWQB^l};*MfVafYtyHqi7VXK5jJT&<6g&8VAJz=)6HW?EkmyDmJRvaG z<+5DVQDWLVz$0K?xqqW@`kCHLYR-SMId<1BA_9nRCgTW-ENd;QOouWaV)Ff2Y`M|V;)K`BW~3go8y?jxS_+B< z#oy+-F8r+wuM2%bpK5^`2BMqU$J^Nkr0?H2z}H_8Ofoz;+c~Ijl|w=%uoJ(m3(DgZ z08OxSkKS9?nBxOz4*f<_&8|gZJ4$)TUtH(ejFQ)49;tJXfhO4b*5|fE#Br7CR9yqU zDZ<(mQs(4w=L(SZ4U#@rgykJO&;+|64@Fa3LL!7(RWf1>E;t{jou@DHNVs7}pFIa1 zW)SlNO|Xm1XTyTC=LWD5B8pObMNZp~WV0k&^o^-c@E~aB z>yRcr*VWxSazRdQ3Y<(mqDguLA~h?J)c;_@<*8xf`OxhEiO*Tk#Z+xc779sZ$P?Qi zj6%e_QUBZ;BY@=p{obrJe<)54Q$AL$9XA5VSZ!cU&o??2}C#Rk{T+`PmlJ6T@fZP8RhWi-JxJ%2?}?9{a}W? zkgs8rKyIK;zwVV2r)y&-((# z)e#}`!4tlo9t1Y6ZWqiJiDWfpw^u4Y2nOcy9d$mST-lm`yxdvBD)8v>CI{MJcW_xB zA**Cgl$?Bd39r~`zI$+hzmmF+m)M+DTNcw6CU>r(J1ZX-W#X?W0%$iRF8h|#~ z{a6;*t2FFUL^WT@rZQDynAOZLC2Gxue=n4S+Tj_J^nnQGU|I29uYn+@(WX99bbj9F z!omPHH&$Yf4%0EAfa|=mP9TCg43cK18c1eOpG5IS+0aS(p=Er?mOC7rjcO-59+Vn- z2t+VP&*?u{ytQ5h~H#{bwMi`K?RicugXq*e2Mm&{mzA%M@<&6dyPW6CoeXS|o~tKKwznDD0tA+a;?rR&O)U<)B_7B)LuRvsjXfwa!8 z3_fB8qaP-36v%|JA=$lo3}|Po%y(PEP^OrgIirvPf|&D#il~i+ct4Y1!%i1m;TvBU zVU_Sq+Yyb|d7f9YbZHO}#9UmvbEcAO_&R?rP^I$SA~QaavXm?3xMZ%}I(_4dvbq8U zF_(u4Sz1nw_H%G_qIxi&q~E|4@H)Bn9!zngPwj@%b6f%2Q?GU=@OUk&BV+|ODVUj5 zGJNs(*DUlea6L8%e6Y>-M6-bHsn^Z|WvweH%T=0%Q*Ef4QCsnV|LxCI{*Fa&$6 z;qi>Lm8Q$^nFTY9;hYtl);?VD{PHv!k8mB8$5h%LKrnYw6p5c&MVlVl7q1z%L*`Lb z4ORzds9Qg8Zncxb*%D&`2~l22{bdVDVbwvr$aYA^pPP$MQR&B zFb`U6>>=drW+Z_cJLq|DAlfdyYyzySw!35p>Kz<9EPVh3^T?z(h#7e*IZ+wdL<{Yc zdN$jPdb#s8kv{Grfh2_@b`n4^Ph6=tJ;Thtjj*5Q@4ciY(_62rWhp+V>zvV*_?E5L zUVz)FfAQ8cOx8s?@zqo@Ge7ORM!?6E`=NyVGEc9eV;Ep39*B+{MAHR-yjPrWG zEMYjK!88^7Wq}ZxA+*3BIU(gnM#VI~&EDId-VA&1$XR~f-Kuneiy#}G8m$wEIlKhd zQ^EeYdXs?W-3jSEqDS`lu+~E+(-5)V2ZyG<3WvRBYs7$2pq>g%HO-Cada@E0Ks&E| zu}Lyk`HSJBW$m{-++cLbfV1ETpq>g7`7P#Y@yLN~MyNWx#PC+YYjX*wzN?9tMI@Bg z7H6a$z%Z~=P%0#!O61#3xcy-GX6ovsTF6!VQaP30OjF5(S+}?X7zU0*P_sclwR2Yh z;n1#$geigSs(!K?vx&&yr|ZsgLTVg{}94Y`91_3`@HdGvzXjcR0xM@!g(z<}Gy9tvx|)BgiG>w=`mwIo=_LaGhQy~@1|(1@71D?8}y zZ$pD66F+Vfn z&$b~WBL}?g{Lm7Rse)RRRo(Fxsxwt#MT{HyjV3Szi-o}2I&P(vubL3T^T-Za1u2R_ z@lF+?7hH_s?)66a#14QMY+g+xW@4{r`$4(QAvr)U*Zx!vKiE z;XQt$>zJho%*e^*33ekV&v<`yMdc%ssQ2(F`hZZU27nmc>!pD{p_jZD^7t~pJ135B z{J-a}hCMp2)ornn?~alU0T6>XmRHXh7a@fG^*fBxVbg~1pS~7BlKNm?O^J;S6(oV3JI& z!Z^-~WppvS7eI;3{|!D6b^TOBbdMEH^AOW6>L2P5w4l|5ZXBu;%WA~)_TUdX0V5f3 zXSD@yCB5^bcweK@a%4QApGOfRMDwt3+q%RDk^`#Tyk7v4A+f#Bg|;GSak*;nffS6v zxtsZF^5yY|IdNO3?wNJF7$JaUNS98@j`Dx=Di7;<;Fb2@i$M>tiz@wTncq){uPSmY zSptv@89l4jdHJQ@S1Mu3L7i&FbLg766pBgWmqvLOo!_7~g6#lqAHYcYO<{$gg$pZo2OM0u)rK7$7ce_Mlw8 zxu&90mvg~|oFAtVw}`7IknKj69q8Zh05FF7uHO8;Uu}0qbt{n^)aVV1?m@^1<@|IR zD`vLT;zA)YXz>3z5&o|xVTl^#@&EWl2u;Hvl|--Uy^@@iGv2-q3*Qn&Vp}PLCKQ;M zV$}q@z>NhOW&U>}q&-G#bK5r(Z3z+9LFF5t(Q5=LPY`#R14{cw$|$M_hQIWutaZJ%Qy^mPIA|XHCIa3s^hRH3*}v{W#|6Re zFWl^Zn{WJG_OiD2mfYow{BakpM+0b?88{I#w2IXaoMEwfjX2iz*(5*yNYq5652WO4 z`;2&E6C>K10EReP5savu5=;En#1qH^Db?ZXI~GsMs1O0m>~|XWAy!cAvnv3^VLDwa zzs*Y?M&~T7kPoW9XeHD-QQ$Q<>gpQPmp2icNe3Vf^P6wdw#@Vmp=qi1i!D?n^PkEJ zedlOrC=r_b8akrpmH~*vvJl-9^B{Xwv?@tME{&b}b%*QolTetbD{+AS&o^EW-vEfi znk+uxqb@2RZ_m31fv~^jKHG`YsMfPvl;!x$b8Q!72S6OQsx-9X_S;_9u^1TD#9CH- zi7OZ59>Otb{`IMMwM-xkpt;KKqY<#7Rz%`Gxo^Ieo$3Gl-FGlbXBj`HCXek6gG+G` z&|Kw+I~*(ebZPlURn?rZvR=r@jGumHtsY)6aJEq@NokeG}t}Z`*q6sI^CKK)C<5Q@ngTqeoL1B5{~m zGk2G3WUn`AZ)hIfE9=fUpL+ z)4|mDtfb{;9^in7Rs=tP3HM})XP17Vwan))QU|=SevW=6yC^V_`D8pdpip6~(kx-`%%dMToV_o{6!y$v8vuHtry6yibbl9m&)dkJ{cF@ zdM##)OgC0OPQkqYZ4Qqq{WefLrV&VYi2Ic%Ad8oG%Qc19J4K90Ys>`>Bnzbrqn`Kn zU}=YlmI3JwiD2oaU(OK*PO48Z<^%&Ckw0Nj|)Y-x(?vKF)R)(t~$Z#ZWl8FvKN#G;gyw}F6%yl9Us;hnUT zLeSkOzEZ|#S&tRHnCN1Wmy6MqYa0ZZWAI{1W_@k0#ABdSK@houV@sOl1Nop+n}uhCfrzS#fZ?ZPZ~vSxw6HqNFq>a^u1UNDklXZxgm&AOLJgWRfQYJU z=K;u={cIWKj9PUpzwu)-S&lhd{mPAAM-p0DnFKv1knT{!$}}=;#crICdF$*eB1zb= z-JcBwTY$U2U}(i5`tzMOknT{I3JvO>D1Y~(!$+vDzH|k14p(=*#m;mV>oW6uWSi`7 zAl;#{sui??Bj^7XgGbLfqX=p3Ayhb?Iuv_(=)LmYZ-|R8K)U0@T?h5*Pc~eqFblcx zMZOG^!QHqc&n6t*)Sl0DLIh{K;DqYm4V0#*xHa9WK_IW!Yk`NRHRdm=Zt!irW81Y% z+oxg;2SaX9+rL$&g>%WykG*(8@!K}xU4oJ9nqb{GZWeW2dkYAk0kv0JH&FNARrXQt zQ8RghfgAo|(#v3BMB#oKglaGQsj`~9XLve&C^7~d@BpV)7hyh<69?Z>xC-&X+BOW2 zoOEm>G)&VhpAgMFqrmMc009pj7itro&NqDf^W^e+3p;BEFE})Dw67gZq;$`k}weC+H4aZEA_9V;9_K(^^ z&ZQnJa5CNH1C)`*le3QTGxgVr1$-wbcKOuQJ}N~`7dH^!QEOvn|8yMK0m?`dR(Bgm z*N?|2al6>o^*^uj*OK7+^};3UnMG5=rAOBU0A-{p@~7$gl(xG%Gl93C+=G*L4Ax_` zKCElX*jB~Dp~>1`0Ln_9Dy zoIfb*E6g2N<;~wZ$p}EvFp>C;5rqtb|F_UA*%=O+Zi3j^YNzoL!ZKz#2?Pe9A8M`a z3$%lTbdTedK*+5BF0xuplnEDl7tmSu^{m<+ODISDlJ?@&*)mtmE^y~IE?UI`p|gT7 zvRWsi6ft0Lm%Q5&hDl}6@9Y`ZbH000JM>|B~-fQIy_;%r(eawZY=Cp|F|4DeI!{mmi-g; z&2$FipElAitHU40)E|1C5UrqA1;i1BX2oW*=wxSKXTy(8R;kDYXd~@wno>|d?aIbu z8K8HL6px|HWp=k(UGQRFGyfvO?q)&(w2=-w#T}zVi;i--K{tqtKYv^(&zL=#3`ACQ zKy@CYCQ+DJ#lHkL$phs%bzQ=|b2esTAePoYA2+O3QzZ@QNqC{oW^>=f%?l-Vu!&JsK!?xJG|< z=n^vgn%|`NQ+@K#y9X^I&ae`-YecJ=j{CD!ViHj9aEtkBhOT|Zz_$W}`9XdWJC{|| z_c@_@%)m}6Y_v(AE)ghqxUcqE@%^%909}ym22)Xc>Ocz`&$6aLj2TF)M&-=w#(*2D ze;;Wc#WA8k{5ijg*{W$OTAAA>4uz~^wYx#G&9B?KKu_@T+g-Mi$uI?~Em8G?|w} z^`MqFFSr+?n!plBaBH;{9@R-TcG)lKBpuW39#yoLpJeZN2G=duGRxCJ&b17XK>8S1 zZNJbX(}nSrg_T4sP3DDbX8eLHN9Zw5sr4d$lT`{xAbs^#w#KRWY^9ce2;dqiAq_4@ zmBC@-tc;@bHrTVrz+(dvNWVA1I=G`&IIsMUQD-e=ku@gC+Oh-?5|piFBkvT-zLWqG z$WO}yh;2)3>JPrYf4Wx3Sxj(^|M0l=8)=0fSdGaCe>erMF8bSjKoFm@))O$6)Pkqo zBkuKk`;jaRL6LARBsuA5Jwp(!SDLB=BjJpmU zT)1b54p2>i*|g}s-8%T47Pbu1<^-P#L+27k{4aUGurFV5B=FI%0(m>9T5GpfeM>s$$hWq2!$c#o7#O9A5FJ^Jl9;N)d1kNFA7*F& zI*D%r!>B@)MzgTuQcdHs2N0adV)=6MU3XAzzr|)HTW(JES()N4?S3vLz3Si@3b8-54YEb0ZR_JVxz1vUMYp2>1Sh&imA0<(?fS^}byEX> zs}VcWav4%Qrs9QZs6Vec?29=-aAKZEDHKaB4QbCG17lneMo0fJc?2b*DS8D5L9?Rs zs1E@IC$`?p+~NLBQ>cmC0|=d%SJDygWmG$4ZeU0&QdhaS>nkuy6BqvxXZ{zKE+>ED zu;tF$?TLZcI*!|X^M}pc*~wk-r|Nayoyz%ZQ1ZKjL9|m zW`zuWoe3DFN!XSBFrgFWaBaSG!S?a3VU63mHd0w zq_B*K^z;TN-q#6KsI+sO)!ig-L2B?*Qv9Gg`dMKI{S2z)1b-z=`ammC6{{Qv^n7vi1$H*V<3FcUvyxsy1Sq8R!-Ym8QmTWW>5ZWzRJ#YXGA(*=p1R zgCUT=6oh*?rdr`TN7~nZqlCAx@5pls%|DF#`2nLeIR@quw-eGT>H}DtuDAtJD#N*~ ztd?AAO5TFVQq=B5CBP_6E<`5Mx5ra|NvuL5quAEs__j~I`%TjO+&td$_^^ZIr@$yp z-atPZ>*NPcHgf$pDKk4lh^j;=vVyLy#~h89(8S(aM8GIbzJuSwq&>f-49`~AI#E_; zn@5F|gE7XTI}}9i&D7DtJV0RzP-IL!zc)BH!S6F%3=$jle7oD>m8b>OJ+fpCQZ;;}Dk_Kw*l09Y*d(=az1V9ZGnS zG%8B9FXd3OuiWykiJt_B5uJVjUHttT-JTFpJQ}tx>5Pg_nSp%^Kc<8TLmzb_FxkF( z{p-+>dV#wB40QW%oqZPY+p`iM+Ta_}bOCYQlJv0HBpnx2gsA|j%WP1%XhrC=JPl~DSTm2ZkYIg+;G{qutU z%l_|jb*S66Uro=!6q`gp+0?o~U@P7~xkniR1ZIotsH>QrMVk>jmz>o!;rKCxO5kDK zYDR7_R4@(*feU!{mABehUCH5Zed}oVB*eq|OwiFqOK7X7e%T{c`2szamI%<83M>m* zMVZkq_aX3oxT+w~9Lct#ZM@}HbKXHzP5Z0~7YGBqsjp-)$>MBskykxyUU+NIisb&x zf9Y65P@ezzW&}!_SSSUks8%iWDv0^yGvj!bNcixG9$(8IBK4`ufcSI=hU8CUND6_9 zYV}Ly1{;=0RYetZ?+QwegB5;BBX7pu%j7YQ0_AaGY7$UUt;wEdS%aGIKPq3rjf^fe z7@uj;$}xJ|O4hh^yb1k|z5#$RwGA+(%(}}U)_QRQ(dHHUMG1IA)ecvNm9$sA$^R&Tqj#aB*A>7ue<7`Y3A8>)YIP>no0p=56s zZ#zZ0KH~bZ+2%Q1{`b8Bl+d@6P2$JIhUs`QOMy0I(!yP*KWvJ$k3^5P*LqbF4oZ>`i4R) zAu?q;!@6EQud(3DBSp zMA8vT9XNxS8TvM|c?7;gHHM(%Y?&@Nu0h_lgFLvvA1lmeBYMUld3QR{@ik`4O{r_c z9t1u2#lNRWW+9t=cDUQWG!g?qOz&XP>02DFBF8n$84$av?>jEHVU}Jbvh_x<&jw2OY{`0E0zmxojz%;{t6gc)M z<2s5?HE>7u?@Aja>%F_dwF(O-_yeJi0Bgm9+o)IgC$7s`L+@9;+I7SMDD~e;8!GkR zb5gtzE>_qrE6W`HBA#1i4n0@S=xqd(r~o4hj*Mn;kqLnJR$t$<`p^n;Fo;MM#+>86 zt0e(ljeilA^kVwyU?w>K@el$GWWdGMYt-zYNQ&e0xX;~9OU$G}SY9xev{Ln&@*)^( z&iD#*0FW6;CB7`}&HY71Vawq*)SHOZQI>x0q%L$03;D_SgtvQy`{EGV$mIfDHI@;B?KE$>lMt98ctvhJjYSo@1Ee>PtmD z(p^+lBjFm*QXN+^JsF8;rC%}4@_omNVUnB`bw3lQl0!NJhyiTEk>uIZi{HKL`ltFS33`C zI}(}=nC~~=3>5@gs#Bh5ZtZAtL(InexB1AcBfR3-iqmsio7kvy@iF5$POxxp= z!<*H%&z%SCVZB+Z#mL_wNvwmLE7w|Vb_&KhEdWr=jFcL@c=yg>#R4-c`+SfSAr@aw zQDVpoqrCnf5q4`4DgedIzD$$zy@m&gPOZjche|>D^fXB#2(O5CdawN)exK~r0-%^V z8W(DtC5dw>8u@)cFT&capt7O!&LF>5yxYF%+AZNE0L9GTZ+{|qhuIU2S+iTzEL89T zA&JlHL;awz5(&zM63)C8xTN}boh=}Lf34R*V}58FTP$*jCUsStX0}?i{fd-+EZ5uZ zTi^xS`?t;(F|$tmKmyJ#n}j(!U$xf{wVr@6T_${N4BB zcm6$wC{os`ZG3s)02#N%>yWqi*&uz!51tt?kO3E0SNa+9L}Kk{Oe~K5;k{2w+Z#lz zZBltSmdR_s+1B9i0zhUN^O=4iat@(RL2ZenKA@#Fr{Y*&(ZmK}uk!cm7`n4O0A#)s z+CL(`?W@!LA@P3Af<{3ZMqX=WUTThzc+T?BTDqki05U6w>nLw>y0&8bSt_gZFQA9yAh$>AWU~jz2!tQao^24rS*fi^j^w^dHi+O zW}XQMo*Q^$|1hjri5O_OCsQL^nzfFd&QXg*IM{u_u@QS+{)4x1WdpQS*9hQ|(3yJK z|2TRd`vqgj74EgE5992MzO3m{dVE%Cw$hiNV z3O9#l2SWa)$vQFanwWzf)BIy%cGRxL#S`~OZfqud^FY+x;8WoiaV~A}^Jq)Kl`|i9 z_h_Sft{P5KVaun1qYoPD-2FQ{AO`U78TeMX{in8{H$O)bSH|V@o*5dgOSyUTkul{b zK^-TL_c@-lDInH=zvrDI_K`m0TFPV#wf~1!Gs#cXov-FH0p$~ga}<3`B?Y(hLi?ikgtxfq(DN`2z;F(8b1Q!_Hh>wlL#rcd zuw*VKV@%t(`V}#6jLXQ7yR}1r;rzmyZLuSl8{SFLU5Pxn)+WnqiWV3&yY0PxH>>F| zQoRAxSC6K9a#bJI7I$mKTt@1p(X7#tS(Ap4w^XMPs)(Hip}_554* z?wL6Cv|?v~gvY5SiIos73l}(T*b3-}*m~46l6jZl@0g+5Y zPv0PNo_!53a#~e(bacWv&E{`4+0rM!8FDEB3aUG7<|qU<^)q|8=1!texv8QSM? z83jZ&iKY9qo|n;pg6e+G0-LLQc|JsP23yy_85@zY3X)s-?RA3AwpnCYA zkZN{O7X1Zo%kf=4^Qyc^+#vY<=d^dbq0qqYSUv<4SRZ4%@mzHKVbX=M(Mc%@I1PLZ z&#T9zA4C?G-TLGMs;+l69rpVkNU9@XS|*!LY|4vP{>B=@J4-eKec>h9`tE2%)n zOLFiEWz^dp$0M@e>5WI>JJG%$xyO&PN&ZE@9Jg~II!%S(=XZ6xoRsv zSpyl5mk&hMie08B#(WH_$a6A1mk+`e-;orA{j$~y7eD716@a>cmG&CHC;jY~UQD0b zPVl;J8sOM;|AI8hMNyP-z!dVcUg{gDAN*be&(6Vsyj}QqsvYUM-Dx%$Aq-#M zbgRvK(J2J#oOqvbK*Rsd&P}h{38N`hoS?{Ycm@-xPAXn`ic)={mG~60clAyz#1=Hc zt#TUy$sR?JGQpxlB{Ud}=TF;8#c*)HUC21Fohd=`jl?bd7A%zlPtJXuW-JKxn3utd zlNooTC^8S};Xtd>{k(<7d}hp-Fo^(2rJ&1RztErJG4QH7Buup@!OWS<=IUo;Dt>Q_ z{9`lQ(QpGurC?-QQ{M$QmXXyAii*=r_Ynn=;)67P_HP7vyCu}v4yglDDcE0UqW3Wf zXHe)KccSyt{ii>K1)9D4$k%56r8{Lh_6%-{Wr8I6zy-KJ9L?O6eMMf zEADuOrF z^m6q?F4E1P_?G}SM?%E-`29%MK+Az?_)(vE)pnq%ifGCs`^IlU^O?rJ1b*_1E>)_Z z35VS$oCyI};lp96b4DQLfs|w{)pt_yB3Rt5E|6`bIdhzgo25{ zkZv!Pqg)FsTO)JP7ccFBG>lN{6CgMq;4P1GXZye$8UR}3K;y?#3-_3Z+aBFD>3kNs8;Dxk>bi59KVLz~;NN?uRoF_P^o2w;YQfLT{#b zh>7%*FOMlQ%9LRpHeQ7hY*as2tfQS3gArM=9K1T05G>8e+Wqht}XHo3? z;0}Ln5n)nZ{1g7A9_*FUioh^Ke3*4S|K{vb&1*ti(hQUky%g=>yK#h>2vfPNEG z>lWoF9oV;{-8Qm6{~*=wSl)-cX$2dnj0FiU;I)434V)eT|YVMz@aqnov~dpxS_>I;gx~ zKR~n+1Whtm2FfEefdah4tfxS}T`0DaAqDXx` z1fda+ZT8K_m?S-pCw3~6iL|iQ)#{iyX-vQ?Me*5lIhq~<5povdZC~7++k&=Kq*Cbt z_Q%x#+B8%nWOTqQMag)xa;V3ZL$of8Ru0u2pRdbQM7C0Sbo1hbGwgp*E)RI6sP23g z+!nz|kU?{`OUX8}0tIAR4DN%EU1Kg0DmLAA170cWcLLHyoJ2kX5Clb4p}GYv2&sG=UM%YPxV_ zc!B$h5!Ca=ThYklSI6WdkX5D6Wu?gJms+XwvandRymT*SnZ7@t1^xD*HlAjE%v8w$ zdL9f+ds;9WbBvVjo4%r2Sx|DOAR~v7xxzFGo0lHF5jq{9=fUVmuF~}NgZxDxU*Bd1 zT~VMoqGqudD_Nm3Vh(o0pq_=}heN>C)7zm)IZ^0qNG=0+o`b z^??$wNil!0B9<)jVMig`Zwi-=BCm{k{#gU>!jt*?4t2ZZ9o0{8RQ2yFV_7%k=Mf&3 zARbOqqHXfCi-CJeI!|RI=FI*S=II)-;SQ?*x5`*kWk90^PW`j%9$I(1pNU(}-=&8K zTl0Fhmj!vpi040oT6n-mL$)LgAJ@6CFPjUf0b$*a*U&v)n_H{Pzcj@O?amq!iaYZO(>P z|Mw-%fK!Ugdy{M{wdPVfB34*F=qtAE{Wa=4)7O|wByKGiBk>QP0jCr<*3XA-iu{9q z;R5wQEg>v_5_#&=ijR+)zpV8 z=}Pw@;oZ(9bq|&Hpu_)lB>V^uR%nBdg#Xt&+T0o;`9D4s!U({{2^{O~3nnBQILB$~ z;qbBa_OG}eF??AKi$-P1hkXW}^87mz3ev6P_cgl53*nkF5#%e{FSX~#6~S(b>9}Ql zkuvZsf(KpkfRBVi{Uu*COC|U^YD<)i7CCC;HRUVNNSL?qAX-v={q3(|LH9iW9SMbf zEXfsy5{i{A@7&wS!ZcK9>->syj!)JM?5+@RnqiMYzrio%0uWeiB$9|qeG|-|X78}9 zUM_S@yRJMT&04p1FyaR}EuHr@gCI zNj4ly4I^@uaH~~mTJRyTcs@&ebmxPi4mjK@9VBjPMomZBcLBrNczenboD(z`Z!uOm z=)kpd==5CyfI5=mg>(4Pb5f=;*8LtXR?Jm4E_ts;E`gR2L-FO|PBrJie2o-MvDRoT z`Wy<1LK3?s_=BA;>Zt1&IJ5hFmi-;Kds_&YuaOSn$s{RRjXz%-T_0+tXk0ZRCa>kX z382&d^rwH2y4(?%uaOzfSEp_m|1y!UH38aYH9)pV)vF+(E*IGLLrbED4de&rYh=&T zynh@KrX+UqQ=J+i2M5=tSH71=u3n0OLF-I)d!Pewj$Bn}*98h=vxQnw&EprD+N8&4 z+r!9TT|a6|>dT>i5#E3vf#=TqPbj1hP~Acrv$elT_$&-*F1j5~yN-29SrWEM-?FqN zfL{JRcjSq&ii_!I3{q#i?uj6wRXN7AOyy;*N((~NQ7-O4Ckwq|b!Y25vP34s@N6^~ z>S#qM+xrQ|)D@7&$e7=?j&D~r_GuY7;P>6bcM$TmTx7+p0Z>P!s{>=|%`TrP zDv<}W{K8vm)(#8{;%t-fx#lxPV8BLIb?Cipe)EiL_v9{{0isM(eze0G945pjccsO{ zv9=d8&}CIS<@j=wbF+MVap$Sa+QsOB()3y~^~*x%MzE3dEWD}>7_d>V3+r~}3LfCa zltrJuT1BvUg>_!!+R`#~7@a*Mr*VJ*25dBVB)OYjM6+IgA}|eu$A+I4HF1%@ur^T) zD@YObU5UE`12!MxJ0QNPSTC6d<$0D*v^Wql?#q_@mZc1wYSz5_#Dua24A^MKvb1(_ zDzA!=Cl=Nqn^q};HZaJaM4xbpkHn(2_`eMSa7GKBhqAr~|Csp0kskx5(3hn_IOlXu ztS^gwSSCmfG|YqmocS0nEUmp8x&G@1*?y(vYr*mfoP17AIbS&vsyZfQn6M%MXSAh@ z-b_LD5k>^;4j=_0!9(38$CAe(*TAy!CH-c-z;Fb~0;^321HWh2(*}B$Y;l%O={Ba6PNG$xOE;s=$x!NSS%1H|OzCPucz9r?6U-*e zHUp^%fGNVWaoJfQ?CUcUs3WhS=)Y4=yk59XB8{HcPkGVurZyH zr>7)_eUe8XVKJ@!5li2@kN+niD1c$4!LBBZ@`M-|urW)q`CRk@dbbZjMiKZLg34Pl zonY19F2eI$Wu<3S@T)%nX3Sd~k{^1AxRPxo2+)KIXkAB>1wJuM5JwTKO)4pj`EZurWf--?sW+6nhZE}o8A zW)uAvE1pSDO@A(wGtpc}Gc1>610UE94%k3!@1^W21F<%ThP>_PBWhqDF^M@~<<2$=r=tSnEzds%yq}c^;~8*^ zHJ5FJQj;{7*gyTq?Web6{Q34cPWK}hljg31WP1!@e9eq*SS6hq741n`XGxx9HRE>ELND`Z0NJ0iR{u}^R*)eYmc$KNsG4pJ*v z06gRLj5>hBp)Jh0{VS5*evt|bODtknPw5XY;U4%hcNZ8?I?IG)2ixUGef4mv zyr0M2-uB;f^hp3W8wnHE9SI&=Ol(X8*A4m)@sR7fs+njMv+hu_< zvJT5A+A&vr%}R4A3Vnnyu>qeJqTSf_Dq#9{XP>0*w6({DJK)`5;Y`GT$=I#0MtyS} zckHvIp`00$0YDiKf9JbJ%dJoo)4YA5i@PyBF=2n!G@i}uRB)@IQwf#}fHI!e@t6qe zuEcebs55QXPBSMq`kRnGyZ7~-V*>qy@i^rGl=0&C{?m!IX!sluUG|D`*fuFRkg91D zn+)eUa2!T1%7O?$8E>=Acg8$g#wnEpqt?Fs>6lGh*E0GVVv&8N#m>gUay{V2>far^ zPc^xUg1)HQ`w5Gfqzz1FmzF{QvFQkRSE%MwZiuwnL9pu^SY^Hxpc@pF=*t4^v9ztJ z>#FwJ0XBn)gq(vcOYWxo_tnXu>%XhaFGYTR$E?2Tfge*28ZNS%SmO_<{8)c^3|iOA zKu3)r6O3lSE!I%okak#|_a5YYduej<3ncDmmZ?5Nwpe@gOlLmtS9<_7|I8^B{C;LY5coMFjX3OSusez6|bo+i|I>xpE_51>PhJ`{VK06ZqL?Oi>n)Y#Xz1N){nt(>82Jarp+RR6vi%?_khl=IhY~w~AX{s?M@AgQ zzpz-}{?2$K{9FFEBk!%>?wj?S>mM6nDg$n@o==c+*Cb9NutPA6nWJDp>#L+=x)_8E zC5WNdx#X$(15_p+SzP$3^aa0#6L&!IIGn22LZlPaW{RoXz`wQJDep}WP??0cd6Bxd zq9euvWjD?jz7iypkF^(;$IuVWZ>}$fF!2NdDw9|cD)oxOJFkJ)-q55|6UsEGE`i3N z!|^^V&to*B6rKt2d?#6Tk^Z*%_5`_e#T~)Y|I*y8)E6w9zH3Z8z>pY4<0t}nzLQ$)KFd}{(*z)B;Pv|QmYDaN>GNuPS-zm+5`mw8u8wx@i1ASwMq`uoc zp{I1i%*C-DgmL{IUPOTBJ5_z>r9~I%0;G$Q-i8{#v~-1UQJqe~){=a8Uxd0O#0>D5 zv<6fdzA^|arxD{5*m5swgKCLkAGP7A+v|u|MaZ7r!x9)>k); z&X*rAjvsa91BHN}48SMDEXQ1|9R;~CoaZc(gxAq!#?L%bC0Eo?^?sM<2vf-5Iors8 zPljyeBr0(q&5d38H!-jqp#>b7IKHNZJL;*8-xKnXug+A!97ii6hhG$;)k^4j>jgS8 zP14zf`=NqIw2;cm?zdUdQdfDzM}XtxTH!78ph>1FE z3R{$gvrPctIE9pU%o%LtP9f?w_zH$v;i=A!Pp2Or=XrB>9B$OzhgJY9cv0$@`1AV5 zkq3f%Ta>*0lcbj7u5c;V_>?OQ9x_6#7Y4uzUYs>85hsp9N?JcnRp;T2bdK78f%iiW zvv@W*=SGbXF%+7zm(qV&Q_tUcdt!y2Yz+082)aUl!z#V_=TeF$LWH7(ii4Rm`8LSF+V(fk9e$Be8} zr+%CI2f7%AUoN~A$)K;mQ>LtmYy*IK`$NvSWcDpj>V1L=MN`dy)FWaIQ$*@^!T+j3^zNgLQKa8nurPj%c*WFLlI0| zw89u0C%>^y?OKT^PTro^U&%K<5yEGT`DP2SoEmw7!?E7zi`_P=sgO>!o+M<2fkp&t z%Ev@{WgH$fuUtS!RSUwy!9Syep{~r*VsByRrj^H1-_9eWX1}f>KC|dBS1&>g@SRlX9f==h%>z9J3jjT_I?4Q z5u%lsXW~6abLx1{4qyhaM|FQUuBAe4g@lW9QuF0oGmi5uu?+s(nV=E)xE$yQF~AJo z5cQE-{z6(d>T(5w z>lSYzrM=~nMnX2Smhe+Fn8z0<&Rv3Fg@HGG6Y3sh(wYS;Ji)`#wOV*OGi zkisW9xE0&I^O(q#xLCF?l~=-14h{K$BWq(f zh(!49ZbbVjJfxD?x13s1guOdwrb)LXVuYFnc~c6NggGwO{*WB7WJ)WdLo?91E1W+H9@=z_d43JE9o|K~}q*P&Jl@4ns#J}%T5)BU@nVEBZ zi_NlZR4>f}1xTj4z7BDw5YO@RfA}2qvIO|osvo3j+LsFe$yA?x zh^Nz5(>ScaO^tqseWRwNSD|N-ft9U>c#B{>^jZ<%1@EuKjGE13{*m9xXuY1sbmi!Aj_Y8}BhcGX(Ex3Re zeDEn?;Y2EyqL=D0OaIkVla^%qB_PTY;yRqXl7%*oNFVTm51k;m&7cx>^6q&jbVr`p4k2?KsDAxI-X3A?*Z zgaUG@;bv?&S{+S3%+V??q~Bk1n&v=R1!+qzNS3jP6?%@bkl@bh-`&&5NFoWV;=4kK zG^IkLY+0q_n{&NI8XN^pNdH#`)`gHYuo)cKtB;NzLE&0Z>MZ|son4!Z)ViT0c+soYm$`p+m2^NtW?p4lgj&B2N( zaF2EF!(0eeRetzY0<4Z-AJZ@KF>`1c}<81z-;`!NO*52gDB)&^W4jo8K0M85f4z1H{y1 zlgL=}NDm7-qW=E+w$$zDKx&C+4hOGpaY(1%9G(v$qot)3qx;ic#}@5ER+PUiP~diO9?j>a4T z<$LBFQLEY2nJ{+HN~6;}EaUXp*}*-Xn6R@-TCmxxQ_2cZzGr7Hp=dUoHcb?>UK~z^l9su?5NHMR~8!QJ<#2HQ}Jk$7It~`*?S} z>c0ZY_q?dg^_Po8r@iHJ1nksaVUNjRSDT%T%=)vi@2t5P)z<(nwLqo+LOPI4WVF8? zz>#-r(Y)>cOYFkV!PjbUxr%wmsvN+j7Tb@Ryh+U>@Fm@(ME=g<=-zf4b*EUV)fnI7{#j)!#W)BC{t;uQ(3`^jBC_|; zVs!l5lLUIDe($V`wNfLR!Ne4J8moQCXk|Oeml7f7sIb!tOVo*GG1THT3pfG^TDz;# z{S1JZTJy&4!SkU@T$D}eHxnV{60L3iDH-!D#8&YsENZ>cTmvAceod!r40*c-vkNhX zl79KBtNaWv!zUZ~32S|)7(-Svvkf4o)(wkP^+ksem%mecWo{J53OA9MVTUxZNsu*L zjR)b;!UDw9hKl&8K)k8aCcjhnqxrzLZUY*Xx+!t*2P0}V{n0DfPJo!&oR#S=*h5mu z)xNtWFfKa1JN}!%VTvV;e&Bm?v$Rdq01#7KAo%PHLH+mw*EX;9@=gShq?7Qj$PXeG zTrw5dxh7#0K>6NIpuIDNM|NhCd(Z1sXX^xM_}hFh%d?Cj{2LQpEuOgxpnUHfdr+{5 zx|4bfG7jl@?1`NGaGr=~SEn<}xM&ifPo~2Jl<(aT6`rI49p9F9<iiD|I;z?eBE0=W3yi`uEm?d?aM2tS}9qK4*9mAky^!xYS-1R@J`STYZ?LMp3?tg3>k_wI3oJ{~ zM;xh$!w|}FP=cVOho}rbX4>9N-1t`zND`MMAuXdQBDn&x)Uk0=@qCpOYRaz~f!k;g zb|fbRJYGMD(AZEhr;CY<6l6e_Iyo0bm;RU^b07To3k>{hI{X8=%^v~7hr?;(WKUkv zkN`lIIvxC2F3x?jlW6!#X7G^aBj~{mOM2my(tALX;DotPMF7ZBXYi-YLdsQ_9GhDv zX($jMADbs5TkvelHh%6gpUuO*`~YOBbN4c?_#U|oj{Ad3tJOU$NT?L53Vz2q@%h!Y zj?wwK4}dIn!NHg=KGm-=X743ED{}At8FS~F9^SJ;wZT-|lB)CQ43MQR%gP&Rnbr(8 zHV31UoQ-1cm`Q%xUC6K^!wsLkl-iDl0l@d4D}M8*BOEd$kr!lQ*O+(8-j?ev+yRH5 zSI>RM9!4@>0O0%T#7j6=(m)|;23~ZKg5niCX*4j-RMTWxA^RZ4a{|!SPv}^9ic9XH#uC6Jv3b?<44Y4{TN7~rNecaY8N7ihrAve; z##%tqo6axM?fW5CCH3S{ar*AgD^0|Izi-dbf{D(E}(-;u`qcbKeJYaGA6 zaa7GmZf)jX^ED=W6M&S3{<{qR<)YPd{~C(uAjokl*>+>eZfD+Vmir8U0Qb!es>z2? z3#0*FnBdO$yOJ4|r5e+Q%5ONs@bO+^OJY0TS4N!bUvO66Qaeb{d%zNvcEtTArZku7 zw0P%IjIZIjx*Fa_(Cr%OU7DLO*31K&q0PS%)dSy@ERo)y-bXUehoBX#PZnPxkFeqj zM?kxs&a9ak;%$IL^(e~yCLv-lw*pDz4@Y78@kpyj>ApfwE z_=@XkjVY>ZXL%dUF!31o>_S?xoC{e@8Y|^sTh1Bd)&#s`eCtZ?`N%Qbt)P zmyF<|lf0RnvCtJ(&||f(a5z1aMFY|jgJJt;1A~st6Ti4l@lg_2Z(t_2{&x6NN!

=YAwi@8fekl3&Qn=~tL)?)@L7>p@rANJQ1J9|xY&oW-MUsNL+*+g%0h(3%62Xag1rV`E)BkL>fv~JM> zSqY4efmF7P_SVU&#JaUW%9wER;Z^q+N>ulrD{vlv2zHB}?NM$3AROkBh(ca<%A+FD z=;Z5b<0B1H+)t>@IGdP8vof;cY>kAB4ECt$dtH;S16oD|KsP|e(u6{!Z2j%Yp$yh zKpodVN$Ek?`3XGY#OTi0&{Dy#SZHf6zh9Lcn>;cROLetsIp$pc3H!&f9Pg|tF?%B* zMyTk3VpN03IvO9AR>D%3NV__ddi#=$T;BFx5?!G$i$8JBp4QQWC$gB8z(K$NEsChF z{~k-|dtougJ__u_Ycpp#`_`sO^DW72z5mYwP~vBCL9i%qhrBD`uvg;jX`B{4yD<8N zL%^5Wq{?J6RQ~yY-1+10qrjM`1Kfyc{ri2#%1$5sOr>)IQwZ03pg?AM)bM{kFU1~w z3Hoj)a~l}B!Y#uEV;1-yxcA@jpFUmId3K!3om{kIW0h6X%~Tq*zw{@Ha3TWO2*QKF zate_Ht_)Aw4$bv`?huQq#qm79MqT&Wt}vRMCc8lHK+qJJ65#B?1pxFAJEYM;LH1m= z`tbyoc>lRe2ir&XyvfJ!f&NF2 zJ0OD*b7-*c!pm~9k<`(gYyW%wZr%4f(Z*VlUA0ZqDV*PX+w=nU94m-f#v&8+-Sh)8 zSzwYCk}+HsuhmCFCc8UA4>v!k9*(x98W;STc-D!>b0klY?sq`hd9O+klu8cbplhFJ)uY*AJ=XU73EA#Eue03`%2xQnX)V0EYg8kX-NK{U?GB zB+U2XU*=qR$0*}R+~taVq_}tV%>R|dz}BNGy!D}mZLo45PC75zbF*|o*E?g!;Hd9@ z%2W!2&mGxfnU&XrN`AWc>{~^;2?38QIvoP$T+6t%@%_6W|2J_b^tv)@R zdYm+1@j8TQvE?{NZz#;YV7_AQHV9Vw>wjctf+7LFlN!8O@62{<4(vsm$w>*{AMe8S zFT^caYg5f{vm+)sa0<{OjdQ@boEc&k6S|mRSA@;%wV`BK8g0*}nDwJ||5Ml^H&$e_ zo3mrewU1G~j3MPR%ZbNQ zm}{FH6X-$x&9UN#?*)ROU^_;KW~fB;E9=QeF6~7{A0z7Bq~oHNCQaJppa4V-8%_sW zuqw8Ho78Jpv~naT%fgTGNMi?w-@DHMJ$%(O60w1R!s~urE^b zLy^cCTbJ$49Co;r7g=efawyM6?JMt;7e@Y;&CzGTi3jBj&=kWjsln zmA(u-C)$V(R*yOkH9Fe&As>PlkXZaFK4=c4|yFk5*;YRP}L6XW&ztvQ|o8 z=2E3EF1A2|adFW!1j-dovT&G^)E9qjvh5AIaAfAQvGDnc^t9-c^BS7;YU*%y;5@TpM2Z{vI znehl@zI?P|@j%g%*XPts0b%DRX5>=ZQi#!?S?MKz>j+R>@$V)OLT4eH;Qg7; z##%91Q{`;bRWM64kzifF;t?LOXMo!vYC`~C!fIOR7C=$qLgB5=@T$jf)AI{+q0eDF z!b<-gf2B$o>AA|-DRs#22*mqKM&ZbISeyu^5O$JN2viOHf~|+AWie9r+jqB^? zDIyOjLF*pInZUpXvEKKKzwGDokRO%6TExMX{OkKvY1>P8_Xdx2^BV&bz#0d}=)&fL zE8kwoysOWSdvk~I+F-Q1imhX+`-0()WIYMlsUkK3IGpNs=dqkCZ)rKYLFJo_&0`?A+S4uvB;^TNf9K`vq2Gr;igsP7U~Mwd%el|GwyjQ zQPIkZOiClH&TntDAefnXE}>5`Bhyz0omCDy=8F+o> zJfO@K;FQ2!%hd+(Jg-4BSrnRZ08*2fLlbTs=0aZkp9$yaGToW;*Myr*!6vLIO7%&< zaUz{UJ}BlkXU`eYJ@rKPr{W2CK=caaOZ+q8SWBP`*@su8dF%Xc*#j{*eqSM)?PP$Dxd?Fl z;~*e{*aGVP3PXl{W(gi6teJrIcfaizY==-Y4wra)Qxm;Z!HslyborYhvS|IrJGrk$ zfx1Y+QMDHyiIfWTgUYT!)f!q`*$(rrz}FT&nw)5bs`%+Bw&b5Ss@mF}@bXi#JPPEO zG}iN^9dCYyDJp(;K+Z@4d*q?8)FJle$a}|+mB-t4lw`=G$m^8IKg2!fW{y1peH))Y z1*!t6f6eL9+pQuo5*CiEhLf#cnsZ>k(^waw%1hGyQv>17LI0YsPtUSEi;x~P0gmE-HdVny=0Q%XMr zkrRDS;ITyS-6sSaO@-Y+qzWS|#SX;QWR4O)_YqO)F`myXGSuS>i6y}h54x57oEizzO`E4Puo}}h*1rl+7s}&2;qUPSOO%*#K><8Q2h|zm^ij>XW2RJT z6zN0z<2kAhe=V#W+&jD8>pK7}2L2UXP@BSm2R@r>eLY@qAam)-nVA0%OS1Y-jgUuc zZaM95dVM4-5Qpx0^wq*c4Z&Zv*Vl^qs@&UM5 zpbuR)el^@tnuyEtXm=3;9ytUA+8t`(K8`ZBhU=Dz^z*a!pz7K#Uc z<9BP)kG7akc%SM0POfWfZwZV#x4)j>MjBmWkI{Mi7%|WHuk>sdDu)3`>;;wpNQf;T z{bw-yH8qoJ;fvp+q~0rMKsVQmwdl!p1+T%}hFa4GP<9{VI?N-sgL=>$*0YI^2~^e6 z_(l1z+`j1lyrJGxpgCP)&3IaL@r1z%bOizeF}T-x(AGU^nF<4ykSqi1F#XVxr4|+L zBhL%d)`n{&celHv?r(zdb<8@`p&b)sp>5gZ8w)tTheu1_=iJiqS+)RgC!LWy5eb5E z&;?vBfi<>*k`PJW=$BgY^V}&gX62#$bCX!O+iU0sAOffeogOfu2 z(bF^iP{025imvY%X@|nlMbsV9 zH9-rD)Y%SO3u))2FsXM<_i}BUv#e}~0rfwc#Q)%awgSetINWHz*a*EctC(%;PyVHP zjogm?on_yeA3-?aAoyES0r23s954BotDXAoE9A5&juIrKzU-CYg;EpU;4=?CVvM*8 zm~JXMp}74aQs}w?i5*wsRfj^JF9nWiKJv7vER(FkId6|VA`eqNFdT+f@Zsx=5H+qx z@cs5#5$1|3a_RG{#I=bKO@5$n{PV|8K%j1o;HKkoQqDlm{qq^w!oejUPj){K9i!E9 z-_$75ao4V?CmgC-utFsK5DjGSRtBe-K3OQdVu+PKkxTCqQ!H7n>BzvzQ(6nualK;7 zxgfeV;(h1Y!Ao#agC!ruj*k4w#dG95^PbBy@6*3bSMR2)JSpx)y%l}yepQuJf}1?h z=ltuDKwGye%wHI2k;Hddiej=C-q_rp6g9k4(Z^%GSyPB^6XPj{IG)Tzvaq&9U=mQv2Y^zsv*+g;l;(Zh^8M;4c+qB?Ua?@ ziYVS;&JkYABo6z0`N>5Y!RHGug?yY$Us&E z)>SyFN4UzpJb4+m?mni+>`%K&U4C{2>^)J+`a_-hkXwEMIOE_XLPuW#gkJaS&uo7s ztZx3EeWb`zh7(m+nc+e-X7@~i{6+Mf6L@6*kKKZx6z;JtlhY6F?t}uC9%;f=wcG3y zY;hxkxVU%m`^r11Gy&c;5QO8>lEQ&+)u`Of(MYR0!#Z$Jo)Y>NwzRr=I;hNk@vC6w z<1z=Z$;i@$Vzz|H+jyM3E04|F>j*!1AMGR!PY^9jo4S6|xm$SS!07T2fR7KFe1Zg> zKzcVOu_XU0rG0xJ@7q;K6qV3FBJ@a7f`6-H*2upn4Y*>~3+>&%S7X>TupA}vNZV>N zGvwl(;YRBgtOqAq)oV9tG~ZEzMOO@m0wF&9TU{(k265xW5~T4n9K;U4h6T*)ygHtr z>ePIEKjH2K#venkE>u1ce585=(GNP_Vs}W=_it=I(>|2=sO8D4$da+4%UO3>055c_ z6+DHM{OG5EsSrvL{#4kE%u~DXiDfGPi1kUq$ixp${gb&nCy77jCRvODRtcO1L3Ers zg>M@#;4xLAnb_?t;3KBz8KE+8yXsn(%ax417nXg%+aB#_fmIPZ(P{fkr!6%Xx60R6 z_@YOLUhW{U`EXAZ$h_=)Et{E_0D~4L8i8bAAoV8A7RDsITt5UC_PI%9fYh(L~3J+_X2E^cx3& zq5(@ciUZnv_$7{0F2x~bqJNSyP+LwKhqCPZ#WE38l8iQSh&UVW%U;XvyHPS_K8iM-c~E+;E2GYgN& z>ngtYoE&Yp{O{ z4Fzum{~8rY0|@S6-#Kr?m22Rg;`H}&X)d{=`R5!bkCQ(?<))vl&reXfg?{-F^r1)5 z{Vd9E?hU9}#kIO@N)eOG(Ovl~ugW%tug1)jG_(hSIzr4Mq8RVM4eDh&lbESuDKFO3 zjB9T0+c!2~oJwlslUC8u@(9)9 z*I(q*nAG!kM|`4%aT5-ABpJ4-18%%06ndDaKG!5`J6h|KAGh8P&219L>e<>)d+aY> z{f;6MI0QzLQg|qILf<6K@*pyo$Zh*}okk&j{C{#Z#?R*$Y6ZZQQ=BEIE8^otEN~0G zIPWovKzxVd3{r$q{aWjR(- zcL0Y7{I5HsmeUz$IqIyq|Ji*1ZLytY;d&l)n1~?w&S+mh*2nUTWAK7HUp!*P-SlkslqsYi_^D8|K-&{NqC6 zQePhs7xi)(+w__l8Mm=t{J{er8vZpi@%iBL?QglSckvL0V+m=UvtIukCY3DNy}eiX zR(_*7;C6}EZ<#1M_dhuA$*qja`+eSrI1%B&hqY}SP^C10_8cd)=TwLgh-?^= z8~&d?r?{Yy@c3_S+y6P<(chNP=%hx%uYbK`qTk_kQ?f?+)bclaYWOJbQ83j%PyX~a znTI!Wp2v&xkoh$U;`u*%%>qbIg-MAd`T{7_^PrXa2>zO;rDTP&uAR*!>dqSKg2k}P zZoxwnI*XQp4C9ynDy)bG_-pj$u4B+do{ylJIm6+v7*T~fngVR;Ruc(3tg6N%o?(yd z$yMTuiwXIhqf>GbKUuIq0QzT3@Ju{IhG7~mQ^Cbx&($uijVzp|BMc*K1jR+oEea_lvHpMHDnXs1bE7zIC?= zyjsK*lF_1*P`D1};!X)vZ}Y#6H6rWcV(ryU2Ma$qMz_wd*Y4g51?2yTZ0R9Z$Q&P0 zb8O2M+-Pko?L<^%tJgis;L-LKX<`-&1}f1;7?L7boitjqbo;oOrN459+_-tchV9$89NacPA7bYC z&-*>x2W|*a5iB5zo)TeLd98|w6s5<4gkf+lWex-Jxzs+eFL{(b{rbv8kmMQ5mB3v! zIs=h3?X(kI1Rbx$5RwMQHPI(>QPC15j#kXBBv*X&5I}X$XU}G^?-%m<|5U@dyKNsi z@#yx4W>XiyR|TFzrG#P|enDyV-c4IW@&SW3_jry=%{e5sX*p_ApNOsMrJA~wWe}ax ze-GpbY0QBXc#mecz6yV+!Er+=RLFXA2Iu|@CtY<`#oJRSza+6+-DPgy4tLQ(%>QGz zp8d;ieFwvCjkX2#iax%3D;Q^k6mh&Xz=`cJ+PZ2ir+(FNqYroAzmgJUV{HA;@Dp|y zk{%S_Bar1zie+OyeCJ?Gfm1ntW_w}wtuPhFdH?j4dH3kaPDHM&>R+yXrp5 zM*g^CeYcL#C>V>XRE&F%TGpYt8a`{l?;a-YnWzC`{gZlBeom2LA>QZy`h0)$L(O2Z z)L0npB6U)UdUwQsAaM(m_Dt^vv4N3TxF1a?R<{+K^(VO;UcRH!zE}Jwyy|<;%Gghn zKcEdA#3Y4(690Z=o{!y!fLl-RH?QO7ekIAh&_ZrFa%T7;o}kR!_Y55EK_r6|M1~aL zFOA^eoPH@CtF~ZzNZ>TQQFhtoPa79+dToP@C3tTSkp!&}8RnBY9nd`Jzof%VL^`e zF=d7L1x)1fFp@RxJVx{{8U+TBwo10CFU zXS>!``96xm>T3MR8y5v1pR596AC^=E4@iy9K`tn9voXJ}=i2U55cf6sb|sLP>YPhl zD5|wQ$W9Tkd%^fVk_b2QaYzn{gkL%Tl)>fiq1^ielFeEwKLS`EkyO->uiSVo;fI(g z?LZ&ZG3dk1N5o3@;h>Yx@e6L=>ye!FnBmmh7v-8K_@sF~N{A%0igLD;{1U;!Cdfbn zh9CqZ2Ss#YQ}>52w{>j7_6WaBecLwt?0W3n@%WWguDpD-j64yb5Q5y!C?r~iD{sBd zH!;6#MVXtV+gx_~RJ>?nf8BJg#^wVmtyjPZ=nyJWpcvt4#IGY4TDSV`9{lOU7mMq> zsqZCMRH{2~E4vIF`TU9fe}r9kJeJ@4zYmYS_uhNY2obU+GZNWZWs{6#mXT~8Qg%s3 zHip)?^{+dN$Qzvyw*<9ql0p zt@X8!@M!6Iy~Wqpy5kq?9P{I^Jo}+39vIpiv0n0j zB^m+JAkh=bQ7rWmT>FQ^?exf&weR9|yUM!!$=cp$3nXY6hF#3em)Nf7S_6*^oP4IN zgNq-#pDMdee@LdrXG<3KaW72ReDngsMwVx$%tksysEVla#WkYez6vayQznEH9F(gZ zf3Y%naH8=W{L@O#-lo!Q)Fm=~7ZB}0jSmJE4qzZr(YV4a60p@#WWz<#tip*VV*{dw zs^oXFo<_bfwzYASc1qnc`og$yv+#^s4TczD;U`E%Ct`xtJ9vUIi7QZoN{>Uebn5xM zY<#fg^liEjyc|}0vP0%uZ*TO{T97Z3|2%<*_{-w~fApmJ!h2E&*^zxsh(!&)nYU}Z z74BmGL3vUJQeT?vZR!*^Dg}*f{O+5y`|2G4&Fz2uGv-|gp6jeXyl~fj{kiVFwE@{L zadMI8w{mIAQdg}u&SO9F0OfR?`c0|PAHT}?w%@9a;oh?}*0dm&J89RM&f4)@M&A8( zEAF&9iUrw1uH46Ns*?JSp}bT+N!MvbADi)pXAwMxdbamkdqiQEXRlL*_ed&yVR2cQCw)5TK34 zn8M(`u1E06W3S2+j5q%Ev!H%S;i^dTpyTqxBW{X&uY|1&kU&0xw78q7H_2b$3fx21 zWZMCD56<%QN{^?`#%FM1hvh?NYtx31mVQDtdqk3HQAA1F@CL9~LI|?qECi@);#WfH zsc|*SkGoY`hPTq5NeFie-AHm>{xj@1G9`x>2mY+#j6tR;AdJk?oaP#pxDowRkG+CM z?CjO^Z^UaO#<%Q}6Q`bq$GogTQkPoLr@jlHx)SrF?UDypJPFQ0`--ldo0jCQ;_ugE z?^`%p&lPVP8y}8J)S0`sj*A;uLrFI*F?}2;=6L1)L#|@;Gq<8nxiLI( zGO!WZ7(j>7`%od^3alh!ZFm6VV* zae)x@4*#Id z*)SJ-t7vg+ubtQ0a#iT1_{s+>eG10miB@aB2_Hm2hD4Sex_M{OjvsuGG6Ftfp1xO& z!AhcpKb@M3wb@(4Gj8{7UpNO&w4Hp@?~;GJR`XJ2)v3UNHn0wFUM%li5HdQ4Yl0ePmkRRZi7Z?k~eTyF_033m{bcgs4;-T4=&+%OeJxW3&)~KzfTZv*)+1$WcWYR@{H%XCO=MhwgG@*wIn)lEk8kta4!b-ur0dd-SO?P?oUg4(~ZPx;uKE3+*yy=e5o4JmS z=YLh))ejI+85&(gSfsA=Br=O*0#?a>09YlsJTEyr@9ZU-HsO3}I{m=4|fUy@OA%QO` z#Z78!PpbOnv%6z2Wo2J4$nP*&a6Q9UBtGsz9{s1DmO=FtXZd8c{Ih(-x#7Rl&x%&i zviWSz_)0w;E?bu&I?wv^tiWMS&r<*3ON|VK@xL<7^#95$Y;vlM11s9`MaoZK!0dJ^FHnS#n@wyXQd#46lM;UvpT_t zto8AE{i|^f-`pqX>WI9RfgaDkLSM#<2mTKfuKyijL9WZ8TgyX*xrQcZP+<%QRH;%W z(8hNaC4ukdr~E6-zr4#-jyF8*q0fGc?Fyaz_2Qc2xqKiXJAoADprtluU!7^Qpa}_O z?itV9m}UKi=Q*P`U?QF0fRUSbtDM^f93==#C6?L?4m#Z>WT$Z|#Oh6XeXc~ykMnHI zcwC#&EF1SGC#=)Y0diO^MFuPK6+UC{?u9G5#gqE(A~aIOrw0wD7X;@da^hU=h^Q<+ z=IH}HHgr4isvxvqX1#zRS-RtvioLz0M-1;Z^}P4D=g1m}qYn9QKF9=VeqcQTXZVH7p^i6)$4xyK=NtpB1Rnc?_XXL_8J#|k7am)VXLp2P_aq4NZnbWr(Z}$wd7AxCWo+rfOEuU++ z>8^)@mLznSDQ4jD;E8&@O(H^~+4{Wu*!SIbh@6mdo@s@}N0t2I?p}8S#E(aS06iW) zkmv+IR^BzV`i33+uCmYFugJX2#xFf-(n9&cMXq7N>7!kgvEpJ$@Y-=T@GJr>*AbDT zlkt2n^X`$+4e>dX*u5`!z`xxkE?0f`?BknX%hGFr-f+t06>nV7SYJ5b_ZeqKm;mz2lvfd%;51aerZ z;*MSHEqn!|xw>zpWlwLYJgS+6C;IoQuZLf}KZz;C&1#4Fuo7cQLqhu7EkLF=B5gZuiYiOj9k(d$26) z_^N1cU^p!ZRKj`}GFXPEaL}{9PZ{S89(%Edj265e&;6-z$~;)F-?KmVRvMjsuOU!Y zQcc5h`NA<5koK$~A2t5Vw{GlBYO~QdDm|kcnzi6g7`bp%fFAbpS6M8%-y zZ+CM`!uXb01a;lBSM35{9fJ}n5eLtUDUF<Ub5fcr}C_qeL|-c4~n z`Gh@*6ZaVhI2$g-a9-sDzi=W2s)xkay=L4iWYoRP${${9B^*5c^R6qYp`TT1@yEvM zKwEEc1y>soWrN(<3K@7#M$|ddEbH8?i9dQWhDC&xe)$H)VdWDE*EgU64}NN}mW2>; zE<2vpNjB9gZMsteQamlY5uf6pd-oyCw1(J>(HowcI8>xG@qcR69dk&~ zlR9-+^oHg>xPube2vH(%{Wr1TVNud2Q%@S`pzgA^oR_;NS;!Q=_UijxBvvq{+CMd~M9O?${( z9%6aDe>e5h=)IDb_tcBBDi&5$UKN|=UCU7=AYlhpC|I1~9DP6Tb@&Qk9-E)+73rXt ziHN)wJ8Jv35;AyT2_CXO7NqhL6DO8(pEFr};2P^(}1X`A?x<~Zt{ zj9O(MP7oLby*L7qaMbU#=hGPOGm-I;O)bb@y~A8L?UJo!_*%yZU!}X6d72;TvZ%gh4EQj*EW(uxG6-)5ni3>+?!4}tl;ek zym~hm^KbZ0gE?b@U&rT^(~yVI^@=NcSqgm^ni$nFj!BH<+H_+4Jnq3hE2>6xh? zR%Q*Ysy|L%RM?#wcOPwM5Q^^@MZPniIK*K7Gkl;BLdXW>zOCMUUEA+L7^O+N8dRR8 zFG|hpPB+J~eeU^WE}}0@Ad9|ZU6grp3nM=$c?-d!zCK18(ID(aK9YB@SRQzvlUp(2 z_I4#dSPCs4=u{I{vjdk0|Jh^oXuVI)*w!C{I^yph;JI)1fIbGZEX%v@F^s(%gWrd{ zYJt$ye_S_jI54LVRjEKin)rSlmD_{RXHkhYB?Qx9heWSv_&$DJ3juYksP&JR$ix|x0LAsX6Nr+UEW7B7^ zT+N9Hk6*nrf%)4o&lWbN^uYh&RR^OGSuU{B1Uoy4Q8E(8tG@4KV|w|dD=DMmHJwxD z4rea$7s()|Xwd}`?X`{p#6}Shq@kvmHH@^@BJ(((kwQCkHj5v@iPV)i`)z#C{(Z7%X@P7m4QIqb zAdY{F#x5>e1!IuT?}6Wk7m$|=7ov31Tqw#u4)sad71wxm%K`sllx&8fmIs7aDWGEi z9Ro|?!&ESN$RqTGq5Qf3wKz*|^dipXhNWbQ_2w^rG~t@e$UCKWchTczOxI50!r5%< z;#$%l_Md)b*`@<;OPqI`7-bdNWTij<;$ACS$WNu`LFA*jw67rEEN0vT6v!W3hj3 zENU&)g9YEX;r#4S(;;?E-1R^4B1P4r_F{S3lwFB_S?(X!$xrX>xI~?KSWcr*y7Cq|fo7-~z!Zv$p5snZ-I)bMM(rR?<(+ zWtv?-sWxeC42Wvrm|~|P(wD1aqlqo3$;Kfgm_tKfA(1wGt9)lFwc}xyz!T=1pimeh zIndtQq1^@yrlvL`g+;tYQP_6sfGSI^>%zw$f2sB7v*IBmTzEXT=qVriuhOIK7VN$) zQw!$^7%A@e!;f02B_%q%R=ebCUx*a>p(LGFZ0i=K$UT&`YyGDY~Hy<5soyq z&Wpg}GOX9jR|HoOVVYmKL%dH;e|)N}Y0};<$J27?@}WqH>)z0)#)&7u{3(l5AwmQ7 zbtFc~ujE?z4FucmEXUgSbXRmdD@XWP5NOHD8iLF9Dom4{WNIN`V|j(2yo^4(3&lM`p&jUk4GL2 z<%zU6t`opr6o3jCOy@-4s5#cpADDXh6z?bE)1+>S4z=m{7a+fR$$iWz&Jw>;1+%A7 z@m@~I1t0Q(eX|#a{I9i)><6_+_}_U&{)*FNiIdz2rT4cib4o;{nNVY20E3zM??yu{ zy8`0r&2?k(J8@&QKay{3c^(s37e==6OdaH?@LiN<1$VP>_Xm{+#Fm1em8T1fGERmr zxTR-Je%(?#cz5oqg^YgbPxV5UKj6nV-2K6b2Om-zbMEt{sBeK1@3lK@SQ@4KHe7#S zb5mKUdD{wkY9QVFAEALv9FAMvSQyLiQs(P@g(h}@GbduE=so^N!H!o8cf4k0;)DTJ z8S3-L(9mf=j(>Vivh$hxvPuF$IaRIxiNQOsub90NQ@LV!sQ!)i>>=QR3|450LcymA zSCQB)QAtKd_eFGHs`Wgco~2?0tCZSg&2IQZuahp%0397l-9mt)e|(2YXO`g>-XV{} z@cO6yb#^jonQMleYC{~CtG*c}>48c;$d5tCB{~aN+{sc+a8=JbQfrYEPw`E@oz9Z( z2mhX}d9#a`ud>W804Les2$mfJyEwy7Pb!C6xNFK{ONApOsn1#Rcj!IlX(%`dcmA~q znl2&04!&#>O1N6y&VAEYR5YjiTZ4ES361%v?8b*$`Td04K-_1?bijG}UlSF+6o@Tf zSLYx;9?nkNdTlB!(BJfQuzJt-H2=mx3DZyD2ljgZ=?HWM@L+U@`X(=Bl9P2@?yI=f zFZ!tN)Y;@ycYZWlr`}__1mN7B9lK9ZNZuW=3cWgyXv45}Ep|4Lb1hmZS(?nRYc0Q2ux+RgqPHxgvC z-gd=5&fJy1nzre(OQQv<6*+vcoG_$9{H^)h{ig#3T(tdLULLpol6&&~g2Hl?zp}Y- zbIZC40bO-eYrqn!L+tF%FI$?=zo%HuP6+a!zeISUHY!u&M)N{j*=^!I*y&==4tMTI z&`{}IY6HLD8_xnlL-(YMZuh=Eq0Lyl^U9mWHQ++&wcSQwqRx?x;U6 z`rlWbJTxCoZ=F=Tu44MO|1oi6qY;Kw98~EdBu+2_M7RgH+w`u2+-L%ur2N>)rk)M# ztZU}YPhQH&s^>j=KkM^?z}$bGi-DPvOW4W>flxi46>I_69Xxkj-@{&5bd zJ$e!72(Gr`8ivv4L+sWkr4q-2L(G6Gt2d$8*=sFdD(_vz6eTmp{N8tVjskjNFzZmj z(IS4o^VZVIltI(!)jvHH5%B?0NqtkSqXeOYAuXd8h3jB80pQXLj&|UPqlY~=P$WPOev^PM`Z>=NGU-Y&-t2ZN=W^**d6gZ zKg|Y>wWR}t7FRf52%K736Ah7tnX35zCDgF=!I6bns*oS#>P@>ohS^fAoocMeFFU;Z zRqyaWoPX(Q{usFbmrz5Cs>#yY_0I3Br`7hh2zon@Ot=*c9uHTW1w3aBuw;?i{{;MS zJsdD(Jg{idf`X5a^}QUObEPiCM)c}7@l*3>1P!fdzrOvRcdxfU1;{7iiWX5c!GRSc z^*SmQx&@5xeO44_&LWxb2-DxQM995FyjW6|8o=ypoLr_u6)05$YP}K`@ad8Z2c_pP zuS2aVz%4K`x$TF=ZJW#+-BqIo*EvldIo3MsdB3-Qsu%zr1)ci*ib3i1QFJCy~_P8LXV#4+2InT|c18 z11(+lI`~aroPEP+%x`8NrZW0mf=SCBZ!5yMsG)l~`NbGpQi2#lrxfRnYE(3WSQ3mR zF6*llPGG0{?y+l1g|$du=ChJHFGZG^@u=l98qLU_|yNKK2S6)S3KCu6)II&((KBha*Bj zE=wkJ}US&UdBP?V~(RykoVeR@o<+v|w#%X*{fK$+a!bTtzj(ndXg<@bN zF5yRZ&v8|EE42ariWkS!^3h6d_1sgwmq0udN3?~NmI1Nt2-M%gAeWFIhS2t)O&9vV zB8^z}$~$@g?74*k6=f@lbb{hDY%*0`R73dZ$5=npr3wWXTlgA0wP%3UhH>^B5ht9z zaJbwe?zu;(oBfp*HB8RAohQ*(rQ2eOAIh!%HeB)mzAX%>n}rtruFKy^FqD!pk(sL6 zZ@5qE;DxEE#c8zC1ut-Zp1DRX2ku+qY%gAAh<(DUbi4fepF+==9b;3cuh*q_64nmC z%YMJky3;PClMD>paCRc;O^9vQ<1Aoj@?H!H#Ps%V$m~v0`Y+hm=dP!ao;Rmd69JMn z@Ea6Em9A%Z7}mMIL>LU7WRsD-?hs-tlz2$q^n5)+A(TBqtp^l@LnQe{hp(UJA_dXI{_=U@6w_ABt)z_f{b3miF4v2^ zhrPyY*$m6-Ty@tU1D`;MBttE_SH_HYjJFQsDtVU2jF9E{#omr14&|eZY+s~E=Dl*j zWHFR$)EA&!s}26@_~nx8t<^t3uIf#_1B8lQ7c_O&6eq$hU0S1+!LX<<|uURr5+d z?7vNM41OdQ9IL?mtHzx3E$A>oYu6H^bhUTP#j7;nKus%FUqiWy;TX9;Eo)54Uuyk< z-AlsV3p}F1#lrxE4zxX5TPDD|3T1q+(w|-`P>C&iY3X0){ZjKohe7TnV7Z2db;!^= zW@u(J6G@IeeLML^gPV0OU9w*HOj|0ceL$VbtM~V%fLJXW#-Kq}li_?R{%S+5)w84H zxha0uT6(K`^G4J%5`L#g+n$k=10pLHnR0|U6HNqL7*UbMBOty=ZTP#N@%jt<<&*WE zZLv4L>`kj}wFo<#rSL2&nL~S<6M;MCTWM{ zFa6lPrGPheernpL&PX*kYVSbWWF^{&To?0c6XmbQ!4;0*cAfV6v%MFB;f!~CYCjZv z{(DYjtw$-@JH;10pT>ch5&(DM)x(8~+fP#pHAnX*ez)JuG}kKX-_!T+EIm2&*U+M! zorx22dCSf-_YNq;{xRSLVIuI>=(|C})zRCH9|I@R8$ zD&2kf3eT0>O~rNzw9VnthZv_IcAK2H>=E8;`&bQFi13bo-+Tj=1@Y8&3a6JC_JoBf zaIix?ThvA8;}?sRv&k*Y4d(p(>=pXSaHMZ-ZFMTHr5@_?!tX77kSfP(`0 zg78~;UX6dQ8f07wwy#;YASw>f%egjGRTenEHwOOV!_SKay+&yAf3LG@jbxT{Iz3zx zx@~PAIqN#uJy*Pwkus_J%Mcjg3~e;P!o&{V&yQA9bo5&gb_^&FYV^eLter zONrJ5KCemk;8xMShFDhef&C<*O^oF4(pzdlkNesGor^eU20*R{dY2cQ;fv?nHbOI`ONzi!v`)&I%-_ z!JHML35YyVt3xBF{WoRi&;uY0x6IZ;^zocfw$USq2CV$pjo+bT;GiB{D+y8V*5AmKA%Y{Evh@FRVY z8ji4pVaZW4(q)^SPx5^s>JR1=9tlDftKI(#gHW5YLC@LPJB=Pg;3hmFEh0=%&A56m zg1CORl2%);?d9d|B1Sph(Z?Q+Z=b0AGS&$RLp&r=xrFAny1^(-1?J5t^u9^9HAUT_tNUXRKfr)vi?4?d+BLPWS2NF%d zqj?Tcwc>J#X>UO6UFX&04R-h0yopTjQ!2IfbuK|x&G9e3MnAFK|8~;~*gnJ2FKJN| zJ~c)fOxRc<0J~U#t3fIZ%b+3mzD3;Ol>Ioo)ia=DQZV)`-~u7dos&UVLL(9CiEJcR z1rLa!&kzmYYA~jv1vaA;7lQlrh(5eW>C*T3+ZZbO?<5gltU0KfqkX=J`uh?E$c1_V z>!+yph^4WF*t&BWq)iJwG&*XMCrKact4=C0HH$s2D0m}VmiqH&D(J$8VuXa>|)&O}71uPJVs8Y6*L~=|Ei#c7tXq&WV zchX(_*8IC0r%CEKUiCISz9~&(3wm5of$fJPc?MS5IfE|dk8E|M-H1IuRA3fqkU!ji zfmV8^?L|6xV@YrcvU-UrBgo>1Qo6&PmeoF+H9IYEv@pt~lD83kY4T*%;U;6X2uuJS zdjDv>L}qZGdxa@3w7!TV3!#jYE&jdd#Q9`J=5Bk1jZgx z)2|e1%sibwmhXLh~KyG&O%Re%?N{c`gCS z4on{{hLg3HtWbf+TQ~{J+zpS@XH83orEb-N*;hwCIenRPnKb-?)8xP71MmI9Ypqp5 z`jxaFqXOj}%q!41g}jiJ#OKkB|9au)_GOEbILR;B`yC^EIio}(!p*sO`goFD-q)lI zz>iD+!h9qga5SoCgp&=VoJXl)A@6B-X97 zVMt-lE<5QL7LC8(eY(uHJ?18u=7qADLk%Jq^a9@!hy0Mi`!?lIX?9N8!*TM7W(-#o zmIZ(CfmaOJe}=OZ=(r(v!@>Mr?3r(@W?Q>VV%ukA`;b0Cb%p%Qx}~(w=Y8?P{w#wu zv`QE$B}n48$d{`==wBUS2(n>jQ{2{Mh^qbRc05OTfqUjV(N`Ogf>!HBcpMet_X|1a zPwCx^`9^bp{?{Y#A}?kk-AUbpPFJrNFN!ay0}g!HKC6)BF(l?L;d}LSbpLsk!}F|3 zq|HLh+%vZ>Jzd88LTvIr-B7v%f(L7P;;K+1(1rgA)3>ThjgisNh>KsMk+E_9S*$fo zt>e-V?cx0D_@r&^;0Y>|m1DPGwFKWmV*pe__*dXl(pC&<5)jpt@EFfrI{z1|I8Wu^ zWMmZ?FeS6`=Y%H!*Dixl_@$EkfLQK&^5BQNO0ncNG26|PYd3koRU_8Yqtv1fUAc5c zGcebSOAeyTg~2#93G6&H+=Ss4*+RqZ8w|!d{VxfuXg_J8;9pUXCDAqQ=1rGxe#Uls zbVVkFYZrAxv7Vh;5t8mi$?V2oz@6~_ih2m52S~cO#p`agi?}jb{8E6aA>FnPa47%s=V|Fp;*bzsZhD}`$Fu!uq*C%HkkLbH@uT8jNzmfDx}?NM zyn6AT*9L6Iypq4|DyVD*&Jb6N^Nr2}zG^`63R;hd=ob8*PRS?+kLJw98RIYUCNFgF zzmi@Go=K>`oMF20l62Dzkre*V_J;XUxN;BUKTz%h0h~xp=%`cw(C%X9$wk2n3Qv?9 zi2IV%2KHS)S|@Cmc@+S!be#O8w1ZeJohf%Yg*Z_HPxkenOKgeLE>&Ts-f8)c1K6ftePbvc>Z>ldT4vt|kf-L}tgbj?3~bZQsS2XTDB3ZNH~ezYC& zWI!+Xfv*0D#5sF>tijAhBYNXg7j|yZ|8=BAxFr77d*qOScM>b+?ihz|p%gJ{6fK=? z4f^zWILXB{{6#Fy)bwf&?U~@pOB$;@=Njfjyz&u84uaFD@UiEB+KfKt!#0OLR#pel0K zU7bs3R|+~gBEx}t>AwVC>i2NvZg`>9ymbR!8Y)uikf=2#Ui%?;4$J&?ao%+&zR49? zXJi;g{>Xj-I6B1@L%&_mK1%1CkAsM&$fn-6!YXfdA4-FxXh7fzmmvtr zlZY2h0)DOEJYR0=AJa=V;cQBYAH6j%byc1ubXcz2^F_W({mU_%gc*`N2AF_BRTiuy zs$>O-Py95x_VCM!Z11DDtRXeeVeyY{jw7KCuP-7|ARIWk`wqWLL%UHab5en>E6JDQ zro7MEygGEJ4J9@h=M{k*jtqmvdk9ybrsn}vv*=CY>pGLMrN5#S zWhXU6QU(5Lws%op`xM4~j$;ZdodhRI&$sez^cp7+(XhdH)+5I+R`LyawK$?kGcp$^ zD!&PGL@0uwHys}h*5Bij7b?B8bUdFCm~_F6IU}Z?K(dUC}&n75w7GT}Ajf zmsNHGf$N3VY(a;daXg=Lg4A8<7i7QGrSsfsyMxSKfvGgKaXC?5Mo~h?BXY`zpn-*t z@gdhhO4qpT1YJQW{eYg^niCl%Fv7{Fa}Zh9GakI8D8qH|qsmWj<{sHPXFjFU4C|V{ zf>={Z!$;7EtLLc$k8!3R|X%!|E;{O|b#w3F3d z+CRU+^|N(=|7*S(2=vCO(`395I~+Us-ma?i&y#a@>uxy&#kcM0(<^ymzFga^6uj1S z0tDT}?JEW9-uj~X=gNx=-XZ(+Vx13rf4Ab2dHeBbb)RHp{(jMaIRj));w}_MRqYS) z6XG|(!pzegwrmSNbvm`Q>@kr!+do^b9tlqVMIUd2yq16EG-*+t@|#Ra*oEbR``r;| zn}_Q5&KBc zo%TkA^UzJF2=RqitUapXdc(xH5lq4=${G-ZANuGu;`B+E2+hE~YTK`}Rg`L@YGN_b zQGwmBoG+CSgD_YpNC)ca0updFlW*!v)`r7a_+}0mHZR;v%rD?B|`66K7T-_v zR1`Zs?$O|wWwgM(NxXkrNDY~YP1jNVV7L-}9z0})UpKotM6y^|xc1zw5ER#Le=16^ zl5u4Bbyr+6QC~99rHwOW1B~G^C!3(K<=heyW&U=i)rc+FMAWhLPsQX&by+XQd~A9FJV z5915sS33OMugnlSQ){hXXyW{ubGZu$rvIz+DU3#X6%pc$aOGntt4jGF9cPwLdxOA(y?f+?V~wA1WB zm<0qBwZqXgJ;sB2R68C z&aUB`)2b@eISLKz6mi>iQgbw$eEGmH6E-10byO@mq2oBj3dumJ`?Oe*yW{SZyY$pL zm67#u>FLOrCf_;cR`+5`=6Xh;8xBb90YC(c9>;s%HEsRz$MIH4{7%v%sR&Bph@*|2 zp@~mny!|{^D2jn2&%g3L>>coR2dxXsm2^0NF)e>q%`yD!Bw-Cbr`#fEV9b^7*6F4 z2aZtI^>Ej53`~7DL`9p&%Khup_d6KN{w$0<&fQ6+3$eE)0-kgj+iqk4onf;v&i?hA0xNb4 zEmiH@A6tpsVt|DRTDX}uiTvs%Xb5;fGUX{qrlf@STOzdIPW;b)tD$@{Sokmaww%CI z)3nx;*Kp0+!1-=jG0Dowrz!8x&xx_>I5yvY&J614a3(dFhtsF|&OcDD3z1h0Y5LGT z(0ME8PpWr9zkWxqqX42?VDPDs z7S*}37#TCKS?EtOOnrWI5OG;UhK{|g^_k4_+re1Z`}JxdRs;t0Uxf490 z`tZ`~+3zi-ZslM4_>$YH8%AXCzfW-Y_#l@dZB`mp44nTn-lW^1Y9M|HXUQ9Vi5*O3 z3IF6&+f7cLSZ1Ttm8IeXZ~5$BR&W%E8gJ!f(5sE)^L^Z0L26DW-hP8k|7oL_ zd~uId*F?M9PL8x7G3_tX#)}K+gkV~6rDKR~R{@0<`t{1N!j!sA1v}_ht_^tT! z=(fR!PaVsn#p2{y6&;f8MbE%0MA5mF8VFzAHfW^ zAYR(U>yq05k|glYCP+ZF>JZG8IgSvF^c`)v)Mim7sxK4ub<2v}TJ%4ZtR7hoSctM* zzA9+5)<7(<2)eQVG8Bbl;F8+S#2i``2)Hh?X=tW$NG`qp#((I0kj4Jzw3PK2>_9P` z$l;0=LhaU#vsIY-{3i`kJmuzQhHNam-SGi0n=OvcUfA zAep?$EwD#F@JfxVj7Wh&oo!O|6U9Wu5KwrPCIj6Q(pwPRH*J(Qz;eGalqu-FMqVQ8 z0?*%xSWeP~^L!omwLP-|DGYR>d%}e(!ToI4-q%04>Rul>8@*2KxiCM{+mqiStA>QX%d2S7pxk0Vsp=<+v=zPJf*L5Vu3YQ>3e$V z(<5zjzQ&PTHgC)e{sIvgcPbPvLk;-lUzH>Uk-Cid9KquEn)g;W-qWdV>qX5f<>Hrp zuG(ZnQkfY1V6wIlz#77lH;X-Ti_gErJSEC;ocP%Oq%lf{-4jD;05}53g?65SD=;}= z9)Lpnr%-EK!9PnZUVUuEH%wA)D)=M2VMp!cJv_%otimWa+tOVj(0UR83G|(!;-FcE z6yLKy>&(J;-vW_er&&pNPr9C7CpYu?Bt!Xu1PEXKM=9h-{nVr_LGz9pO|fb=)NMr0 zU6d9Pi(`3)yy|4uyUK4x-M}f)fBLg9+(o7u&C_@MrgLq`6lnY$4uxr73*KDj9d0jl zAQCDfj6%94|0znHlF+7(#H5d^p2JEuz)4uso4Az*ACPabK3o`>DQEvY0Y-x){n*k@ zN4I&Lehg%aa8@bRTZrWxZ1NyFFYLDwy_)~3OJMpQ^D|m@8 zMd8JB6?0Fm#2ok2K9#48V{7mwF?wc79}X68ysJvnjW7W(EdMKSMjQ?Y=5Zxl4{*{y z_4x%uR|1{kYGAmedMjnn$i~)mMEZy}_^pn+=n+C78!v!7)9Xt4BV~vdK zjH54)hS`nN51dv6beXbMjVB^^ltAh>MJBYDSg0ZPl#6rcpng&^!zsba=PUhZy0nI} za<3$;TjWMo_gI_*k+6mqY=5c|uj*f!UrGV{${&BzqjU1>(SN6{e-U$==6qw?X0iAq zFhcT=#0oUwsA{*XC$v@#k0;Lu1W3HHIWveo{X(PX@x*jT6RCCi3{Y*s=|!}P@D!;V z3feqeCJ9d4`4mtZ*p1&|6+Lp_i2Sw=@!OIpeOKf<|G$pQ*I-=@*m2o(1tvU7cf(0E zMuWFhdRk1+()qW(dDu+f#~0Lb_n}DJ!cIoWH@`}-!Gn5cu=r?9UaM5==$CX#@8dcW zYhYmYW7saRn)!;{sZ0DiwhAwAfTWMO1u;P3K&&JC=EDvCUGSav zzuq^`8wwObDvg)>O~b8(ywqHIhz{}WY|kP?Vgfib>pdFF(!jV*sA^!O47Fq9EwmaN zRdN@ShN{o1MXpQFjvhKJ&vYIYtNE(k5?Yc3qs<5fOeBMR9(p*<1@F|gJ5iZK@dic= zD&)HE^9Q@1iN&=>du$UuS7-_l0+BlOM#qQ2tS}^7_Bp_Qfe&JbRlcZMp+%?VWkBC2 zS3b!=C$%n7O7Sw_Xw}D(57uU${6`LBq=8`X3ZdSu%hB0^WJ_lcMMmAgmThIr#T|jW z_KEzi{J}u;zg~6EA@-W}UA6gmn=6_f&m9)m%Vq=4JRE=9vf-|@G<&br(-PR9hjnmx zh9ELHpeK4Bf6!Az|FYGBdOO1(rY`)U$171UC?5pTFolAzMyQ7xwQ)k!3v@0SWegK* z_6i96oix20nc`&W_{k`LA^G|M>1DvKj1ZvBUkElK_~!khAwB$|{h@WLjtc~IJlu}6 zv`3Vsi)ESe2cq3zn`xj{rX{M5YVv z$cMAHW$ioKpV)iau=()k-4(owdv`uu+T=A+G6Z(C=&h;-rFt@7@2<&^ZLhZfADh(q z#Gv@E#xMMN&#G5flh(uoP<$E?q(ViTYlQMAS)@h#{o1m87@Uw{a+veXBwP|=x)%o&)V@VpD%32Sz z9X&^7&}H-v6qy zG{Lf>4W**Z0H50EW<}FY_o?_h^=ChLxc^o0Bd1*_^FJRI4m!6Ga2)?m5k(U65TMIQ<^?V(3wSTd`1_o94+Eq&ej0+a648 zklvUDV~MA!wPG~R?F@LY1BU>!A1B6q)x`zCvN{;AIFSM^umiq6PCovyl9uwEC8k_;^BLCznh7t~2->WY7DOT`p z@nWXC1{mY{%1ko)PRUL0Q50Fi7QtO$R*QQyn#b_1^tMt7?<;a7oTKq59p_!~F)NN{ zO?^qy*H_jtT6dEfnc;+*8hk0=IiUy{!>n$hiR9D&N7!}8Q~AFCbL-f9@4aXC%+Ab; zj3PTBL}nQwAv>!>6d#*x8A%CQl|8aDBC>ag{O)t=`}glZUa$ALpX<4wdtBpvT^Iae zR{=9~Lryz%RQga#jfU|*j!=AupSv8)*fPx4vt*2zlfzad@gYF0p$ofwlY@m_T#&WR z%&-U!+F#y%ZIV>F@>6qe*-_W(6-fqTdM8OstX{evn&r-{eN`}>bZqN2-I09SoQjpXH2mRt4;X~->{@jvwutjyC zYd5)-oIBE9{9tX~g^TR=u_Ps z&~Jo6S~N%Sf-i*59}+LUH1K!*Avqwk{?6+UuR@)6+W5^MR~jReh_^yPBRg{%ifIZW z7gi!K3H_#*{e;l@<-BdX5yPN}Eg2XfV-meW@pXIxnERkPf`k?j`rUuWvx~o5&uwN< z)IruS`8|p6-7~;1v2>btPmAF)U^qat`RJ7(bdj6%8v}Kgao6v~lcT4h?#5p;l6dch zn*`;2$3A==2`=EHIf95YxO&!T+}4SbZ`@-{Nq4=>eh1&bUgHdMhQ(&35;#^8KO)rr z*PUDCpP7i=2Rn|60Qi*kTw$J}{+?>{?x|EsTAwePf;wON?ws8tELSyPSdBx|JkT5o zzzMP23^Qw^eq>vUp)yADzR7(n0YjsYQc`EXC*9NIUTFoo!I&5y5%jzuc5+F7odid> z2Dg8jV6AwsQ0!YiU3QyUW_dOz5Kn9lfyaa~Da(*JXm!5~`Tc~s3@Ppn+k+lHb}@SG z^ina7;Mw$@k~}=arqDB~aq`Ngu?WlEm>VGaCcuzSIN;HVcY2^+%_HPAhM$+e7#DuY zWY>S4miVSZrBC8sHEl7hWWmntl*9A_s_*NBfuc@@lSNrQ8f)OkMA^sPFju3RNcktd zq0f7FZ`XljIoJ*es%Y39P<-;=;mDtaCFDutzYbZ%_0-al6#YU zDpp_dN8JC14IhY^R%cQ=_N&BU41x@BS-np(&)?Wg3H}=*ZVfZ z{{(|N4q-w#j~ARERGPYRX+bzQ*HvR`@&RCgS~(Lw98`KPGiGjXu?D{g&!0qQXW{XXM~N}% zv%nQ&qmo8^7!_y+?eJ?*q7z$`Y$W^ZW@*JTnlv?=l9IKnM5v!DKmY#Xjg&&`T^Ci5 z5)MV>v4Kd<>ZSCrElhX1ztX+B#}h|?qhf(3R$1WZEx~@v22c(L_An6yx&e4LEmZ$x zbjT8WIQzt@Q)Q}sEUlj(To}2#m7v-i`GFqr!U&BZyhORtYMXX0N9wb6cgOmg{?bj{ z4VU}!*+Q)=tgjjq#FfbqGN5|@uXe)-SAh6HCHx>IqGdhL)-%SAyoTL^ z84{)0V+2Y_1Jl$n9nx4;J&?1b%+siga1$d;QLmjR7?W%-<)tsdLZ558nI<3)`mfhI(~J_rhQ zWwW(^;eE6Z#5pDk=^MJ2CZ^F_p!)lkJ{P;NE3Q)%V^nmA-s@);Amj)7-E(N!&}RO+ zi=?&R#_7Oi5qSnk4#ev<;mCP@e(F4D%dX}sQIv+(8>=b{VHzH@HP$bru2mgj!A>JVtniX+A%F0~t62<*SVX@!C6vr3 z_2)_Z>;1f(Iu8bak2z^ejbF5x)8e*~AMm8MDkQ<%Ed+K8d~Z5*fH}~KFU_#{c=5MQ zZ#)Oe(JrCh`#SOCLu0?od>>Yo9)TO!=!_uLO9%}TC^x*t4E;BT8^{R3bHK~8)%e`^ zJn$hk^~B_XGjMGD*Aj%{GDJu6mZU`z_Un1B=!%dC-PEePx5=ocy71X}?$O;|D^q~d z`s*Uc*@oa)^%9|2b?fQaxq-(iV`HMGHE|sD>6%AhVfiP+&3X`!j#)^ga5p1RY*e@U zJOg>@Rqw6Ezxcz;u|MHsPEbw}^8k0`+N}bFI`dzvM-@^Ypw+Xquc(R=mxK?=ATo=5 zGio$v8T#ZifAEfd71g=b*d=6ctO);&*0E2(-VkF7;-YJ_pbn>wGzXQ`lb&3lyq6(` z8@(FMDKoU#;&gX+cbps`VIfLkbOQYw4aw-|vzuy@xjI)|815yWIndGyMf^GL@R{4i zB{3CSR(*_!zVt6uDiT^quaG2-FpE!c4+@lZ*;)WsHOO0wKoh4{xZLKreYD|{x}*cK z^fi`g0vu3?X(EqSZL%BB>ugrKGCk5hKM_0N3T1vKDSc8Y=9u?cCRSc39&q_!NSuUd zXZ3%MiY+fGN~^+tRG~*z5Dq0J|u*G47@&+@a++J{Esfk|FJ!~ z`Ni>hZO-XN9>e+XCO(!`q{R2}hd6CaqizoJh89iWO%sMLm_q@Bfp{JEitG}1g2G-i z>#JHSieCSiG>L0Kl^k2tza8Is!2$Ri{EI%bt3z~WC9j^Ma5a_h&`^t*2}`}5SbS{v zU0!zYdzvX`eY2ngUU3L6yQ1hW_YWSL-k--x8}EIde*$tQsua85mJjpI6SpywFK+{W z-@jTv;S0E8PkoErXnG36RD)+lFIN-yH=X;9ytd<9?(9hOh_M1ROMla-X^No)z0YVo zUYnLT#PLkMac>FIZ`1F-bwgwA;$|Ipban3o(7}#zK3$-J+pS-^yL+=@XgIIS;W3>` z$2HuC%vxeA(rK5!9xHiolp-D|XlSCpegLeUr%HgR60yF36yhf#Bo6&OzsG-ki|>xj zN09PRM>MCCsh{Z|0NVWR~a>=w!JT@p7;iI z-9ivgqSprgA1L{jLv7hj+N^tfgTpvOfAoZ&MOG?Kl)flP?h<7Cp-_T2m-t5{JA*55 z1}WdcT$UqT3^lI}1PMneHdP66hJvSb+WnBcMkjHlKx>*=H^QqN+K}W_9*h9mXg*J! zYDDw~Xt=MW(q-US+-ZW$n3Mf)&z6JD>?l0o#!*;Y*cdxF$;H12k6SV#_y)KP5t{{b z*#hyRgfSgCXO~wj_?tGp1A;$tGds#NB!HVK7~cU2Bt;=q9&M}erS)rhwc8j|f^Xz{4_B8_lXhHOb~WqIiB@;nkvS1sfi>Z(@#gI(CTVwCTVNe79aiIrHbi z9q0BEKHTyZS~6=*yt%F$7u2qU?qcQ>q<}4u!}P7jgZxNGXu6@G>Glbhi!}USu@cdr z{i%=tnr<6BUkf*U{tz-!@P8j>rVvOd3jI%+XzE%F=W(|2lZT4nt`o*|BanuV=M&0L zd9o)Gl2z8c=!-Rp^KO~r<`Xl{=>wAy@~;X9z~1j@1)(+%4MVr6+;izb*iwmD`pw6JE(A8{yuS#TLir=w1C zEXkaE4a_j*k^JE1Ev_n|JJ_1cs_p3$lK8KY_b#_5&NFMNM>llp%3`L$3tt31OfLHf z$CO+D)p%E+MyGX$`luGl4MoRR{@-w?s2U9Jx)VoNNp~d_uceGl94R?7 zUW>dRJ^xO>`sw>91Su=p_Ce<%5dW`1<=`G9U5b5$&(V2%PJVHTJ&yEvk0Rp9UGh^C zHFe@b(Mqqr^qa#^P~c-Kx+oPX4}==33>_EYcsb1*2s={t-Mlz7>1o-AwO3jAd0*pl z6)_-cLK~A5Xve!rne=I#`&61R6J?v5+2hRU5BLXOv??|loH{?xR>*)L0}L@S(L$t! zXGQzhg&0KAcTy6X#Tkv{A4BduePxkxDA6;AjYA-XVT3_PCf@B8N}iKfqan6PDp`EI z66D2$(U8@xYI?%oCHFHghyY4MXj`!RL*$)hYT1|yoI~9<${#m&#<0sl=E6Q@A8;jS zWyD7a0gG|^u3`i=OiaVm-tf4cpCEV*xf$20_`Jl~a4hxgiD}Uc^2+U#Xos`z*IypyN^E5W<)DAB))=vY0238jEN)p8$NugE{UG zf|WJ8j!(A}j5;PxJyowphF7K;B74+#3D_?Ki)M_0OsN8~Aqc{_cRyx5tJz(?+9 zI5enHzF+h0qNn=f-0eKmd%O*vfLjilJFMu~N@;%77th%3_s7Z<1jmGeO>`!VG{2b~ zo?9{Kv{YQ@0>}FBf`#XDbOpdw{8p4Q%ilckoJX%BYV79;L5!pF55IO@rC*yNKuZfj zj0utAjKX1SGVx2M)w7vBI_9bUpBnVPJ3{vXw~;+QYN3%7bO%ji7+oWW8k$^)+M&oj zk{qe_bd{x~weWIWp3k|A+-4~K;X_?90zg$vCJfuUB9Vzy5|Og9PYwwB}R-J*8eqoo|YisEh0H z6v^X}_I2ur^>AHwOV50T2&52d&|YP--)3oT_Rw7f`FRKoxsEIozD)fezUa-EL8Ye_ zY}M>)M}I;sspn=~mW$1nS9I@gZUYSt%<+6d6=EBWgycAe9mEdpOD$0TQw&h(aY*l}G?hdZ{6`$PKmT( zs!i!5CcLH94J|KSFzu*#6UBKSBEM9){vyNrz^OaP!Rz{}82i(~1G1a-k8Ov)BahgJD7oQrJTNSrVN&o(RK7!SXnblfiG8|6MLA#~vk*Sqly-26|`2E~5}k@GSu zA{TrL@8)xp$W>mRHcoSUX6MUE=$xPA&b#}k5KJ~;ri>!2CwkeID^~LAa$cm>!HWBG z5WcAHUJ&b={Mw$%xZ9^A1h~`vHy}y{{R4RG{#_7eX1pdwdUAAkkH-D4^1}iLHS=5q5Vk zydZPKdOCH@tI5TlUg?UY?SprB{o4t>!DKLkI2Em25}|b=eA-3J?jX910>_mp#`{Z# z&kW=J<7-}~#c`c2Xi8Fn&!T^IAr?FM*>vLE>eIPeO#Qe0O<8k>S+WcaEwMWsu|t2- zKF{w3c9a<1JPCY)*wstKFH2{wLIZHB3%BbI4yOypHn&a@KB31r+Z)PadU>af-2mt)a?^QGA@ua1Mn7)3!8uQo(7b5$&88p-bR>7H-;aF;PT^T_T? z7>Nr@;B~xJI++9_su)@nPCUel=B$rIeQ_xXIkTuR6La3q|Kn(Z%;XE}Q(ISP!vM;z!aScm_t_@<~0Ke4MexXM8VSpN)j|-e7~KLXkDd5()gyX!ybhpH-1cB zb=LePAA5RVzqCAM z3H`&oNy^y+@jg}oL4J(97rsDwRWIjZ^$%FzdOGq*M|R5f1m9+t%U)WhQiu| z$Sjrd*vzZZX*;k2q8*6-7shFZ*c*2Sr@UY6GV}sI`nv&z((9b;caoU#WOZ$c#yVO~ zfT|d6$1xo7@Hu97ORzvWOZE zf(>5dL8|BaZ4HIKuDvtV73o3u3@zE1t-s#v;iMu|c6I##bi4t8qN2Fq?TQ!qZau;z zP4@|N&GIj!c0L8KkO@V;7LPG2^%0L^HdWB5jk!p0(GG*?=FaZ9Bjr5rr#1)7Ns*UR zh|?{;dl9}-{WFBckp?}d#mwDE0rOiN(Q#RIl805jOz|OtA@?`t99akIUWXrfkGQVj z_jp}&0k>fpee^n{)FAOA2y$0S70b%JMVrfKEW2ktG*kC5VDeC}@9?!p?bSqSFe6@p zkE!31{$OgADfMZyJoknj@uNo-&q}Z85x*LX#wKe{^F87R?6L?UW8@%E6-&m(RRS7wn zQK1KoD!mh{GrHXXdA z#F%f4Fy4vRlPj5C|9tr?b!oA;?*lIjgXlh*)T?b{QLXf$C$iC?HU}<$epne1?{%-v zY**a|t)G178w;=N?8*|Q)kircxe@ehINm#8!x~WA=O8%YPC@iaioD#$J$#zhQ{h_w zpvdghPsz10?4IeS%b-f|^La!oY;q=!R@mPCi)Ll+GY6o=(YM~GTgSNzuW=krH=mJM zaZdDJF=$1YwdW`8=@wotUbqbSGNC+tXnN#lz2t^ZR$oxyD=_6Dj6vIHj>jJa>MIZ^oU7{F27Sp%uT%^1sP$MFeHxT%>(eF7&h!g z-(&*DaNvF`|Dy$p%9XUO+a~cYd3KAhy5EdHWVBfEWFJe&><5Are{V8Iw4N|Ng^#6p zsx439@HDVCJm9;ELwU*v{Uo+{Kva}A%?x@$LDzCxqdHZ7e~pBfbS!xHZRjO5aY0DC2UiWj~s=0 zYZ|$js;rs6VO3V~D)^j3+GJ@@0{cPfIrk8D+Mq=pMz?vT9Xpyn45|LcRZ5%=AtHOe~7tOh|%GtW51wNnw_K2I|Tw3^B*dr==qZ6 zcJ2?kjx-3D8`sT&nPBwklS9-2HIgj^;rxACsjjNw%207Y;LZD)L~>`biP_ET5U;H( z0tu!G0k#N~f?*hr3`R&#q#}k~?5oXo@2shh^!4rg)z!AdkoBTg!K^N5GQ&uLhmOwS z=9n%#8?duzvvm8TXUgLG*0gk0i|LHqQAEOSgT-zWi!{W@H7`AJn2t}C3)Le7VwVQ(_4J~vp^(v3!PQxrH3xRH5p4yo{WNU z5G4vr;jln=A%Ze}@?DVf{)_%gGlp^D9O>M2D6jvXla`;Bo2#Y2_>CZ-mqH@905%~$ z$dMpI$7!~hmmZmKM;dZ3aPZ4royZ6&H1DaR+Fr%RV`${0AQ3?{@ncJ(XQqK4`nvUz zMKjEisEcU*hVwe8H@T-}ZYZyDM@@?PCJ~Mgf{m+dzn+wN;zs=}G&Q2+ePePpvJ{$dCr&`ZWIh98v#?LiV0P#os@?)4#xBFHs~ z(TkdBe&M&Onh(SFP-WMJL3S{H2im+`Xvd;h4dO*HKLOIRYcZVjYiz=8qo^bcj^%fV zCj}j4ui}ACKjuuQdIhm^TzrNDKK|Rkr~(diY0Mhi#bVMItQqQj1}N2Hn@B*ODCP=8 z#z3q(0R^=(Za`@p{|$WomyqBNvAV2HCn7qEtq4R? zW)-PgMw!I>#~Fpe514eYo64McKwAaWLIn9BQqQS@PNvqo0W0af3Nt-X{0VOAtD0WE zwXamT%V{MSLAvZ;oyiko4NYZg#L0v>6t6|`1gc6EPwZeDGn$Pg3Z7=gXtpkZkr+4! zywK*xGk$q1P+YVV&o1-9!nROn)S{X#w!gcdud>30>WQ-$(2Oa2>jjb57t)j)78Hp^ z1+{cW6Hq%X0`|QhYkr8$iGC0h>INWp5v|*xXrLno?*$EQ;gUV=-*AyCm{cvz{)`4Xy=+Uqv`u=zOC3D$K1CcJs6E$+twO*Fz8(ADrWDV zH+Kmv8en=t;-cdU0?HfqTcfnhWzGt+kMGN@pOmk$4OaT*b8Ec}JV^mC820xrVMGUS zT-`*?1B8G2&2?!ShQwH4b4JPg?+Fa%RKBy(_!zGVa{tn0Q8?BR>{eN@9w^x~Vf=Rg z@D5J@h`qbI;4x1?kxd{-FtTX1HUCaQk;Ia> zDx;@cZmyk|8QeP^qxF0^?RT=xts!=^n}K{a!P-nlthMC}IeE5)c`mKS0-Jd^(C+{2jY`b6n}i zG!HvTTLPQe1#0W?9y*{3&k+O&K?2 z*lz))8NmMySq&WM(;>}sdyY9gP73+y!fP-UXEN&J`zn4z!h?*j`Nt`21@-0!#<-@1 zVNwL@8e`sn2B3IHR&Hd~r)o`Xr0ILdlW^{f9s^r}Fr|E4;xA!)^lu{|V;D9;38Qb< z=Y&do<_zj$Rkkmuk>-yr%<;uCH<`Xp$~#2ye_`1MDrtWS+lKHV*+tbgUFIRj)GXhw zx_#R4E3MHrVxxOZUDn-p@A?!YLRjQ)R)rvBg~P0h^%3Z878!yM$wA)oWK|Ij9@m=H z&VI;KIHP{W?Lfu#W8C64f64r3Ff@v$t01UVIiqv4b!|o!g=s6hm%Ce28_x5neU>Gh zcS5&u)IvY;E+H)GvA{+2=71&KNq)f|U>I#7Y@k@sA zhhh51alqjFFEmb=0S7L~qb+*7v-Z=i?qg-*c;wRKY%pwV^lNM-R>$G%N7 z?}ACY$e{;QPG;aeqJZl!8zT=*?9oCVV2C|$;13%LiFKmi{MO2eKFyE(@OJRLMwjSP zXXYdJkyLYkM_WWF``;giz?L=ehx8lpiDH)UrJ6{BSRcDMSem}{zPcqGw>KfEdFu;v z$;0-CncM}1AA!>*w*-vE(P6<*{M(6mzpGp<|Fy{3R{l$AQKL_Vh+XCNX4ePkg?nn`R( zLfNFtpMJ&{2ZB9LB$P<&tIw#sZ6Z37)F>*wUl>0G+p?IW1v>#w&d}@L5MyM^CZ0Lr zDpSU%W*0#$a+cWq-;m4{r(}VVnlGm&(~%F?!7?$=&XgFE5jEuFDlU@kBX#e(S?CKTvx1lzXu7^41PQ zod16j9#N>-FrhoB9nHXP1W*?T;qq2W)D!ufG_CGF_MZFOt$@J~*`0)Wo@!o6`eTH^ z8+gOGlV}ct2^yD(i7x(!e8Y4Vlk9aPyjRWVn`YyakLwE+4F{yYGK8oi9AGC)j4@;f zud)E-pLS>p38%ujo$8zj3E-r=^#1HfZj`<8|I9AGkz&P$`H6m*xCP-4 zh@DL|2>mW&%$CbY7leK9)f)v@X5Mn+A}dq{+i;v00Z_KV#4YfjLhR4>x*McVu}REE z)6S^AirkPBHhR%C`5xiAa+lhL!5G-3Va`6%8xXrm@7CV_B`EotoD;bB2VKhIep*P-hS5fG5;cs+w<>bSkA6EEks!e zDp~Ge^cSOm`M@WL|{G-&#akhR>p2JmS1kLi>b2xgarnhp6BU-HzxB)2SXj5bXwimt0!t7}VAu zoO>V2y}-raD&?edD7*By1?6Z{!()!!vb*c3ih9szC`=4516;Jdd``ts{by5+Xx6N^ zyd)n%Jy)&b81#5v4OQnsK@&XOs^+N-D}-FizxYQ|V3}QyBjvL09d{K8?g82;Ra+6ZGk9;A-`v^$VW5 zVSOBeUsc`o_0n!r$>^Ho%lWlBAC(^^3gC6xU(16O?PcTBy|VA~GvU%N1%Y~x>l~#X zV#@Q>MSjokCEuMbO;`gv^^i0x2#b2*EktXXEWUhEA2w>3^1h+u>-8~4q6++k6?@mG zi-Yd~{XrHg{*ZlzzUPV&9Juca|ZS>4i#q`e%uBGRHTE3z#B|8K9 zf-%}S(R;Y=4cI=&ylE&?e(6kEc-bFMT;!$f9`07F-OP(Rw`y`z#IlTz8M>k8Hd+r_ zl7V_qJaXYJ^K+CCI^uKn(@h+|hgKc3HlHr98BU8=+?-ygCdugbb9s8?@JkSMA7H1! zRYV^Eu_iK_Sg++L1)f~*k!SOGMdy-R(NlBnV0n6p-hb^t7YrIey`S992RFK7KBkdCRJ*gN1yoqO<&C zQqCmD84m4Ur|MGF2*QBrZ!JwdG{<)a*@V%UZ^1`60MVg7)O=_bc_CBR@J>rvSBGyk)E_HK0_Zo#8k-xdi!GXbFwk12-ymFWK z|4;d?3_^t3>Eo=y4lB>$PIJ^HKaKd0%6&U!Z-LTn%t9dugjf%1L7O-Y3u+dE7lL}bJ7Tt|{~J1|=2kqhtq*-@Sb z%{R`NEwS@H@J$Q>bl|ig_u#80a0c&lmQXaWxf|JyWlH*)j_5DnFFUoB+=_Loa0LXF ze={QlVO$y!iS@`!pajp1FhXF+LOm*kVTER1^7;5+`MaxuBMfqgbbju6^y!)kFDvj0 z@m72h7u5n^JF1uKQII|M=&ZjW4nx$2V2!s;YMnci zY~LJEUN$HUFyT+i$14!xSCXl!m<*T51@-+qkmf^X^xNd@g)1|wNsFEKIl*i@ z&+M@x15wde4Gb9!(yu>|v5%hv||_Nw+DT%5C3;*3La2XIeDGy?8SfGq@N;5&xcS%w?R6?&^z ziW^;6oW8J`=ubtLtBf?#-qlI0Dd_-QPJb^H0%j;f$B8*@z#ANZ!CPh6VH*9 zhvgP?mqvSfjN~nT+45b^ziuJSaE*3?&YS=o<6}xLq5w49@D|jXxsCs*%%IZ95i?6f zDwWLXGZB;XoJ}&#%Svu7U?5i!iQ?~qqc(9%$Z3D{G%LS3`^=jeXt6jU3xD{$H%Iyp zpQ>4bMk55e=mZK+9*+8BZc1=o=_S*Y3vWuJ&2(qc{>v*?6sT9@kB;ki^fN$VGFl}; zl6YzSie8PWqp|gC)5^Ryc=)H1^NpRd4olY`s@T_`a2}>E69Cfme|=p@(OTu^gSzn_ zMKag=Rn|T56$jo}1pc8jeb|!t=*g{*4TY?LQd|fm`9R>W>>#=!m8N$T=aTPi|NK`J zc{JbYWkT99RT(jOC_Vsc#Sbo^praLWO8+InxF>H-&+iUam9esuVz44EWpD zj#n3oPOxD?`6wldlFK`=vb&h@wdBblFWu;ks=-=Ar~LIb@ELOUAqf`2P2!6mO?IhH z(CqD`_w$fRTI#`pFYi8)*v0=B{?7AR+RBB>3DDv8H&#cG3}v=XGrGz5LN)s1Tx>{- z&^Yb&H|OgUEHb7-mW|!-&p`kcW@Qv(L7yIid?wkhzYA};qrdz?{B#?TJJ;VotQ<2~ z*q!lACz3~4!D_v*sgN|X^IwiVIvzv4XE>aCiB4!>87HvWtf0*9yO5Xc6|$>QB@FgU zyV$@+>}Dy7B^e@VKgI-is59z0R_eW=j7E55?ZFaj>W5bpl5@%6*0up ze}AHW3&rwIr`Z92Cb6ssPl<OmO`LJoL%zwW#)qxy1jJzyru*Qayy9J)sW@wd@;#|m)d>xX@fRaV`RF9y z7SOYGY z!q=2Qp2UUJiU%5SVUW)_4Ec<`(17#(Un*K7$C6Uy-`3YVGSX*=(%GP~eXrlv9MZ+C zA{&Yd!lKnkGAq?H)DtZP2_43OLmO`HSnyABER=*altf!IdK;@3< z2qHD=sE=#EIlR2my{cc^{ zK9xmHy96XjD_sheSDd{ zUAjmz^ZCISz2O3V-F@_ckrGl77=t0w%l_2(kIh?Myjd##1qVx~;%68{JMdXEOTLT^EoO;HRL? z8FM)9eRcYPqHi~;RmTv~%h^Yp2#@CyZ!Q}iu6?`n%=kMA`13Ee1kG(k_>JhFjC9Ec zx=T+v2p#%6^;$oKoTnb*J|0|C;GMET2auvfr%~A_P}!~=bFsQ6gXS|p`yLta!q4i z;?i;U_pIpHI3Y8s@IK&?jJdpX_;}&CksV3Ni}O?S$yOg9Db(NHqN3+b%^R1wF5kCe z|0VAX3}O8v=hG)abo9gn+qE~E9p0hR7Z;~ragKPrd-_mvFP}Zy@kn)i5ENl5NuX%a z3VDo+xT=Wkg>}YO`kR`@Zo^Gy0?uxqrF*X351!Q$r~!um%33Qzi9h=eT^vO0Bqpj< zlHc6U#8yKY+3!w`0VPJO{rjaL-sbNei(dxEeR{ozE+_xKlB^k>faMJ?lu^eoYMof8 zv#xJrl!HP(K>Hy^jUiTq*kqw<%}n!#>a(r)rTU(Z%pbpf4-j+FtRhVrOE7sj2de%# zu<_uhDVq^r8C+alPhO{I1&bt@xS+7i4%q7r0j)^{x%VaUe)3H@pGVHX7UQ3Sd8 zC_tbz!lTP0^h}?p@8CS?-HANbE#S{Z4hU;YOj@2}KXQzH7y~HM5%~V_Dkn{Y0yP@Y zzWHNhAD+gmDA=EWhk?}Yyx-?*n#_=N}?#wG|)UV(KdDj2DvG_OP zz@Ho$Jop$sIE~&}98)NXk{^&qJ~e+T##nCfq;ITU5PV7gOV%R^fm8UkK}}@S>%W`N ze;9Y?h1pVvRsi};)<+)6^>QrusCL8}KesD-3V)*GgFeV7GdJr{7tt}dX%T$h|N82c z)@NSe75c7NCK80G19M_kkb9r2Q_Fh1kwJ01=D&R1Bsc;rxUt6H)2Z={vSHI{&RhmKqwcSlA+NB z9(v-*aJyI?x z+}ZBbS>xbwEb}oQZzdwwBy?+#Iqs5#PzNe9;c=oXtwUdoikr1?Te=|XUZAVaBd~@} z3h{+w?)h{pks3SH1lqQX*?iQkNewG9@J{nJ(Klb8{q4gEx{wI`RCtnkz|VI;c%?IQ zko=6+nxl4@ILv#T|KN(&70t8h0Ph6cJ8u!u(ALFVa4=O%l>q5*%3Pi!z6bqayI6QX zz23#tWYfyhmcLDCV+a>C-B6A>7Q5BbbOq6P9pNm1MXZf*f<8@cq|ywtHtJ#ulns~T zENj5rl)9S#?jUVh;5JqE@CkwcD6MBtoW@z<0{E4S@oAC~LM&dEta4XF1MTsb2hJm_ zG3?g-riV4bg$;k^gr^=(x`7I1^kzWd%zuq09Fn`kd0rUK^1Shp^cTDF$qQA6r#D)z zV+k}N4#jbS4lL@4&U&Iyfa4NhFG;5?i@_($DkIe_T5#ztco{z><~oOT4jay^oCoVU z(5K0db{bH8;t{ZVemisiR%A{ak2`{Aqnj(S;#xN@1s3J@=K#Qrjy-Xc4B%#@?)lps@D#m9m$d z#Y1RuPrri~rp)3<_9d87yUV&ZOkny*Vbb)WoA9lNFG}m;>GUyHaTl=4LA8MOHe4M-^6ywh zZ?GYg!zuFS>%;k^E;Xx5-~I14bJv|D^uTGRN%rB2%j9O@r{kW?Ge9r@SCz)zfrBeL3-3NA_r0h#y?CkXL&0nC!lT=n>3oW6+f9Dj>E&%=sks;`ij*O}{c#HgVBnr9h7p`(ReeY@pVc%gwfX0a?k zjQW}sGZKZ8c$<~LWe+qJ3PlJ*lz3VMbl8Iw&8=TZ7D{5o-_KwnuKE-R%zdt9UVJGs zmjQIqjgNS6;SN6}dpG;q@(NYIUc~U)_!`}gkZD@fu=W6K$jn$ zSt^?Y|2v;qOHN#0nCCiux3D{rD1MoNjBd(aKK3nae+X-@qu5#@)aLs8tFm@S6p#D8 z`)sUbCXsDPEC)La+2&Fn+K0zWVEz{Lrg9EIq+Qdx4@)g|W_ii&?2%^Ths@5SOKijS zM|Z=8!pHPwKtJT@qu9~=!u}JnaF!IKJ=5}hfy&7x7hJ!fQE6VL59BJoy7nGrpd^<* z4TT`xLBEs&5A}cWpA4puY@0n=aXp&pve?Gq_z!nT``3uTU2A3sBqy~-X|(-sYNK!c zU#rY&c$M43lC2{cqp&ILSx24l5(0N}r+~j0pm##CWWvWgyv#u9c-^$V5FN6r_e!Pm zx^ML7xEvQyo6LT-KRgbQn#0O$9JUa7huUR**}U&8rDfey*ePfF>V*aVpx+%VC$dmh?tEYF zCIzWSas5i*Hv!_Uyv7mw7JCDGpx9v{FE+zmY$3Gu|Dex+$(`Xr8U^0qj9%&iK5hwL zSWVrub3k9?c^a=bEXE z8Dn@LG8iLx5fuE{)LKik##h!wab<;N{hxZx6Z9Xi6c;;U2jaZ&a{}e?juk@+vXkf# zhBgJiP2fuh! z=f~+EcL{F~T3_v6F{eA3Z%CJka|H++IO*O9a|*=g@|WfI&DB z*lexpe>PnG{L}qse{1&tf8&CR#eX&XMfKra=jfz!5IwTm`!+?R;)^4XYumnRcm*jP z^8v|jOT6%KG3RTaYn1MoxIgyR$hFU?cPSgA(QOv_m_Xnq|L?%E*8#690wCVBQ4b=bg z5wK)N_>q4$vANqHm)_>R7mP(2*x?{7+U5$#{*m$vA@)5b%P-M3mj|R|E^K1rMm$5L zd`0yuhLX>`#=TGy6xRZ56#d%EMrkYYaXxKg^C@O!?0o}uvc z<2=~af_tA09W48JW8o~0YQyt3b=XkbZkq__dSyoCS2;oT*PcBa(uLr&46}GE%OU*S zokJ}HfMs*(Hs}=bxMMwR7ezFkxN(}O?N(XgrT!8jCxo$&;a8J^1qLt`dFe2nvd~8I z@L;gw?B$4Pug4e2MmFD@FGeyY$$m*`%x-TdO4lv|P4rM8MtF+jjdtA%_A9jl6PAX) z*CMnK;st8(`P#2g#cV93xh-(47iL43m( zVi!f;-+-J3G4vJx{R9D4_%*iVa1EtXX`QD46sNG$9>(tH|k;o3U9(U<$y#B z#EjYZoEgxU5Xsvv60u`{Ob=@}Ll2|#lQ zk=+;Eum#g!4?o;Xh|>_Yj^u`gg|$;mH3-Y-?L|Ipxj>KBBqSrNu6q$+~>1bX`+jo6YQd2&int z6y%^l+b5*YX9x{?hv>n~ds5#vfIaniTeX<@%~&{&?{$a>gNKCBRlraOk%D5M`0trqtlcW%t(!$7o~5}2ZlmRPmvnas(p^&0A|a{Lsf0?4 zv?3BB4K4!GASK=1f(p_hAqs+kfD%&bH@p1)*WcCNJUeI3oSAw1d1c)4PTWOp&0G_= z=wFiJ%WJIA_+9v$);zjQ_q$YK53ntOF7!3n1+gkI6@cqStm3^jmbbM(f}5_s@cyVW zTa8nbF}l$fJqmbzG1njwI&@Xhp_|;gs}Wq3?{lY+rrM2{aamni^y%~2JyjLQEFiCc zZoK2Qz;mOvg6-}~^W{u^4#PkPU^N@8W~P=ai@%_RuP(~!688mF`s8$y@k{n>PDD!sN{Wg@-#hsjIrJh z?cuMgr^m-Kh5UB{JAISQ{;?lSF_%9}_HyMV0iEUWF_+LeS~oU*BYZBbb8vj()*^WQ zp@~i`*!8u7lA^wpWE~6S6KWLUi+~0hG67;O2j6Ai@$}-*xN@~b?@H=A>djz?&eO4{ z&q;Vf*+K$9<$u=W7l^gqICT*?Gc>%L`>MRNdr`ZJtv@m9eq)yUAF~C#88Ik z#nFAmB#Q|vN}&1-U_w_H(a}Fo2Y!@y1x{-D54|Vr*yP5R3ToMRR5s0zfkGFNE;+D& ztYC%WLF-lCnl0)y`X!vJzuIDrDMy=y>uTsj61773FAB%b9Vi0{jFXceB7G!Zu$u&U zJj*rY4*0@mv#xntr%2+bP}!Fs!~sML^8iLf(V45*yAbQQifcy{617X6*I(iLlx;mG zXId)`f#l*H=duKL+@tqgW5cm`dSm;BIu%{TU9M!6>#Y{J~16!7TaN4*Jou{P!W8E;al zRdI|_qIv8`QF({Q#C4HV4khkFkjscZl1Qv~u;3<9K~uVQZLqnHD1X8&WQ)(TNP<^; zcvC9i$hWp7S{+EFVES6blj*<+_tFE#Q+KC>SZc~xVg}n@hWSI)Lu=EGU+I@kfWs`J zjV1se9k6L3Abf;{9Qnn(h!RB?FeDRxZE%()^@w95z1wUj^?OvF&sm$j)L^+Fk6B96edZEMZt$;AS#-*ibq(ex>?VX z$_|;l8gxsN|HTOUCa{aqbc+HvD?Bza5@wuaMYYhn$28NoFtjRk#I5}d=vNP?5_&g5e->u0uTHKjRCG1 z+KxwytUTF&`llv2oTRP@+o9wHf|yJPZ;`U26`n#7#oYlFRhaEe{uW}ZE*A$({Uq3IK3?Cm;Ke!28lw*I z_^!rU{=~7VU-~r|^G0uHB+(R{uT(*Z*C-b~RX@0ytsscvL&xvhUcRa+6e|}Q&a|^}Nd0&VJN2Lg z=LKucTbt%_&*+O_o*ff7z-EDyT|^Y+-lTF!Cv7+pS{?zz`S&iH;nCl}pFnnhNstK$ z(_=hyNX8!06p~OqQle;e^78&?9i_|n=j^Oz8lqOGd(UQ~aBfEG1OS!>=9GB;JUD96 z*FCQvSCtf&Ivix!e=rUcZ=WRyP``h+w4%6){RT9OEn=h4!T67|x6=5to^&t2;>K~d zc#ZlRf44iW@Y^;1nmp|b9Z^8!oKFB+z;Mao(I_o&|2bVkEue=?U|TJx9d6t zWMkhM236s@WMe5p@P3opx6Jj=X$)i4a z)%u}~c$N&+0Hr0AOPBy2M-GJlxkf_G$+ttaRQo|tTODD`%c?b9{G|WS{7odI$x;Wf z2s_U#=E;TNzwd_3b=Z&p#hYvVe4DC9Pth;n!PD?{N5Jyuw~P51%tYU^hZ=m3>#&YKWP9@}u6+#@-l$#z%T0O>b=^AFaPId$FN zhMa+idt(w{Ukf7~@EjnPGF7}EE3@DaPVcjj8CKlZFN|t7Y&@>TpKrW~9B+RH%o#BH z8kQBr(&t)_NGSEco!*U83ONZTar!C3ZGPC^RJJ)Dmoe)BcuXXnETa! z)cSex(+1lbPBDGsS(LFMI;4dD)f4}GWjMECd z;5|=wVn%0|vGHkhs;qx&jLT2-ydOGm>odn?K*xSs^o=R!4>M;b7{H{cW|IY?BX|4k zLYw#vY2IxPaT(J~bgRhRl0KA$#tU2CDYb_$Mmd0A3<=C}Mv-#BkvTkcHt(bmzY;Ap zS-5x{@$PM`bovtK!-82Fp2)|_V<2E3vl8?K5X-}*6q97LUhP-D=abf-|3DswgPp#A zO{YPmbqgHx0JcjC`zYphh~yPs!&YRLm1_@{qDqbIzuT{tZU05))3!t}-eQw{HIT!U zGoV!~sR3Z@@s4ljp89>f^$7Em?J+}Ad5asT4WDi%7o&;+6UJVC29cLvhZ@8)of%(L zCvr|rkocBK7f9N^5O6oz*_bNcyGo zk!YV^vyZ~m@^&Vm!@L!O4!jLj8lH`5RSnspnj zi}eCjC>&Fz;M7vky|<`rYbpJ1h4GXcVqkgK_IICVZ)(o_--e*8<-Z0nl=cvPrRe>F zl}B^d{vz__`tOe^t69eKzk?2ED{8j@b?Nhi#xe-O>X%Xq{$SToT=ksZiHz`U zB#ax|C&W&2D7>|=tHZMiuJb7fAer-2o(1kG+-dhJC%UK}KmFFX(I_nX7LSvQ$V0mu z%cd-mVAdb@*5i(WBkDw~U%WePgLCvR%T3Ikl)*7LG3wLLRJM5f>$$AI8GtON34{nl z>WXNJCp2VPeWuphc`oQV9=EGJoXZ34O&?#pb5w83G^4}UzH#d-8#wo_H_?n~+mcoQtW z?#FEhWJ1cjfC-kZB6$xT*(048yNb-%OrM9hzxvo8&Ar0?g3{Z)nT|Mqa1U=?sl zMBt#~%%o_&;b9D)QWQ9D5yh$Yb_sOU@4;?ZOQTcZyi_xGB_di1+&m9vQfxwO)c2~D z+t#|)bD}r<>+&zZ^th_~5^=ey33*Qe{@;)Odj8<^csaxjjv=#}jgA7HYuk z150YS;Wk6ODv7$(){VHQL(`$(Z>oBP(oE{a75c;yq>@oqt|*2$U_GZ%-9y`irASST zO;`dSk?m?rx5}&K^^TFCOgtglU-xFEB&)^1MC>T4JkQtx@aKShXbF=IKx~=Wvr#!| ztJ*M|-?3`!>CYIhPHwdcWoufv)ENGrx(wc75^d3m)fw`OGR78m*}rbp)#l^b)JW$x zH1M%W`uO;&$#2I3x^D;)8?>j22A#H0+t59>a>2WD`>1LqQ-&p3`%wORwI0b=!)EOT zQ2hnqADqiMdKt90YQHWPUv0rfN)5Nmk!@+~Lh;FhIZd}W3yI=Vs6#h32U$1;Pyu;hh5V$UfeZ%Q6>z%3Nj*%zKl_Kzk zY9Yy^u9`ry#IK+5snk*F69$9IMie@sR@Xj$TwilWmNdOS1`-T7Xlhfe>u}T_DQB=(E6ZtP$UtG zRG2VSXs6j?NMu&8U>*??hkf)n;n_P2UgDisrGK!c!|;Ftqya`=d>q~o`NL(224y!? zm$7xRV)84g)xa!I7khim?6Yq}`X{k?fXo}9X%P_I%Y~79FG;0Q@EEG$$$T$!^GPJ4g5?*f82hG*((5g$~uHLw^86$1-Oh$UB^ z9{^=`fYS`kXr>ydDIE}+`SzVgaT?BXKaRhU*=x#tRId1m(W=7CH z+)YjB1Og;Q66qzv&_VBXkNjJML$k1Fj)J{n{>WIO7~QAzuZ!v5jMi?0a@Yj~$;MB5 zND#_fAxwkIh0RThU;aj^a^UCPmhIxas@Tna@oXNE~ zKZxTW#4{)ckk9f|l3!us53mcitfR3-tcyBg4$n7Hc<$$r^25y9NFhp662ef|%6y+w z8?o0RZmQKIdAp_Ev9~Kk9GgA|xOgcSBLM*c!5mbh|G~Eu#4=(nev@D*mhrJV1tE~= zovHd3=V~9{2Q}m0^Mnt93?W9DM=-GagbF8GaL!!ystz7E^nN9V^jWq zYP^CrT2LUCNP?1vgNodgAkwJV(#pZkjPhM}Da9e%6VG13(pB!%qqrDm4z}G8#jjx5eE0K8j+KIjg9jLuLB~*8(QzM%gJ)}l zx8IXah*n?jEGwl6oU!bvTS*MF*yKlg_s#>iVHgcVP?1`bL`oWLbzf1HK4ld;7&|H< z8b-ddIKEhG>zA$)<}-z@1-vNHF*Yy?M^!58Jj&R=HIcq|xcfdZikoxCYgc^ShfAS9 z#{UVyE;xOo5Rc-Qhe%}tuM6R09o=LL|5No1%? zr%)X1HPo7a-jtv1U1o2%>6YV8(U;Nk@%IqF!n=My2S?xygQzJe7IejTtKJy? zv>}(D0)EET-PN2Aem-;5lhGe4X~Uwuwpa6_o4C zA9SZ|nh(|=2A_(AvA(}3AoyCS377?7irl!-zS^s$^09c;PLH32lxDYi0$eg=#iMH( zqDRv_icL<-nTQNnVj)I{)({G@umFZ%0Bvhrk6GCE_NG1Ijp;0s*sBP)6!;3-T>nLv ziOc3st^5WCuxa_1E;E1O`nW>nf$}8tvm1yqsq+%T5-E(Tkkt*H zMS`sGDK4H}epP4Vlm`~b;)yh;0NoRp1j&|^q9~Sk?aIG0z!=8M)eMn$+jjoYcA#!= z4OHBio~!%C);$;Hp7WVQ&(z{8QN{phL=qH2$>R*64;V{hC-plK-|iXR=D(Np&f)2H z!%#=s`_0k|@sE~Y1A3x!^M@f3g8jT%uQ>k83HzdLuTv4?kdyw!N`_|h{z>_L7aD8Q zTJT63MlD#Nml6@!nAvBy8Xcb%`R@6>XM&uOp|#2F-Vgs|8ORy(^ZFvn`Oj;UOVJ%~ z$dCc^%$i7HLv@SDM+LBC zp4Q5*LROmbWAIxG(=8MaZAT_DoZVky{mtCnC_nJIXZYmzoc4~;aBNV{MoKL12^Rn_ z(E+F*aIcFwv1=qS^Bech7`-(#k{lvXWD#!-lQei|K59>=1gI$irkITpP8~me>Y3Lb zsj4D&(hnsQhK%6t*7lq7GnF>6%OP&V@`J!=0ps+d9)s9y;m0 z5c~Vgfy(_+;6^P}aT_!!VWbr91&Ga$c;vs**|+bN5j;ocFf`C!l6v(F8`sHLh%{7S zi2zuLqKQ1vL4rb8^KLmoRe!dEVpr{t3AUfFxfZ@RUB^54dfeGkYXMBOFllah!Vp{M zY;vz6-_vpHmo+si_A?%dMjyRurMF{_(wm#=H{Ai-8@L9SenDj8hmQtt#KR8gVtzOi z@8eC}XPSL6H<_lE&Y-JJo^=T3ArCW(3!Q`9-L4#T^w$a7Fxu}*#lYOO3l!EH$jp`0 z({^9;vRj~=9Lh6BLX14?xzf`2OYPBB0sk~{k(euCgu0qM35Qy0&qiiG%2D$pqM6ji z(8^#WEHP8Lj7&K}cVtI9Lwa$(@`iGAQ#o{Cojh?_Zv63FyCccH=TdlRso{lLThd-_gu_FEJ&XRaz07J-SiN- z-U<)906K&+=tvg+_l+Zd#m|}y7dii;rGqjsSaXFty6eU(W*%4IDhl73B^4rvv2J-` z)BXBE&7^U4{dRqg`oQ`kGE(Z~x2Z~UJe$WSO@9@%M`nVtZOm7vLnk$S zHM|`>;h{_tGy9Z5_1*SslgcWC#Wys^<-3uz87oD@J)s0CBS7ouRg+h0muE(?ZNrV-_d4AJz$xCH$pG|dG%?D z4Y}7x^ZS!G=Ow@=Z=tsclrGf#4iWscz2P5EQdoI@=taK?CcDa5GsJz?Q$`;$N+_H$ z1!(edtf4A(p)8gh}-pCLx zJU;QqxjTNBTl2f!D={tq7MFY`Q_%Zg3$sSJiAa}Z3BeUto$G&QlxRMDSgE#H(LKT6 z*>}i%wdMI-0a1Bb9fjVhZ!W`~nu|PaP@q8ZqfKwJZz;bo5)k`cS?h|x|863BQSo@K z)Avx*CVqKjCBFic>|luW>0rhsKBY!fy??EgU}!4kukYPW|Nh?Ye$>;PJe5yrfE)}B z1o4!xbsQrMMbO-R7ys{KObAh6pk|)4BQhXGuzn_@t6pLqmVXw-X*H-(6TIcvn`okCt}(7ID@<)s@bM`&;I+cIwFuCu_KY`)5r0UwBncvu zyPJ0+Re#JGFb@gYU;8}VlhD>n54@6~bm4``z4*)oS)1{%?eSdboj8=TcwLHxSlZhM zOA4#aUL{>(gA`lIn5aA%7sT>!ox~u%YS~gvHK_!j-W32N?|*LQteHALv+g!{(gNOK zns3~JNU_y{$6pmjkb5L?Vc1k~ObCnwPr_({a6Yki7E zL}LlHuVxjFQCue0Q~l@Thb8DlsM;Zn`w`(K!~FsMNjzZi_&?g%Sh1H#R4@Fm^tAA? z!u5sFY~$be9^9t3?B*U(WBbf4VQsaUY_|OuaU1f5zd+kJjxe`X3CS_Syo?gEffH0{ z`#PGZ8GZS3owP>J0|grWar*e{zeHyg5hvT><8`0}CRw1^zeA+T^_Ft-PdkS5{3NFj zBE|w<-ud-NK$_C(XNvPgN17MFB>;ZpApS2DFf~VJQ`eu|scU@KB7{^tlNX+3{wHvG z(K78g_#v(Z7+xDJAKRqn-_eQ#0F+?D_0<_uL^TuA>s5r1&Nt#zT+_t}FUMA4N!M1_q2505R z9U4ReWR&MeFL4|+JadtOy$U2K!FD)rV;?6c#|RCALx+sYs*y9JrhSjKr0i+a%felw zDZeX03cPj^EVdPqW+6<}$NLo5H3EHqM03!5JZ#a&v98My9OL3{^YJ5N(iE zs6PsI5M#wBf3$MFOY63n#_DsGrfJ->mYHL}05w%PD`W`h7b_%2eS(j7G{}`!{`y#u z>u#bANw+j5&Wo6^@kFX9TZTrOV54-96OACSgJ+8*9D?1Bgu+7+^Wqoe=#3&CjNyHG zyJFv>tk$hUS$4f(*$oIoMhi53{3FfCfN`G*N5m$-*<7o>TU0SA!XYn@T3~RGYKlp( z_Mi=Ti~UC*kHZZI4r9+E8m!wa)cxk2?egZu&${@68+~MBE4AO_RsSRwfpkucL+CYj z4cyJ)-_6XO7WefZ@c(<|oTbY8MCGj$$8(h3N^gLMMYjc_P#PVIVJ|}D^IXD560|A! zpag!vha^@x4uV|r52*?}wUMP++gMIwF%JA+kV-zASfA~XOAEQ3z2EE^sI88 z9_i(kJw@FkcWlze=WK)awEM;vBqn)3Yy$tl^H@F)EgU!ViO5*k*tW6g4e)c2NSSB(ixB%6Gk3Z+uM15H6)1D zy_c>m6h@luTDtz!T4SDwt(n<_K}s5tO@s3Smt2e?d&~RaR8w42tgi)?bC)&lxoOKmUcMgAvF7G9)>N;5Vta%R<-z+#;e+gy1gH(%=4Li4wB1n$7k(ApqHeUAcFmrtt9E8D3 znP(Crr}~!4XM$K8{Tze3UeP_;Vihp=3eGD(iBnl~jPMWf-nHSmH%&=<=y*L1$n zTy#*{rpCZY^KGWXML;EU-U*czE#ueKVsc*%<~~5V56-HPG-=Xs_j~E5cq}d|O>`}B z$%9N@Shv7@8zPUdnlIPhqR`G{QI9j(4i(iuU}3%n>LdG^DYvi5BtpV3m?g@U2anqs z@7=>6O}Z4^`@Rt)iDfc`B_=fiyG4$&EAJ`$W)~0<82U(bql0iXf8;JE1!@TLM`nw4 zLLKina@uR+&_Gvsshk^^?E zoNCnAlkZdrm|OpVjlv{Ac`KmYuLq)}_45|mB% z$K{jo2BU0H7h;NqNGh|x^d$MrJ)OHZY_!?*rS2}phIPj%i+d~6{|dL~2U+`=9Y9YF zUz9`JUGkC%ma1yW_B}#lt%|rV1*`jm7tLN*zQ-yZPD7wL&aLuPSlR%sa*r)&jfg^@ z1wLW-8m|mO_|!+)Sql|9}`xj3SA<1s}rKe&KqC^D|}v zk{825bfU*b((V~&At!^yN$N?DUL7I^dCyIr0dyO%he+u~*oR&Cn~GHAZ$Yuf0-hb* zbUWprEVrsn!_}z$f>wQ`sRZ7yn^#^Y1B^}R00D~P5uA~fo3_og1Gg@Jx$Ome`Xxf8 z*GPjyhj&lX!#PHM1=YYmZ_Hv6#Y3$0@xYjL-IGEzgzhg48A() zWa*$I4Mw1Np_>39hxPQ^XKNvDNgFIbhtL-ZSiz0M{qo9`j0)Uyc1gSl1jD)U{}*;p zg2q4N88rUI(1Kgt>?UEn&qL8F!wutPO);W(#|5{)?mtKv?BDqsNhc08eF)I$IYh4^ z){tsd>ebRs-()i8-h<|!MA3RhsBYUXi$kvw(GaZ+Ej&TdE#Mk_If6?rhk+ROf=pH{kgPj-biu!F7mHWH7a^`&A> zV015m2*=M95cXfr9om`f$ZSf~ly6{oJmjV+_r)ZzX@@rUezNag63Lf4_j`K)i7eb* ztY|{?_1NA-p7xv?@phj0P%7u$`AX(iQ57R!$FqZyMRj|kpc44n|^dXzRW#^WA?qtz>sA=%}l9;{bW z=Zy8H{SonXWG4ccKZAgh1n#(BTrGzrgr+&&bh>;fjmA? z@eKCvV~>mUsy%u-GneUe>45PESz(dB%f#&b(zmV4(cYKjFKRS^Ze;{c4-AXoI;)RG zMiZ0d=jvailVEy4J6%V|NcpS+so6R*(L|rY&iR!N46U9M?$fNm8N@5oesntFsU;N= z78DA;+wrEtYe6P;U?$mFNfzl!g=enA)nl7N&l#vZ7;%36Qf-j5 zy21B&=G~GgXkf%RRj|e&Hre3D3umR1Sdp;tY<3p^Z`k&obZgsUPTv{(-L3G)LCgqd z15>p?Y^vGyOa+!m&B?24GCfR!!HcNvx!4HKj#;I4ccPE2U`Ss<2*r-h7EW7wEdN&_ z(e8$cXlZ_%DTPIYxim#h3op`9)#>v%7Qn(}>_@<@p8p_*99?PejTwB3c zB-i~Q;n0`wOIPLv@UaE$=R#86AqnCdq2n9C6N;Iz~Ug_3Pt7S)7DR<&(lx zO@9(F8V0vI&mf#m=i@hPHlcS+S}m@7?1pR?_=V?V!zV39cwpfW*& z3IaFBS;K-?#{Ad}9;OwZ=XmX_{VS6#})e>Fgr{6xzBR z9_q+2f_su8^QLY~`kT^sJ8R~X>Hd1tc_puI!CKk|j{zT>UH z9iF&VTSizayEv()Mcse(rH1uR)*v%6!blD$54}9sVdV`dN8W1@Do3Ck;B%&Ta7!(| z#HP@6<```9ZYU`S3eWr-EYRF-r5SelSphU)TnT-P5wAh;oMQ*4&T)Z+xno7#DeZN; z^yaTma*qGjJh!@MO*DE0I(9IdfX)YEKRe5hkl~HjS$RYnRwFRFg>xRp8oUF zv7+!27*j$YTD0%zOE9A{Rr@ol@|D~=g=|xTMA?U?RXvLOtfag8v}4X7Kol(!5J;6j zk*lk$_a-M-tJlka%_@-w%N~Be&wXj}j~J5l?%b1q4S-7XT(xF<4#)kL?EFPthHG(S zudns#$o)jOKR2b{TzTeutg-TQ)^r9uHp9#oAD#KJm9=txk(8_lF&iwoXi^k(;SX^& z9d~SoNKB~bkDq}+DF$;CNMUph@r#*I=TJO5j^hdJdGtilSxawq#EG~nw?2J+stS7> zp}@_v2-;rAbpV6A-frzr*@(M@w?u{odZm#_LNI7DE-4R4{f z=z|;gyy+q+gL=df!c1)3m!|gciQHkVSwx!4@ou&b``fbEzVbbrN+JqiA=XJ4k5=IQ zFPohG5wHqbr4beB^Ujr>b8(Z~nl?|3Z*1WGeFs#e`P82SC0)Ce}7L($yh&5 zRd8SS^j%@mF7U3z$aZpTxEzf0qb*l$hS%1-C?Dx!Yu(;3EcWW&H;!`snj~|nl^-!f z&n=5y#Hr&Qgt*ua9_lN60IS8OMs8vHuD*>hR)-b2!R2w6^!3yGT8%oI5n;)>z*Yr; zgSNtOA2mg?-n(l*|lf@&6EmcurWj&Nu)s4{i|M=uE;nHy;$d^ z@zgimG20oDJ&O&#CjV$>Az**nsW7g(fA%pYB(DCAdDI)1!^cc6InW z-5<*iJ8QtoaNbr0>ndpyL1_7Xs_;9Lien969cQ*Xa8aEO z933!GXbd4W%@n^!B1nfH=RkMigM%Y&$ov)l0Ev|Mi`6aQHa^BYfEN|M(m{}#Tph)8 zA4Kzo*LQU4zTh$gDHIsiFeHe`!HYan{$wbuAI)j}!sLC&ytT&O zz&kzng|vf{1acit9Fao=QbKeFi3MBz+A<=gdljyr1ks^{D>*I4)LiXib<1Yhf)oV| zn^#BDu1+}=t(_6h|5MHZKCqAi$=wMax$Q!O4NXgO1P!)8Xt1F>WQYCFU~35fAoS$i zU^~*{B)Yqm_cWca{L5zSyiI0adi;$m`O=~DssB;#igD#_uXn>H!>rgk#}Rn}?CqnuDV5iT z)-4hcX7X6T3VjqIISb@z>uY4zKnb8zz&sJS)`c5nHGwe^BrILa)=#;Dm%dDg2V0h7 z&$?eF1iP4IvAYoIx1x2&wKx6k^DATvrNV(Vl5j(7^;(d9KR0?8>dY!+v{Bw~Uk15{I=C zYF-wuZYiBDnQMPRNDJVDX-kyoIQe4>!uMF^*_zT>wo|MhY){RH=`@GV68csT7_6i_ z1b~VrCLt7e91e@hn^B5l_r5eWbflV_zwBV7I^oZtbS2mbOY<^p-hk{fnH}iVRS-b2<3ePr+LtVfevPn~Yym#a zQ7^9*jI8&rJ~4fG_xX(i<4{g;ifJbh3Xw0^u4xR-gx3ds_A=OwZ0D;Dy1u?|WIudq zAyW956A7MHV%RIm(LubIH4&L)$Y_5hCNgVW;gMVJ=K5>>+|^&0fTEd`F|6YihRO{K zB}AsHlj!tP-4<60$P}y!mCM@FTfNE8DfLNnOHWy?$PUn83XaisU-rO;_L8@Sx@Yq< zyC0HkS(8_TUR=ZXC(*CI-aFX%4HRR#zNkQCsff{zP|Ru0C%)z;DIWI%@4EP!3%s>4 zt)v83ZYVzmS;H7=94a@6tt9-&r)~bc(JGv4blLiW*sEuZ{t0IUbd8@hq?Dc3!Lc`- zDYqF!)?7R^wY_b~cE9;g(D+Nm=CbnrF!8F?YtkP%MSst3fV&15iG$A$zg5RHYkpj- zuu+g9gJz-DM;pTJ5izmHf#&`tZVzAUg8JrjvNcLVIBu)%Hz&#VJN+D#`1oyM3_>2w zlkXS$yb@|#3nd@iP6NaL5z{<^*se_ZwMU#3zA6zlf^t&PZIlGfdiTxT1Xo#J8&OK< z0$B~_0em(!L{4^OugfimqW* z+&*zxffvm=G-)`0fJcUU4hfX`j{ z>A6xNa$fGcU+NFe0@Tn}B&Vt5*@2!S$H)sqWk1_C;_F$)fDluimIILs4;zkb0}zEQ zRMQd9>zRKfre$zF&-Up~3QVkU%fbVU9O!0%2yFJ|$j{iie@P+*-ET-af6Jtgs%42H zHl7wzwo8_~pEb_o243a>5=>S+A6yaqW)SqV}qUb##`0HD{=@3^B^LdUQdCqk#@l-jL$Ej1dzRP@cCkPIl0F=e(o<9%O zpG2-AnN*^>F7v;1tGztcY{=*yJuY2**r_6DlyLUCV*o@1o_p1a4dGYW9Wt%@XD?d+ zo+Q-l*+yuewx1IYI3)J46`Aa|Q1?Q3GIEcg6@PbF%LCgvDx5M0pv2Iz?;~>pto%KR zFV!a3x2Zr3|7cK!OMx-o!q|oPu92Bj9D1L6cE7n6|7gr5LHavhPSCq`yQ!kGvk1`j z<3ENR+ILW0J;wf?zAkeZVMyJ9!V8kPb@j(q!RxOHy(m{QV?h?uJn)AX+6c^O^AG8r zu{mi~%BdFpG8MZrh$ll(*X5E$R)>gcbw~A>E#fxMxhu#Kmd-<0(Ao<0bcnzp6ar^S z<mowLHePf5_o}>Kx$MOV$5oxE2&5_cTXI*zzUeJMfDiRo5 zL12+i;73X@?|6L+ASwFIJ>B&<*i5!JQ?)fPSR~s0^IY=-l767PiV1l6>O+ zY9+kQHu=u8?~oUieHM9x8tWvspMPn!JNUK&O#bV&V+yg-^eirZM4a4`5>HAcgKl@! zvTJ^zMy=);M_=#zcIz|P`p@Ef0aN%$-) zWE`l-z(RdiX1GfRae6vwMjK@AoK;QeZCQlX-o^?Q^E^e$*Eb~m$OA&t=bzt-Iah-yeN0FeZxUh+w=N=^>IpilxtPa} zL>`Q2>$g}n8k_RP=zjN-DNX`1vKY~gQwXufWZ!3_`7L#;;!^^&6%vlcy$Q=iur+l1 zCYDX^%3lNxnAQad+DDy{J|Bms+U||LWV2edo}Hc!rrKyJRgE}F`sM{%d{Q+)948D% zWy32Ly8`YwKL?ds<6E+GR$gzvSkd?%42=lSX=DVAx+H{OaJBl505s&p=o9&m!(p zgrBbz0y3$uDiona&>oi%^`GuRXJmzptj|lo*J$Z6m2!w)&s8j^x>t)$Wkw7PFrn6W z5cy~)YwsE7Zx&Zo9G$eIM(diiK+8Js&ZK9RW@KcF3ZNdNTR21H(<`5^k1^ZlNNWVP zg=_9urWjRbX-t`#jx&VbSW{O7k5}0h;I^iDPZ~fNs;c)Raz3T02iK*SBa28{tAbfcqR6 zWdvIvj@s)P=~?*B|Eylz#AU0N6!x-&~~cZyeq4F!C zze-DoE`ID-i&L0|(Lr2!Byv~}I2WK(B0I@N;Tf4LCL-dLE#OoB!|;6Whvuf_;ni}v z>95a8?Jof0-d*@1f3SFGkpx}eO}2aXROxl{J3uz_$QKrf!n zP!A>73HbG;3A^&q-uI94JsdKZ*0Q1sk#X2he<=Mcy;IEP1bCmJGh|7s;jnmH$c$Io z?^M)q{2J?5guDGp=u~cTY!@;r0=*Qd?rAYHpQ4!1f`o+4Ly7pUK*8(9yEGRli+_Yk zOuJ*h;AL|AzAr`1E(7pV=rP4^4Gx-2(S#YEp6KXg*|HOZ0aGYsVf%TQ z{nGdt`K5V#PWSbDnmVZ(Sv8yK8$K-pw@!95NyddUzyoY3^5`K4FJg4pb@4`L(*glu zxN*bY{7<6VntncKm9Q8F`kJdo2&qe0AO&qQO2Cv50;I(Pvj$Q)6ZW(}VYsHY|JAkc zcLn1O$|Z}i z4|}(tE9DcV#8z!Os0y;DF}FE&8N`Y(eww&P)=d29<<0jNH@(xZH3`0&FDe$_KUD2G zB`g7+lrUz(hz@M(uJv22$~JKDBnaMeT`~%Dl1=3&yOJyv6A&d&O%C*V&jXvxXj4!= zvZM?7oH)tbLNbeQ>(s7zrtKMF3u!2IcI%P#lqJ}4g&_hiDu`6XbGV=|zW>Idtggm< zPx0j~B8NLs7pL`-b?&&+{j~$_l$f&*&~A6t{rMW2q%Y5Yujl<#n$IL%yJF7w{IiYb zRxZt&M<^a3z`+rKYk(H1I^18nXzfd#KMi^+@6%_x2q7;x`MM(5MX+!L@bM6=(2So! zUK?RvKndN03v!e)@hbL?zL#=$&CH5ubZ32;%4quAw;%N<|Mp|0g8_r{?#}p1a6Z?m zWj6v5MxpODe!PFv!ANl=mtu^=U@Sg@r^TG`6za}P4r)b`9=&Zd4pny}M{ zeR}~vIY4Pc=)*62lp}91+#9ggZ1l>1x}u*=_{3{k%sOQ;_JrpZA<*DMkPE{L5j*Ef zq<>|;x958W&ue~15`rj_xrA?6@}faA#?K2sXi1%lg3@pBLPF5y6h;R8`sALQ$Q8VU zO4uGYXVB9K%Kh2nNg&HmqJEs8f(vW1(FyxZYj6S~qw$k->w6bnGlhIf`foQ$9@4Q8 zdZ%VlgAIlFj2s}{f@$h53D+-_oBEmwE3Ko;HN6?qsios#>c3KDFR|J*|0Yg)gN(vrGccfyYf)`2v8-D!pEsf`#9o*|Lt^WC$@v;v84UN77_98e+gn46`tw0=X z_NxKCPdGhrK9O8^+yY+5x-NeHM_Zt+*xn;*uZb7i(CJOk6K-~M7)0>F)4+^2jAEB> z#s2g&IicH7(5K5~*f;F>&VF$_r~ZO33jqUJHdur7N+_0p5Sb8d^f`{iM|08fK_KZ2 zkyG%gem0UHsO>QDCi%c3>cIb0Q*BUKcfO4XQ@@UD^;FdXY+d@+yiVcD3)> zLacQIcQY**syffFBp-$2zHlEaJ;OiAe;c9=j_(n94Q|vcQNA&{Cgw(-%v<>nbO$o0 zB6);ibnTTawV#HqSk^{W93#bhm#~{zub{vENhr zRIJ%RfYoK5e7oH1)W&*#0$d8gh;0&R=_9K7M`WUKr(0wWC4>6E{ltzFr>@VxitrcR zZ5_IpafGO1c1%X^{t8H+0@)+;(3Z6r3w%gT*5@Fh-`*$U(`rV8G&AmzkE6sLi;`HQ z&p2dRy@)_$Foyh-_z%R^MLnWhziat*E_zqv(_%twHvVUeWE8BhZqN5XJ}P!hmNY*EFRDE*ZYorU61 zBSP)vr=!x!6}*9~&V_r9*Sf9%5~s!Jsz_nzR{zVwxBli)cp2n+j2 zo%Cc$;TlaYP~}5=bCKASq)vpPshyX2boLnMbeo+M!b0WW3q-XNpe_rH9QNfB{-gpp z(F#J@7a5>xa*9MAECdICf3~r+qkV)beArLPv`(D)g0z>%y05=G8;Irr92+=azC<_& zd>Rt!*FwgB5~{y!;`B6znKeJ$RC&mCYoO{37mw8jV0*)wdTtzuBz%|en&~CerNyjt z-(^#iCDU=>q9%^@@`AGKpC{Z!fE!j^Bl%)UB?v=5FxQ;CjETIZDDmZc)TMh9+|<-p zB3CT+|Hv?{J_rG6G8pa+91l3^g^$Jg+J2S>q~zFdbJUgPO8@DDJLC#eUY>Gnw@t@^ zn+Vz|iFP28s|q?$(HBIdZKr+x{#N}~6!mua3eP=4&LqdJ=O!pXj3M`eL3ji&#dM{> zgLDp8?bLh4izZJ_R0tfYgv(r+rg9YGrVJ2XT8{T& zHKE=rk2ic)xyG7R%_GVAGKFbreMyqO2ad#G{s*Qcf_4I81(u~dXa!4?zeZ%my1Vf9 zO7rT?RgTQI@3=0+G`*bz43+2){eOhLRX|nE`>?$i-QC^YAzdO;(y63$3P=mmNT)PX z64Hnwjfet*N~d&(AV?}9ytDB6pL_@3@BG^Lnl)?o%-w?^1o?ox+OB__MZDc_ajv=C z|G@c4@!jjS&z*y2d3lD`i$|N#1JLFe?mvTHqc9$Q!F#!kTl^BKH`+o!YtS+6>@Jri zMvkU!MceUUhC_NHL~I0sE0?k`vcMp25j%I?)>A8eNWFZ$^l^LOZu;1-X;MWgxoqgK z^0X3!b9|#AQLKSkk?#KW?bv`{T^g0I*e08@;72j{rxM&4iS0@9&6&ek1dbr91UxHP za6OzNO6Q=AB7zUk4KrF^>m}iw{9KOJ8cn?CHAjN?kG>2y_c}vH?v?&mw~wK9^P9U* zP%u65D6v95XnPBN2-3@VQ~5H~$j>zU>P?_CX~W>Gxf+1`J)Z+=b+1ous?HOOtA^?7Sx+O z>mF?(eD5unQf%^g`6Cn@cas=~U}uaDF+%e1k@<#eYs*tq-t~ClVtt&$q)9vjE$5dn zPO&aO#4bdGnS~6VZ_JQMsq)2!idww*y1h>~_7CqsBCZB@rN|6@0Z;WTByWU(KyhOh z#w!4uK^O!fCgjiE=cNlO4DZ%04k(j}#-RH|rOvDk+Z{kruE6Wh0$iU6>#{{`9jc>h zo99`huN3@3N|=f-WF!d0&S<3t<1zyfogA#5Hx2kM;46?iI52tqfQb|V3?)`zn*9b5 zwE$q6X@P3Bum2ZOi`X6Bjr|u1<;e5E^2TT$c4$IcbpQ5!or|mf37$*uaLfmAP)PH+p`^xDiIkw zDEawKaywopFdO8I#U>0RefPflKKiKo)8;DrDXJQQVr|LJLD^0^H{uvv;dYbeeE47F z?bXdCZoc3t?jg2O${xRo7jaM})MvO-zU8+OqfgH9Jgw0zY@uL*a3jE(#0E;aFuXSD z?{r=?un7)PSI=4dCUHzpsA|5V@hD+Yj93&Pg5F@jx#Wc_U^tiC8|$8os9C&qm%p$L zq8{0L6G&sCy-{h^$2o0BM~Je)MkrK?A`JKAtVBUw2XR0FC-4lP;RYt3`A}E7@;foP z1j)h?--zCRWI`r#^S*6lOJ@Kn8xnezgWqDnjzs_YX?=5?Y45499`U`ggwKIHEY57r z*WLoQN$uZsu_1buf4(_%S^z(hA3-cM%D9#n5+#prmgyuD-rxMX?p|6R)qKLF@dnDX z0md4$4IqR3GPP)qD@1~{>j^W1%ir+!CdJrza^c4(ZAvMpM?wcSAl2xm14X3d=VSGr zoTnWYEZcsgbt$J-G<)WOqut{dVoH2Z&Y)`ko2JSrbP(vt{%oO(vAoZC`r;0acQboJ z>ib7|n0Hyfa4U2`&#%V5L%%^LJRjKD$QjF`qj9`g{~8B7xds$Gmw&HW^D;DiF%L}} zdok3`Afq7;k_!KqcFC3r#v4=1aXUl)T}ATm)wq%;4q{_xYv0rG(7K4UnF2(ey&xb$?ldd#pyG@0n^xoyC*org;^q~}*WXR3SmN#+b%)rnZVDS9bHFA!J#F<0 zDq{W-yq+)Xb52S)GNISEKG*r@cG;7+hs%&W@y!khf#@kBxq=*jx3v3sWF3NvVIGvczSMrcEs60eN8fBq zQ~v$`B(Ok)at|4>5q6 z<}5A_K&E#gsy~Y z4pM$RU!k>8VmPyvV|8YQ$^&owt2nSPs$B55siQk-T>&nZ<~2)YEp7H*?$IXuki3pR zXUE&$5OylXoO&SukKTq@DapC0&#&O4+#$p;j;)c z-Wt)HSyFYKdpfk=(?x zPr#B`^gf$7-gat+20lcIDV0(5nqf^D z3%tRB*palkPTdM}%#WYyRxkC4*|1YaaNDE0QOFpyv7lQ_5F-sZm1u!7huC&g{Sm<) z@3&C)Ks(t;GjsIy)rI@F$5ioK%P|IWxaU7t|Sz_hdNNq zAh&7II~PPaY7@Um{bXL|ekB*l7n@F<*|#VVi#c?2Ujx%6n5X^d(r#^Pl5o-FtJWo~ z`Mg&@8_-@XJCgi*Nz~l}uF@240;UpoB_NL-=1!9e$?i@{e3qCLN3Glq7(=?Oxt04c zC89=md=lDfgm*GHX7#ryRmo3=6*?IGcAsLoGX4FXeczgRlMyosY@9#d6RlJ(j3@9<*l5#!`Tx{%H?kJ|7(RK3pYJy0UWR-+JRw`_u+(A)p18qWh;1D!P zjm$+FzM1$hzG2+npeM1f3GNPj{I>X{yD@xw?&k>$eC}r@)ETmr(<92qJVLa(C+-F_Z<-MklB~Djl{h9Lk6;jzhY)JO$#==3 zc@3$gyJfsk+v06y&6p(p-uXIrV8SKv8hJLywg$?h!iBH(K=J~k;ZU+48fZ`o$J{2X zT&8nGd)~j+>L@17=TIp%UZoZdSzyVOWl@216v6e@i(vg?q3AtBKKA?ER5NVy1@)G_ zhP!*2iKx-evItoU)EdTBgn`gkv@AX#S!6-~rvi=;W@t#g_@G!-kle2+bt>Bs4?J~V zt|yai&<4n<&jo)7GFYb*w<}0{SwbL%K8xRDob)qhdsz3h@M!1Jwgkx_qrD0$@wq$(*wRlunJ{lo^~sX zAGR+Pnwmq};$(Y5#&@R|FDeL<)=^P6QMZr-mlO|-#1)~?!JD*n64+qA8$rI@A{x)t zFwKKwr@mh0ypob|$@gmzlj95jlO+~Jru08WIz9UnX#DXBC5!tPc!IjIITK^er+|jL zo>*2q6`wK$pE;(?Z0qyBU{AsKkcTW^f(}5OzX7TFphjoRkA=OS^Fv3+<#$atylRGB zi+tsB>)n-KNo-IF^Gyagaw8avmQXv@ST5Zy1&5&9LV<|zhfHZ`OYZ02#s>zbjO-K< zwXCRBH=5}steIA`qVh1_MKN5b%}o}FL}A7FllC4pIEUZp9zsEve>}@qvAM(wrtJj^G!@O|=0pRU{$wf*2pq9{i9$zUFBNM+dz;`sHi z1c?H+eT;2}S<_T9-^~=Jxf|Phx_JgDPPTItPnW7eu^Ww2(25~#S{9QIAnz}iNGnnO z_P^IX6~;BGLM-3e-*eadT4l12UvGVP40@{xPFP0pUq)Cpt#}fxyZ=OIX5pea&=?-c z4*ARKf^jG}({XZ;_Y9#W!HNuT0vZxv6Tn5my2Z9zll=|LZnw-uiBULAg-^;bDU9=jvdxZ+l~Cv@)eFD((P1iWUf{hg2B{Dltg z?i^Hh7RkDK(YqzL!0QAmL(>UvJ<8itpT43@R$WgD7fsy@>0pxwX^uu z<4GWNEs(4MAMlJIM-VYb|Mcvcp>wr@Ms~`REho`etImvV9?ZR$Zf{i(X$T4tR%&?U zWNb5dDBRt&m07&SU^o?0=s~&8%5Gb3?>P(%g*;39W;hkD)$3XUV!0W+n z0R_2)0b_v|7-AN{5L*Q|u8D(<{Q3V~nO&1Pm>>NwPIg%#YhL6&UE>+qBigvKiu84O zZ*3(AEoF)qkE*V&{Q{C%hvQ_0WUwQ(lALzpW9X2%3x-fTBCe$^S;&}Pwubb_`G8Y_ z_Id_%6%Ovw28PcxV5@(=ZVBGKO;U^Zf&cZEg{pL@Bw;HOjz#;bTTJ?TEVK`M%4p!t zu7+Lr>gV~{W!^nG(`}ARQX+VLes6r#>YxqE4M5nW$+0O#Sb~9jIs@ zc5G8P1GE#T^!7FK6)*0m$E&s)*+?H*``jPylRQGaqV{0<^#c<51;^Pafc=c|Q4u%z zOCoA;hbo8a!=|Vu#{7f|Wh0r*;Ue<;`_{Mb zA1=Iu)QS<5f*%M1!M|#Dp?}o35czl4C$G|qpA%y&Og~3sb=@U3I7l>+Q=@c&;- zbBq7K!YtPznc^%ye=wr`-xs*SLcGJOO0Rh?)-Fk(-aVOj`Sw$PKBip8mWvr01C8&p zIN`LgBPt`xgT-m#M_8MK?nQ*e^U99J*e0Pe7r&yZJ<{DMGAbZsU*}GWWqu98(Y+(<=!WeUAZrh z*tjdG792+|ps6AFlaK%>83OCKWe$mIlMY2;zDPBW6~)6I>MhyPyref13ttkRr6L+w z{wY;&fG6&zQf+q~^a2oQ0zbtTD`d{6K2(t@HE;VIxX0{{MJKCqM-Qvlz(F_WY7?Q% z{4Z}uiTNgP2V)ng!GZ`dKX^Jr-|#B4bPXHmzhW}1_s=K|Bv?g`QPS^Be_B;eg#_#< zI|~t5i~uDq(qMUE?`#^I@y6nQLw$JkxBAyC!;a*rakr*k>-_+29l)C)kU)VU`5gu$ zPX#~3+TgM7TkY_Y7tCKgJMrFr$0P}ET%EZOQKi8FXS|<4DCO7Ej?~-1Jv_a!i{bbJ zM$cDzbqYu8d3wfLjwGhEG2|WiW1J;AKk_V@`BG1=I7xp*M7k=Rq**ZFZnCh4HIOsHkqDWw=NW1`L zGG%2We$P>&Cn{ii(V5ieBe*1}icu1zr^k)nw&Mw{f>uYuDCn5rwxho+h>2^RW^TLt zq{FfnWr2>DXNF1Z{TEk!rqUa=lL$ytP9`;r9_RoVY~)e4>P|_@Ce|?_pTDB})(0DD zTgT_0Qz;XNB-#~1zfmY{!A=kaP%fv=FFz;u%yF}!kWH@IMN#sEC6RW8-xZ@r&-ctS zpvh+VwTOTt1;P8=uFOl~1EU5eMV{%qH~PO({^syZV)aMRE8&0P_d%qQ0h65Tzk5Bs zfo%SC$3yeyiUM4dn-^$Z>)gAg7Wp7KKCwHFum>yS%6S(#M*n*Y^Z+!72VSp7A7R~w4^d_fOF0ile1z!%){E6A7 zS_RsyPiNwZ2s4ELUnvw^I3|Ipj#LReC>|5p(fdwbcv2&N>-w9^Ut9-YcLOKBCy*=E zja($)r9nu=e-?q18G^Qr?FF;HhCQ-2#} za9rkf7GEFuq3mz8(K`zZqYUNQ9(1*ybzNCPr+fx(G&L`)!)oaS5wCgwt^ZoyoAoa? z!KaMK+5w}JpWl)n`d0Yh=qmMAs$q~mx@xGS1rmaBt^KsI1#Hr`fR0cm*Ogw(KMo6;cV zFKXdZn;FYhXwr+Yrb#SW z1m^d;AV)bMmA(^@CN^&Ra|PdC6Q(w-1Y;;^h{RYMmlfa2&k1ocpsde>%56bo24*ND z#H_X^obp`~@xtDKKi8>qNMQ4IW@g}7!BeOLGYeG%au8}j&w}mDhj$G0%w_iUQWUMe z=2x@C>5KK}Ms}v&7Oq)-_ft~D+wmaoxSJ)4`xdYcXxm-tZ3WUa@$I=RnAZz(PrryzbetbMUktW&4zb$X3KRHT|sEGG1<6@i%o>~x}YAhMMC2RgBNu8U--R*jVX z4w*N{DcYY29xVJt^iP~LkOiML0tFw%mLd8nf1S2p>lI`7<{1)OZuQi`OVgdHJ&E2@ zzrJ^5#OY8$00eGRWzRCY+D{$~9V763LW;Y}~M70-*U&|o!kUbCFj z?GvLVcB)ajN-< z`{f-CdgIGpD6H+qcR;KOcCfOg)4Ux9wh>Kbj!bVgTuQ#I&Lxz4&zcvlT9mANToD#B zrQtVQpA0HiQ36UrlT0y!yJ$T6)ms!S$64A0dEM{xdHIQg2UUm0E(>>@*}V4cPOa|% zefK{jgBb3oiNY`lda?0g!PkkZzE*IGm3F*c#8_uzNqz^Hg14CWLTZHQYNQ&Xrl|R>kKRm=`kp5Q*ST z3nK&_9vMz_zXQX&0y(3%7Pj1K!}!^dx0ds?iD*6Xu8addEtMA(`uv~Y2(J~4VSu^= z8vO9&{{wi9IRVM6n5&qN%c)RT ztERM5_@a7J+)LdMT&`w$$UHTKdA>JvP)#Oljk{wM5Z+V9BY4VX_>rQRl< zymOyYn}XzoG7vW%P*=CQ=?xXwB2(>ycWbLR$iu%EusohQgZ7XSXV8xQCY#^#+*h|Gasw-Kfd;V{#jMv=86ch@f}? zSPr|Axhm;MRtM_&4LYv8{`<{14MAKae>i(in(~&TpawBGSic8IPW=oa?x{3j+@VWTR%95fit1v zx?cT+JQ!lTX&e^}NTI*+r0Ra6=0pN_(vXBbI)m{^%#KoCTzn-o^;VtPi7P6=SM)3~16Ph2H;Fc3pB#eL zfz6gh2D?i1=Gcoby=vGe2V&$?HS5(>t=;fy-H3X`bCENSkB^|VIIu0T!>5t)v5%zo z;T>mtc^bRdtewSdw`=g(b`s;i2)PD_SnNUsH@C9^hcAZto5$=N>faCgYXTKB=A}Akf-vtQdC`{e}J~)JEETbQLiJN%o!2oBXR<2 zt8ENO2pKk_DPIHBsxDk%Si&){Ne1h=+df`pD;9CIMb3CqZe(n{s6h!7Uk;+0T(C)G zC!#P+qu^w$EkVtK#SoqaeV2;5AfB>&P{XreL6r-!yTU23Sg_vW8qd{fHI+l3#eeBO z%pw1`L6CUMfcSRd3*o~jyYb3UuPyw1=Fb3qd|Y(R{GoYomf$__U2#>eMkQYvQyMpM zbq(6OorBoqp#LHnE<)lfVV1SHURrUlSZQe zYEXVJqqdOU?RQ)~KS^xzv0S#atz)!J9~VR*&RCHUG5sjNK?nHIeiY7|stOkdkIBs>+YEFXnE4fMAqQG+Lv){SZY720Lk5{7uA{;f24<4TBJUyx zyl+s#l>M&I_GE6pSN*w1BjhcF4`mGlkwdtt5@`9z;(4*`;(yRTd44b@ed^1-8!wJJ z%;;?G4qe7Tl(t#yPeV~1#I8K;8hasz7-Uv#OEbK8L_0P%buN0yyTDAvOks&-^ z@O|1ae+lcbZ#oDiozO~xcwrpKEnt5S$aAv;cF&XahaVX@2JNkURZMjVE7?*%_GTKI zx8Nx*ZmNKjBPd^vX^ zt`_j7T|<~x>7iW5Z@LoABQtbQUwFxG9Sipwp^gppI{eNPfs$$=Tv%BET|j}Zp3_XT zvBhTcW#(#}&y8Ik_sb4HMPK1Zuf)@2o-!GTs0oAvxR+6)Q9xTVCU3F9%DE){e!htV zZ;y&>l!(Dq)~Q|IEc*rM716(DV^9JZFKXG}63hW~vchLq&s|uaH8M;stM#OL-qw?- z@V@X*gSL^uIY#*tkl2GYht>x>0%~G0=LQzW^=9tRG-s|VlCV!>tKQPgL6$e2Iy3?kkRpMMqQg8B-x@4G6PFSAGWYoQmEe2V%?TMr|D{C<8I{Q z)&N%dRq?Qh{oUc`LziW4G_HWujeFy0UH7QfGBZbY=TLq0FWG**BbMvbrQraMQo2U{oDS4UQrKf~iX~`hnJ_4}H(0R@{X9oVdCn zV&41J)?WhMvumYfv_0AQA>P58L~aC0=v;`IY$jc*v{}ABS7S>RxgLLL(SD%$y&dWh zc{>7R*|*TXkSKCiDHyBc6}KN1vVu~eVF0UJ#9K!1D4waUwF9S^1}7f#57`K`hxdyA0=zl+ic=V+%oO8kQ30B5lLS$04P6~t2dZv=#07}4$)nEkwm zM!u7*bT*g#v56?%Z$g3|g)mh!Oul#_aR;J~|Ce@-2dC3pLPig^E0{J`8%le6j=U8d z>-BMNk!gh;hecT8NN>{x+}IzKdGgTXz08-Y&+x;daQp?6(FSP%cA z5M6?94nlDFDDgsTLA?T(zdD^znq2kM()Z6Z^iQ_KTLb$Kq(5H2hYBVjX^@0N3W5K2 zMsR$vsrJxc7l)z4!Nmswr(1;6Qs1H`H1cVBdhEX-%Kqz_R`RcB+C9)S4Z$C}A6-dU zl_7l?gqe>r@aD-zZPq2ZmV?>Rk6XaTt!1cj1#lLB6*vM3<+T`rcr(LZ$ zX>yphkY*JoQQby8^sW*qI@@~%T4B5~WKobAAPmznpwXWI8?Fx&WZVPSusMUs8yeU( zp~7u7kEnkskk`$9XJ^)TaXOcZD_L4C##c}X(rdi9jWtn;Nh~omG@wPQ|56}n^uUC4 zy^-a^t2%d>$UK9@6P_-O|E}s!k|zF1EJQtCRA~pHk=&$~A;AiMzmMdvXX{EnMT=@U zwn@1MlGjyQjh+uY)3dy8jV7N$KVZv<9u7}@S!>a-*yTYgK@SMVv{U_MU*bcse)JH1 zCfJJFGROe>qx|n`GFTZM78IgCUqXKrl@lH^U#d6q>}d~bmcH%I6Yp3@J%(*40u>j& z@&jxuh`DjTq>c4fzI%<1*aM~;?pSVkZNJ$l$E%^!bu_m-2m$W@nws$ams;672QmTp z;Sk%psQY4k1|ncFgXGzE1uq`U-po*LE$L~;_@S;%U^H}I44T^3@v36u3zXMR^9;^8up5+Qn+zJ7*4Pg`puQO(Q|K9y@=P$=@BE9q0c9 zZE?b0rE(M;@S=a|zVg(^KK*g+aw)XS&@kIHv3iUyk*hO~9bu9lN{N`1fNeWaLNE@; z=^HM?YS7a+bDxnvtRourzJ#$$1)NW# zm_?SjBRHH?8`-b%+L8)tGnS9^yfpfvlgP#Q{9ds0nEPWKMn;#c+^WW z;+m^mxl?SBe$!zE?4coK z6HQ33?#tMSlvZ|WB|#-1O&=B~jtTMf6N{Gq(4=r4zT;o{d1kr214-)Cl2Ov}_-_X+ zjxb$-km24#Pp{i9Zq}fIJ7-0?wZdPSy0j*h&pbaLn6M!wv3Q;Q!VObGSvwbdWn{nX zi-N;&7yJMkAVGp^lgkWp3FW5Ok;T@Yvd)iTlDgp!X})s&PFVhq8n4=DU=|ad;VTL1 zgJg86g_EA|Zx~0cn?l64X)Q-wZfV-53i{(<)Hc=s+NJ|sKM5*V^46^-!!Fc+HM;!T(4 z$v64*2i>nVaup@IB>U|_h42`mK6TcR2wlK+!5mH0mNU<>v)v-UaLP3(O3pc?YZdS5F>hywwWSj>SglOU%OzvqqHw*hRLycwN6Gpn?PnLe)Eoq3k zzSY3QLR>j%Aq_}-M}n#!9W;FQawR&*fsLlNmLyY&?tzY5>{e<^Ru~`Gd38fJ5rTk0 z!9&I~2b8kh zCZq!>U8*yv+}JD7@HD<}3_iEg`fss2)ZzSWfUASwm^5=fLZ16gsQ}dV;?-5`^0J9U z@~7%+#wgo27b{_L&VZ|dxkNEOoa^?vPrZDRiRSw0ztU<0iKxAL0_`@jNYBS@FacKu zbIwdn#uTDq$I0ruI~l zb`Ef*FsF$7lOVZ#<=BwVKia%sTq-5rg3HS%p*FbD<5NwZ%}2l$!`w{CuAz0i-{ja^ zZWIUm+XCmQI$y5rGJ_oRaYRHW(UAaG1amD-rM$=IWcqIT>3k^<-mz`U@2KiwywMc= zO>tM++0_Ja1u&;+=DKg9uu~}DpD%-x#g9Mc#W}6VdHUGjO>X2P;c+71@?fr#E_ggd ze&@oo62m88lXm6}q4TAzG|^TsVM)PxL!1cUaslV}PH|;NRg9W(p6QX`BwaY!hc<7_ z&M2mgMkTYzJf=z$?48h)aVSrI#Klbe>}9oC9pv@0!CmV5WI-5k zN${MYo+LMaG|4 z==KHeaC%hh?vcgi5YeO62Ce>xr}WLz(vB`M84b*55|nc2}P+?seApK-3`>wL&rR& z56T{hYN_yh0xlfp%=6|5zi-4KB7}3u`%@Y+d!H>kd|EOzexIUHU5oLm}{GXC1uXAspaeBFNbNKuT^DNDE|Zj z&KG`%MuGE7LRZRtRBDY^zuP8Ds~8Nrko9*AkB@jixiuh%79qSrtDe*UalZw;@;t%H z%l;#&X3O_@QTb(b9h?8Y*Y=W+uQc=3rKXA+N7ofgEO@F1yz-KBf?uqORvhJyHWpP#*^~qx8ZV>1mJ98ZZ~&v@AgcQs=6c9(%Js-@4LE}D(5*58M?5EfwNnf-#Q9`@79n$tegt~5=pI5qTI2oiLw z@!O9bt(MD52GY#nwbIx*=F{i?xc3L6y-l$0_3!8HB%jT{9y>Zz_3C1P=HGxbfk#)0 zuPtei8a@5l)Q7Bk?3DJPYgr7dOVpHM*i=kD8UF}y_hAlKTyfL-8e>4r!%IOn;A!G3 zF2j7u6MHh$OYfIu8&8P}zAq09q)Q4?L1y!~L>7p`d6kTUD^~)*WD^ukH z&H!+MJw*P~X=b`MIli`Tg_MJTC9qgG$@%PTCiBf+;(o;ugIAv(Cu*`izfAHyxy(xx zm9wMhUsZ|7y&ofnfQD zvQ_vUqbkd?4scrV_@3;1urL*r7?A#5i}|uJn~5~@7|)$tvZ!pH%u=+X`YYfxU=Eq~ z`}U5H*PXKB7duBY@fH!f>J)MDpS+)x^%Bo+JzoW!I?O2xC+4>pC)+hjor+yE>q`EW z*&TS#X@nE%WctE-1jin5sxX&0G_FNJ{Uk&u4O=Tfcs_rFmP;k1sywd)B=8cvKSBna zGR&d)<-g~j3iwlg#txMeI5L*ua%|rg{*$Bev1o*?ucHNUN-%f+KT72RrwF*+>Gw8+ zYjRK@qtxwTuIL{3xTls&k5mUt`1|F1x@pO_JrtjcXS88UqfpUHUV@ly50^FQ8}->!+RH;e>P044*k)=~%d6L|vLun;Ow z>6kww70&!>IQQ1f1H8sDv<>s(KLAb&ert^Bcz=o5AE~yQ{s|()A%=J5PQ$Hq5+L&Z z$DM4LuXzC{0dt|wT!DEbF?2)a4`P#Zj24<$zCXb$yDyxF!BcklVD$=cVla2{KT1>p zCkk^&=pq9~6sD#S()s+7Au*dZwtK6rX!h3TBN{P*WqVk&5{9`r4J?U~Z%rZ=@A0)| z*{OANkcFS`vefT*Ny<<+3gW`LxFF00N;$RS?4jGZnMMehU3aakE#m(AOJF?ym*Vjz z(q1a8+w%j?Pxoc02=5i^o@dnD+{?J_gC>+UmzmYAN3DW#OD~`3Lzf6%&L_!I-cKUO zPkRH_+peVApNt!ME-Tp&nEF>=g<6u3Y(HuM(zxMSRu^egx`XlU{QStRalz|__)OL_ z!u!xOp%wc-Z+m>iVgSbpkFNe535PtTr5$De3wguVdGw&c;R06n+4X z9p>1FqY@Nk-ah!d`)E=;3Xew=>WnK`?U@(nb13vWcrgVyR+uX^8r7`t+nImyA@%3+ zii^afPp!TVO+_0NZ`jo;Uwp&|95dhoSMM@9%ZGA5m{~#%d}XDsL?`1ue{mp$++i=~ z?jCNV2JZ=sU{9zj)@2W0c-K;w|JOK$A8U~YMYcicBeua%XF~J66+KfRj~?C=jHABY zrZUCKVjA^Sk|{rNCyja0`mMbZS5?LBRG9Ei58!Cw@eQeoD$ty^>ii<-#$)kRhu+-Z zapUlPGg7XW_RB+kKM-)#FgJt!WzXPC*MprvMMkohOIa0reN~Z*q6ziX<(&K0&+-9B z33Ff9d1#ytj2>Nd?d6wp%t?Iw+K!NuGW_yrlUo>Lwi4E@$YHLcLZ|&G=EE3jSC3Z3 z$_rtu@7?LyhhL-Z38{nxOWg+nM+$R%4Z>&QyTXl^tuwV%Wh$Z&C63Bp0z7^D*{^K( zr{fp^M+|eH(4us%B3#~DX}^bVRsP-kaBi%s(-pQC8F*%}5Xi|0I6|1CSs<$T`4ElM zQIVs|gg;A>@q-klz|XRQwtoK43;f3L8G;XU{@HyrDRzpaE*%ksNX9-IoI>eOyh>>f zxJd5uV!C4V0}dDFqA8p0!qfKR3DUhX!!|jGRcJlpky5S*d(Ru0xf9p#0S+7H)?#9q zkdlADo2fKo2*I=O|3TO}ZSx& zh6+}_pM{5j$urqxiII<0W55P9ExV>Rd|mAJcO#OEV)O+)_zxjt>W75Q)f0wN-h00C zK}^w#Qgusq6%X?X^ItoqcxxFWlU-Ishb{sF+R&rVOzKDZV93BtC{H8IeJcy{fDa@}6wTn^XS7dc|!&3aItuAbd0EtEoX9-j7h0o-3= zFeh6@x${BsbV5@jN8JN=wF@R%J&n-_G0~$!-zR-K`@%kR=jWGjz?}fj&w%;2^O z*2b*LnDS4YaES$nPo5R|0q?Avg3pV~8SkSU!Qz4}`qH!*#J{|;3lfjOo|z5ii|%<9 zw#s92uvq9KSj7j#9l)IHnM~|E)eKddnB5>sQg1i0rauz&7U2|uTyy19+8-tWw-0j^ z5eetH{HA>5r`9A}s%9pAhE~hxVv~i3{x5!A1UJFQ?@yQuE+%ARu80cFDqGs;aQ_mr z*>EgipSUhD%a%=tXw_sS)NmPI5u{{QV+Igw6qcjV=@hxN4CofN%g;>;JHw3U9k0kzmAl|bo@FAS% zU2A|Pt=c;rE@dEZkr-@z!Et_$h!kdGqKXW?4`1hkyy*m=|M>F|X)a%GzOXKj8F2IP z_{Md4cu|GqpW$9pn3s0h#&YhO!6uYW zf!-)#wQ*y)Q8svh8-Y3Z+_6xZ?YTnAXtAUZRiFQ$wcq|@HQ%Jkz7$BU$?NkMa6>R> zp?**79lcco|NFuwLe2@neNW}3H_Tr7hJ!zYJ-DY}17HB=Za-k%_wfG^?`BNzJ;G8% zf-IXkDU-9GFI*%qA#3a42Dq; z3UK`}XU%wLzNUq=Q-w?Z&!96woWZiz0Ts>1sr#67A%{=vVHNu`;QUfJZ>u%GQkvur zqQwfn7WuwHkL9;I_1Wb0H*-2gmp7rzh#t-oKN1IRVXsd5rVy78PjE`LB#q;wTr9LN zW%cV~o2pK|Lr)N&Fu4M4^HYq>Z6l*scKpatFsz1m5~J29i}l(h<7`g1x+O<$ z7S-UD7HTJD9>i9f{j?*&%(*sr1h@|P9Wv_4WJz?wmt}EO>%>JjEX)!I&um>P|6FMY zIu@zL;9X)O+AxEXaWLa9`Lf%BhExSHBnF-=C8`H)uf6M#^GMp~6}X7Y1L9iXCFPqv zY4!bX-tS-`|BI-xQy(=gml1+4mfC4YVLkg3&oLhE8WF7{acC8g4g^mM%V0m)rQ0y!-{V;RC+r*i92j6$1CxgkH z%pEBARJEPnrD-F8w0d}SWbWKwR9C*AJLPU?*XG=6k7~#9vk&R#E3h5isM`7hdsOS- z(KYhZ?+!P%oZAq5&cwl1jUh8mzaNG1uH}eWZC*o#s~&JQFn8$hGTxm;B8nwD#5tXT zWbb*Wuf&_RMM^Y0en=L&zye$q%pqfnQq1vYqUpCe+A|xVsI^?uJG)L%ZXtK)T9|M1 z90INa=EA=CAJRZb8Csu=4S8J_27liZIN*6v+s-~ByyaLA!9Jr`fb)}aW^v7)-;-z6 zyj(%hE*3I5)HP8%%T9jx5qxOl`CcIyQOe2Y=iu;$+~~#qSvqkYO2T55CkLd(j_Xzm zkJCz;EaR0}6~++7VBuL^;yxKWqV~iLE)6}x(@iVb)klupQCv6lesI@ms)P?-ctv30 zc^YflI$ey2qTJK2kz&*c>iKym^W!RI=Ij-F52_p;Y(W%&h3A(eitu=o-+0&77L)VA z$)Dk7EpuD0zQRaGk&QZpQz_#VA`f_4F8@b)G?11HzL+1Tf5@+jmq`rTLG8SB%^F>w zPwqRnpWR9yQc-eR;cUk%#X)3a>icDti55837iIkzYb54FnlSBm+E|NnanF9YIh=<4 zx(X;NnZO7N#Lh*}_vvo`SS)Q!s61VTV^1rDj}?L;YI2y*9}v3>9-2;!8kEd3#zpvx z*k1>?^E6_xRlU85D#z)^1A2i3lYnNg6IPS)4&rqybIgx?vbnhM6B(8G0ha`G z%*CPtO?5}3f3K3h{$LOLL9s>R+k`Gn^8!cg=rNjv0N@f}F6HPg`?IZQGquvQGL0;v ze5C{F+;{a9O?fIl_ZA;=C<;T`7`HzCE|3T0iB%s=-zEQr>2$tO}u2Yp~v4? zVAp#L;QSu2H14z%#dsewb(0Fqu6(xVj98Ml<<68*3Lw8w6vZpTMMQCG`?>U(g>JAt z_1Hv}j-k~d5j2jEFZtQDD^FT$;gAq91bk?bm|T8-I6=FWB10Klskda7y-w(TNP`Z7 zV=NtTrBmcj%ITqUL^vkb?*F`B23W&j;URQE2=)S`(UyQTT8;lpqs@<(==%Ry!=c1C z)^IY@qF^)k24}}8mjc~HRr7r|r{aB;cU1#4SDk%nns8ts7%T(>KW5u%ZHarsLFCou z4I$%9K@XNYbe&uT*X|mhnDM>`*i(4FDB348eRUM%Vdp{Zf1lvf&XeDh^kwmLXvq4< z_n*Ed_X1o1JkjU>qZ=9E{9%qLS*8>euZsOVerv;k$Z5#+ZMxOs_GV9IbvsI!{B1Dc zd|@sY&D14!KRdxcrqKQ&eavNPEQ9+_lkZT>wPvlPEg!62c*ES*!w-1aXF*p5wK1XE ziC&^CI9C=8`dbIhs#{*1TF@=PdBU8LLzP4AgjhRo*OXsO^pce&|K|5!?RE-f8fTCr zr6MNaJYa6#-mM~I`hkKGJ!zp==*jxGK{NXHM};&<`i=7a!r{LG=LT~l^D6(3u)B_` zDtH&hPb1w8N+TsDAt8+*-6bLo(hUMqN|#cCG}7H5T@nHk0@B?rp@i_xeDC{P>$mQD z*S-IL)-$vBnKOHyXJ(&MzBc<=y4vdaTz{w=FEI&I|C}QL+u@`*O(BF1)^6;fQwfgk z9$vsW<=JtzW~KiTrJ!~_^O&6WPu8!)W!v!p_=U5Du9K0TEp{xXa*{Iw(W{!Piy@ks zEoO}2IQM3cNJL^8=A|~!xy-GmJ;XVd8~%x1y|%N}aHYf`CdTN6GCfEJr1t^55@FIBY?Aj&YASuXW53jzq228XW?y{ zw=#jkMzLgAkDjiiT<8@;6)u!*q2HxXm2SG0`ZLDvhZap+FIwc zTY`*+uqy`D&Qn{Ys)vuKXk@)?wZd?FlLCM`JAo}H-4e4!V}I6XO{y`A3E~# z+J*ZVNHXusTqOhswF<5ejXu5k?ltbu+#-0mW$px=E_5OXVqJ(&$*792bcn|ERZQi%^;Xz>P48@j!|JQ|vYtZvktP&Xp}$w1ck@5I_LvbX%GS|?}+HsDUC zCUm?vXV}m8ROg?ISEmIyhkMAPl@>JV4v!VZc3}irvgiP(4&B}VvKbGYDsWy+1E_7g zgpX$gMtzujQ^jcUgSmX=<}|Zw;tQ=U@XW#fkTR&yZqG>RyxQp&%UtihaZLW6u#rH( z=(d7=9p?7=7^$gB1VmGW-*Vm3IiU+Pa-RATv%j7bU+VO4dblhDAB)xsZ6)4dGKK=D z0DJdtwfe;kv!5&{albC@I%LM1JZ^3>n;Rl z3Q0V`NdxDLpUEZQt+sneE>pYBu0#_kY`0IX`0eYalljY2cx!u-N|#NLx!4rgd#yS z5qS4zbZ(@$0|IaOB7ak3bJyJeQtCbN5S^!%^8>{nVV>ey;GV#%T{FYf=d2e|RG`;( z+4d0Z2#pGl>oeBw!jeNW%}=CK1x^sUpjK5<|H!&hro>yVrB;FzF$d{ky6{#N}*c5C;1R&&)N zHW9DN&gf6~Zt*SsDxYu%jR;n85{tG+)eiRG@3RZyBu48ZRMgG8Kh=ySx& zbA?xOwoKd}WPiTcRmBlx+C9>GBb8|_Jqn5+v^214V<>qS!{6ci)#-tl(W%ae+BDLj zvZxvB#K3o&Uq146#=ud*tGM}JeqjSR3g~LDBVv6LKCG^q;fnM1lWce4-{GG4@O}Ai z*rfVPZv~by$bj?m)_D0ia6oc6R$aA{x-C4P@Jib3{;!pHkwd6CUGxvY%9;d}C$e;8 zo15r@Ru2cSkOSIM9-?DP)0&G@8{w}6HFs=c^ zC9EnohHN%+NwEHEa)Jyv0@yn-YQt(7eR}>=gfVncz0Z%HNI%vbx=9|?ck*zbeV`5( zba>DOU(yUIrsaH7{7gLNs~I19Iz{6nr?ou&j38mB6!jMta5&I4l^cZIry{@D7}TJ! z=OyW2V_*8Wb6bs-vb^)*m`-vTI4tNs{kt7lPr8eVGwcWeX?UPiI;p_-(U{wf9 zfsv0V2?x2nQ59nsKY+k z?$wnAesRe7CZe}fIvP4-@a{#HKi;>ea7z0F-LuLVKkZq8@nSCSQHp!R3-*p}PG`7R zWN{P70~lw9@xYx!$1Wwg$@RHO^8H*ehiU^F_45Pn&POKEby6z0ug|@o3Ilfv-K33@ z%7d}7Jf?U-N?uPd92z7^NL8UpSFxeg4 z-`rEKc!Mq);d`&87;feqLHAH#Qn4@calcW)Po1k5s^Qq0<|WVHj!vI2?bftVWNrg@ z0GyXP!ntBu1^W{pspQ*hKUqwP{RX~jP=I(lFy5SjAbtBM91|VWw3*Sjox;59D3Y$hn87a& z{af^NxmF4gwm=TpH|BCI^u;;(X?RPHwfIY#2Y8usdq;KJ!>0GKaE}$hS9b$UKtbE1 zDGQgRiROdZmz^yczo)E}*isRzf=5|3`;z=W{snEW5u(2JT`|x`ubD14ROH5J2>sFfTKv}W;Mdg;(sx0wFHE?+#ZZ=BCa^GQH4Fr+A;hz zS(DHR;w=$^CEuycIruUQc8ftER1&c2Miiifyi(TMcjv@LIE6Y%Nj5 z_W9#Vwak~%hQvpg&(wLl&^i!{&|b)kILzvu;e}gTJ>7t2$JCY>4l7Ud>|Z*@;PQYcx@&nIqdqb zmL#Qy_)ZcLVGJxVydJs`m!2?%`92qKdUAA2T61pJ9Jt0dw2Z?B z7Rf1vR%ueL)cqM9WVO8;r?`wphjH`KhzVB`T-AFB!yw!U7ACm`dXkszy}Y{@c!#u< zNj(~oan<{aUH*ZSNF4C&#&;MFXIfO=zA5*ep(`bs%5jG8_y}I!u1?qAu_u3CTAn=x zr`85QwB7rsENtWp(oM=#o@#6+U;Y&@j+f_s!xxQ;!O+^?hLxf|7>xzl*kP-PI8R~z zk?U)&hJp>+W}NFxL=v=y@=@=kAxV0KUJ$KwkK+9+evFp}B1D0wo_hjP&utQ8<;|KG z_e{B$s@H#lXx$*%{skXNt$PtSPYkBQ^UVBlLQ!lL={t8XBu-0A>2@x(QMgA8#@+ur zE1r6c{ouc4#hrxz$%=DLYdgaEtqU(rOhlcBYUk=Le=iF-1^qz@iF;sg(dq%3ZwFtE zIZx6RqmYrc6X(5nQeNq2xXDcs_z};2@u)wdWpFvdS-utYGHzan*ly|%FU2!+X@$Gg zsXy96y2;M@b+4b9GO*vH5qSe#GaOXb6j^z#mp(DhvCkESbbg^6SbxAdya`S2Qk&4_ zzhgzzLTCbmDi+mf1Tkl5-T!^`=zLnYjh^Irm=ADupw&3Tzz;o~e@HMx4{he3{lN`+?_IEw zd}VlE$(koQR_O&-^EJ>}vFogwA_{d!V@nrEC@p>ZBh2%sJO8)a_~^r0DgPGXq3IdS*(;#C{a;=Z1+EObE<`5D$u9Q0 z`(cM%G=?lqa)drcH0P^6K`{$dOJq;BfGdHnd-SWl>c3-S!oUjA*9(vPsL=AWjrDB& zk`Cj2ZCmx=d5|LLYV<`Ylaw5!Y}ZfqW_XQ^p$0apNB@Ps_M zKb57YL?`XjbY3=tHOAfFsKyoti_9@NoesL^R>da|b zP-cAe)2D!dskeA=J(>%gZ`@qsOPg}^Z`RI7p+!_#50%~2rP5-07wvZ2N;iecZ{Y-) zt$-N!=YRQUV-PPBPLLT=`F8CC;$W+P{M@pl*jl;b4$iH`vogokEvoQ2*9~n)vFsm_^x+l_^WoFS@JWHAQz0 z*M<`DOlzWi8P9vXk1~Z$(T_Sz7BXt>st91t6b|o6Xw-wCKswTmHQPlIKV9XBIA-^` zS4V>xuZ z9_IHXqeFbeiQG{3InVyY$O4YNK#&nPJvHdA_my|&P#CiDdP!HrUmsAD>AZn^C53LB zcv22Gr2OI7Lvbvr&p8@S3EsJ?OvL)Qym19<~pl2W=>EQz1zAqhjkH8=*Am8 z6679NzF8o?Iw3w;o(4ZQH2U*L%zL-B<=6SlCUD{94&B&e``d7oBZZB(c5cF6YH$31 z^ToH03biV5;35wb)d~UU3SC0wN>8{l*|OBuH@4^8H;C)TRKqLYdD?lED{gWLIlI6) zLwE6hN7vAD@l4f|{Vu~MQ~JR>$$m@v=uf8WJw9?Tx?TY12%WAZIJf8c?cCf#SjDBd zzhph{-RD95;|NU~vguDt>2P6S4;_+rR8dl9M{SuBZ`z~x%CSVN`pae66MF@W_uf|G zJ-h|Z7C0~KtvzhFX5r$+^%+`H(j(5QsymV%h9IR6_|N5nuIvR*(1xNGGdqpeg+h0=nx=Q%Mt8uyC?kqLl zA$5yshVeP3IZ?C#X90VcYgM{`i=n4&%#1OeNWYvuTW{*Nkn@f8Z_pd(huQI~z?lK( z8?eGGnuwm$#}@lV($gWtH!-D%t)g1vFxuAQD}9mN1sr`QV3U~3uBx3q)0A)H^CywLaKr_0nF3;U!0|0zYA1uMh9>f_xpTtaHRb^(1?n7~vc8De-VJ zY1@J9+37r^12$$lE(BdLW9%mCokw}ji{%^bD=jyEu_~PX&Jf*-Upvl&ygX0a;|QW@ z!&bG_2~p*~qN+Nztqax|UGbBvE;_hu@~`()eW~Q7(uF&4n(!WPij8zqk#&@GMaCER z5t$~O-%q(W`^cRvh;55i_Mi=Bh#(R;gK1)AqUYL}=XTL6C^7vdZ(WW_rAd72THyX( z0KV54T=c186ngQ^#;Ug_NG`XYz)i$&W?DtoX!s0_>fif&P< z`-3K_>5(gE?5G#cQ^)h_Y1t>r8&Qd!fmiCFQAM!kkK@!(QqlJuA>uQB6+$r5v2AEL zup;*KRl@@tvTQyAJU8GJ;6+3u*;;=-$x89?rNkKHYh-R9#pBYiwPL0@>BTT^TC)f4 z8FV9q?0%njTH31_fAhusU?c8F6*rC78=GvpzI47oPss*O7CJ#Y!CHFW>xa+k|Ll@w zN5lmPuRcVHU7{Gks#fV*N{j(c8aUq}{?^o6DS;oy=E!u+Mbmb~)`cFm+Vk%bX@i6p z%Lskpz=MUrF*GBt;^JyX|0X7fZ__iEZsUCH+GymDGFua(bAjaZ3JVg)KY?QJg`|}%eAn5 ziT0B*lHa+=WpT~`KD^8xlyqwbVcLq|Wz6Hl;-uJt9IB!|%llXX_;^u*BG$dvi%-m>uUF>1D( z1*{TG=D)lDZ@7xg^~v>?CU7j!-CO1PbnWj#^KxFpQ0ewA%`*Hn+sQM#F_eTg1M!s$ zK5$IXm589yO0xWm{2;*aE~LDTxP&Urfk~&nQad|qK&DM=3^)ehe9QMdms(Yh`m9m! zF(+=$<=sR6t#Y8@Bou;WAe!d7@qf<*27B?=WV+iqaG9Ruq>RZ8%QZxQaL9-gf75KY zWs^^)&?Tw;pE_WreuiLm?`{oC;jie1(wy7M5bmEd1O?eRT@yT@iKna zL7K1}&XOml`JA=)#x-@;-0`qGO@;KQ)^ESkJzN%S1S&8&X39MxlJN@t7L7IZ46~;3 z$&2sZvFm>%>Id#3(TFVY;f4?Uf3zKMkSzE7TMO-kA)uXonjs!ZEsXpNVThcRb zs=&D&=l!9Ia3;S8lI7m-2=?=b?^W^ z2E2O`xZgi=3s!GzMZG26`(h`a`PAf-rJ3ZXs(9(v+$ab`DGSE1_AlGy+=1+W?Qr2 zf9i(Ny%Bv8^zg1S`2*Q+N3N7EpLdth$2Uq0{!|V!b7IqRdm!E)=(5>-nvs;*wN^g% zy&qdR3;JE(bb#r)efcH_;prrQ7<|s0Lnn9-iBYw8hxaYoGjb7X*$dN*{M_&Uzm0^x z1b@27BY<^)Q|Jf+OC6XNlu#Y7&GAB9+1NQ=OG)A?r$l^3zLQuJ^CtoB1Ug>Yfv45^ z)49|{>9!795+rZD2uilxu>51~GDAvbUk3ws^q>A6{W`|eD9+B#+{C8dXB%*T*+#o_ z{opeH(Q(=A*>VDK2ha&y3-tdH6Qwak6?AEP;E`n{c|nISZ<`!xT&3cLJ}3*^9(0QY z?LRq*tl5uf#tQzj|FsaF;9TiNe}F8@X+$Dw*2E0l4s;n0k$JO?f}x1bY`x|ylSOr|lr6Qra^eK7e(r~Dh~E`GnO++=gY?A9W1 z8_z#XDa@MW`K|uj)q9D!5>b|Hc_eP|7A|xbVE;&a zZ|hvwqA`(wbTx*gRA!+S6AK(vJoQ+t`iFh3{XGk~Iq0gj^Jh`ii{$wIHf1coP&>4c z_8C+?StjyCBkT=%v;&jMng7HS&N(H295w1ujG;0d$W zrlDJ!)hY7WMuf0zPZuouk&X_uE+RuB^x*K&T>;>nKN$7q`DqTNbBaE{kEt$FJ z-EGTexLdEa^!XTHQ?9sOW2F_i3FvZv1u-IRz}NrSWR59lKJhnf?0GmDx= zjJ6pk_l9XwaGw$(hjUPQW)7SgwZiq^Fm$pWuN=PK&SWdSlv+B|5-*Xs`pW4>~u7_Hfk>8-k^-Z4HU@M|o+|NfKS0 zWAZeMg*wMxFJU#e7dq9xcMd0)Dpq4hX<|aw83~oKb=iAWK`6?nJh{WCuK$4R2F{m( zc+k~Ze`<>R%)9SeJwCCeD306XNWP5(S16Vr+xQz?Cw3|n#o;7Av6jNYl>F3pc1~(r ze|7hbJYbu^&em(F_B9bTb0dh?4#yweIoo9#r`tn>*qXgfjV)jwFGAlBb#RK4n5AmK%M^_C6qOkIb4mC zm+8P5T6FzT#?SrAmp(A)5UC_8n5=!RUl~Meg0rci*!>;Jh>rUnF>jC}t?<#`rLDKt zUwnwQ+AB~Dja7sNmj-xOv?C89m|dS}&HsFxn@L$PkcnlEZ5Lzrr)N4xF_2g60Ju8n zmX{(E!n(k}oYQ^8(qI`;?JjyisiG24$Go!`8c+M_5pXroWiYQRnYZ2!(a)WoM5Pxb zA1Hkv2(WM^=U~j9m=YL)NqH4?YZANe_C{*>BdTpyadbk>88~&x88Uo>*!m58U;88l zfvbRy*iFxopi(E8el~6S_`p+4dA;{h)>a5%R|DFc!bJTW;L4y=5f&tyDUA&sO!bIJ z6#O^7mNqWS#4e&45dZBT`c!=fa3#>O%x!opCNq8sGQBxbKgFLP|EHb9RYwhpPM-q>Z zC+ob$lAw9S8kUxgt25FhTFiPwc|Pn`2@6rl&{bBJ^h~~reExp&d}w5BV*H700#Ok+ zqqIp_11c{@cqVX((3xY4kZE!2N9e^p*<>Y8dE%blYc;OPO9WoQ6_K_`(f}?VI*i5@ z*H11v5qd163w)H^ot??XhZTGmakGML-?zOe!h!n$9WU+Mib6NP%M+K;kS(lI?X?_H zE8bS?^V3}UE86W?1K?tT^V005Fd1r(;mOdFN+vA*DrD>T~} z4c31;Z}Uj~!ZPmfG_Yc2baw8vmW{}q^%=`aK0LlKKEA&KqD8`Qq^j~Omrqv za)a+mj4%J?zx#e|rr3DfV!)E6EDBsW?A6GfyQE#)a61BJ(hw+<78DJf%0KJg~*KB+OvRnTILQd+54Qx$|~r zBO+_A3m(uXZO@H$hjE%*OG+I_TL=bY{O7q544iK(wu6^lA0-2!^uB0B16yZPY;mE{ zck-NOHKnZ&TWGm(DqEU}=)9=_vSGX5M?myf+*#eKsII#HudvcUZ-9YEsjuvml%&{4iLC z7?mAgR4^=wwiE?!T0Feld)y)H>_5Tyc9&z}XAhlX8-;7yyV}1qL%%~p9!Wh^|5Ys2zgFdX7RS+P z++_0rI9uq@-f=%rOIssDym}z+5uDWgSCMQZX+7qU<5$}g`vv0);B25fzM&Y7(HO|x zd-PctVQFGoy5^!J(51|6Tlt_c$}Z3uI4kIoe#tS5w^a{4$rvmExvCFVmigzC3FL?Zg zsj3m|-?iQU{3nRO8A2!j6@@A&F*~Zm0?$Da#lp&GwQ4UcgVL;hLZ$w#5`h|U`p~s! z4JdD9YxN%ygFQYndb7D?a7y*)6GOM#1P zP3XE-=5#XU6f;u#jX$F;#ti+n*D~!XkeC~KEZ`^X<|7WAI&@6aouO#b((%k56~ESS zdaP6RoZpEYlJ9l0iy?iKeGCtAr~>DO8@b%}{vkHvH~l*KXCErD zm$k9o(*B=sRHHWj^~Ya+Ds^@#`5zNxnYtIm|83t`lHfo4#sm7$>Pk+vx&qCMgNZU|RRfW<(O%%Lc-;Nf&smivGo|SYZsx?-WU_4y za}kh?zV8`+WEY*7Qq=zu zx2TAHVk5wv=Ll9l8N7P(EXflW;NbbJN8V3JIDOc1#wvO zj3rGcdiisf&LYa&io5L7x|*XcD+_(`uf?l}=^`I=g{Y1~2Tjzfawq*|@zLX66JE0; zwIRoTn}mIu=+=j+!0|wrMwdD>5TWPtY5MWzl;s51nh~<&nS4Xc&)%t2ai=KwSmlB) zT1cP84!tV+u@Wt| z^rv{AgbCIa1K)o7h@ReS;Mk$tC%6tm*}*Czh@1X%ai2HZt@Z=_^OW2`IkkO9AMgj(3U*hlvn?*W`C$?JXujh%SLo{1D=O>3qXE_lgQ ze@q{6{-G;qB+DXiYM!N!upS~|e!&sZ5}*8(pF3XJY2bbm^AtEL z=(sis3yw&NJZ1KpJ&E!{5^>wY!w{j5`6ZU>G4I^lGa$PBJFJYO$%Dgye;Lz!=uOJ(pclcoZdC`Uh{-nyEikga@EzmX0OvFO%U5qu!{#Cjdvuu`P4%|O{ z(7(SDa~fQ#5e!<%+C%O0#&V~9-&LFzQqHeF5GXRBa$f*<4c-2cSxt!%S(?k~*aX`6 ztrACaNQKx;aYo+9K6ctoks{zOp;P&YHazQSAr!^8u%{}*P*c}xYKK>!aj=w5#RkeG z3&8yW&Wncr7te31>6HxZiRCq0f|1deY)v_7aYu)?1Rj{`N|OIj&SAK@=dV0Z5eQIi zzT&dx@yByWN0mtT*IIF1R0@mec^yrFaHr69Q{6lztY7RUUAF&L^0)G9{41_Pek4{N zT;YX#zb$9rL+J#%a6#RnI*#P;M6q|gL)kBM&w}5N7jUUp{dj9GZF|_b58M%Sv&`c% zZ=NeEYep+|ef(^0Rh^tUEJuz$8a~=cVV*m{1>6C25|oTRHZNX2y<4K~5h?uj^&vsw zqGe`pl9|Q2G+R>rC~$kw9evWG%FR(hEIbi<@^ja%a*yX{(^^k>5EGZf=#h_o8gM(% zy?Z^%#1uv)OFK`>sRbC6?-1}Hv>0p_iMoFYgYeiBoR|5*!TCIir2yEZ-uqY>w#Z)H?4hH zh9?1a$l-L~&Wd)!xRcjipN6Up$B#`G#43a(@VZsl8^kw?O}WfbPIsE@W^dL&M_U8>UH@Q^UE4OnY{(qq|()OvdU>vf<;a8#FEwaCUP79J_wr_csq0 z-S#?_dkAfUkk=v7QE!|1Q&FUE6h~w{n*pptjp2iZM(zjm<++4NvsY)ocgVIS48_&L zv)U^V?j1DCu8P}B1OoR1_U=NnyWEUVv&gqgT=1dtdy{W9^FqGn<|Yj|dJL7LM=*sN zhR#C!kX4n$Qh+GxzD%X$_x^YFOG4Zi$N_j3k0_IwWMSRyJ9ILullLaN+IvSr^v)jp zD(T6_>N*H+>iY=EbIc-Qh7bTZ0G&am$mmVTNfj$`3*yile)sd%Y8`J&1|ouV$BlP? z$Kmc$A9Nlz*Z4S=CJpd(XsEiZUb4< zG1+eXvF>wuy1xS7m82F~~OV=c`P$0#xXSJqL19||I*8P%$|F zOmxpu#6bALJCBz7De4rdc207=ArJ|n4&x>c{qa?h@*~Z-Mx&tKVpGOfiSJrZkYB27 zkCbz8jWXjqfoL^gR2_ShpAJ&&KFG5ed?ESLBDU$tHhb7|=n2CI9YZwc_!?DMuBgKQ z&%)VvWOsE8=^4|idRdi0L`x_~vsGwp%qdQ%F?@FRODYeo-5e0Z4|+-1t5>5b-SB z6rCmMBs$Rb_1v*7fXX zUW1W6`tV*1#u>%-^X*w20%n$Z_v&KIq?P7*Ax?cPcHF6Z;ALZQijLC!>3r2-q$;U* zgg|k~=eGDb9np&S^}jia5atj0#Xz`ZI1N#la9iqRI#{*AF*$fx_%nq#KpL6%sRh#QFQTSbM+qjB_{hl;NqckVcVU* z*G`ZvVp&4r-s6GPGjX}Jysaku@02bedElQQa37#s%u_Dg3lWzlDs#wT>g+Pk*6c0I z`}n|2MD^>4O^gcI>Smt$QmWr8lWa%WSc0Epz+$5o(H7Xt5 zD)MbB2p0-&pBF0QL~!yESC1~uw0a;nh2uWo^W(jU(lqsI`(z)jIB+KYJ=pn=nW&FB zx3j0tVTf96jOMHx&ngfVxICxUXa4Gf6h92-(qItHH+?GIH17E`Rlju1X33xJxtTV~ zb?EaB&+|mv&tINd^O+9=y;tUlmKqy|4}H(z zir5d1m_$Sx+a0!x)(9F}JkHQYW}9`lJ3GVXlKvjb?hmgFIDqqkpNLKnWqAx*rijsv z7Yg_-Tu-^Ym@CdimW7g--8#fX+6>^lp=0%Kb}mYPaF{~n6jLx0Y;qoBg!Q-Y_@fOL zRc*>2^L^kvp*vlCTl7R`p=syUCrLtS?~+u4jpYe?Okj| za$)G=7O`=6fL!r~=~wNMlBbvSUEi}U+?;`Pg-+!5AF|=RNh6^=Zn-tGPOF>wk3K); zO-$`7k)y(yglpiOp-VEzJFTqo!VjOBzmJ2PynXqyzWwd2s?6srcBiAAL6|W*LifE| z#4E7(tNiP#Rwp~j`&t^yMDoXo+TNWc7;Dyao^a;1hwdxcPQ0o-MX^s{b^*dGatUw# zGO{H_pXnDzz2vEHl)Zqng|4GLXCksA82J$A&+A7}A?MLT;6JiCo~lqkQJcaMTJ*Pfl=e}J8}q2})1I{->2eT?6u9SF1k}+I?tyn|0jjMuJc2e`LV}u^xP{JmhCgJhPaXImn;W>+cP@>(Unx*3?7bJLYC+icbm6JW+|2%UeS zTT&IvDZAdcsDzMi+Pj}gW`=i6HXiZ9S*lssHOs*1LsvB2BiWKuKQXsF5 zaxI!LeQ+a2^i+P05I*>Ip}XF3RM>sT66Lj+Z=e>ZtCBokd3)_Ny%Mf1P6nJd zbXKGmN_elmrec2f?c^4UA+GrZ3FcXC+;B(BGmY;?{QyoAx@hU?7IgJN9NwTP`@Ub5 zyz(1snF6*CSk$IZTv;xRmVi@-j=TSYa8gf&(jJW(tEa`(i474qU_&rv@uBVQ1OLq1 z2H;eovoqJ|2~JhG38Or>o_~d(bxj=Yf*DI9V9v>RTGlzl2%Iu>Uq1F?Wyi(e^!#4o zG-;9lO&9f3qP;)kfPoV|Us0G8E>IPrQ$pcHbBVxw%NRXg%h8dzkNnm5;8aCw8H4`q zWv1!|JYb;!-QFIl-9Gk50~f0Jq}MWZwiurEV72Lr$g{*BL%$u{3*0m47#EW@CJ|l=3(d_arB0G8k&`HsINjZxZKEH79PPF>WU@I)dJmpD# zy?S)>$7kXkZfi*c=lhL$hB7rmfQHav_TKqx(tl}v={Mbmf86uZW_En{Q^&#hLy^Qs z<@0J@`Pz%A^}9B-cI`_})@1*`9IB+eoESo$_=Sf0f_H(p2(Uo-IbYE~Z{_!g)q3(} z0e{@IWaKvjd6xTxNS9BnXU_|FL9=3T`m25B{kN?z?|RC)h6AJWwhGHZgPgK69dYG* zaO2?}zCCav@G@R&1y^d>TT?0P*V6~P{QMi@aA?%VA{gTn`j=>z@!@|8gwWL@Q)A+s z`Fvp}k1;6Nrb!sWl-kf;u@)0|{lIal@B(Ixg3$f@U;ZHwIDY7|=Nhy^hB6}5bzY|6 znlP=sPIzR*N{qivv;1O@DBBAj=;ed1FTQn&-*WZNcre;TG_~_7t9;1~3wC-`yz;6a z9=oeCa6Hg0ws;a=ef3Uet&3-H$tt1$){koKf+H&-Q*t<7yX=_^92a!2 zQ@b@yNQpc5s1%l7f0UfzV{Ibdz#D@32Pbe|%tc#4nP^5Rl-E|DXznjjs9RKTu4d6a zY;+u}*@=0YeTBddUW-R~c&$UIE{=4nKNtq4c)czr2Dgx^Q2*QRffi9_Wdjh66+VB9 zRt+oSZhj58zCbW}rMelnxVzhw7i0cU4J}(u<8v?KI06fJ{t9XEW=j4zL!+5|nfpW_ z$#Abi@K`zPUMLT3!onn(4F-tD1V7tz`k+b^hJ;$w1ME1@ILfC!1T)N)1X9%OKBjMt z>PSt1V*uCS>m;F@FfkgqFcUKGRN{f8o6WWQ_ZMwLh~!6?s8E`lRyg(1VSt}k?seAJ zGa6L8-t9r=DgRbhq+Vr_lOW4Ppnvo=eLq+k#CrgyKCf_Jldju>M_i1J`iP%Gr}j=A zaVDjx*Z#6UMNaUD!0bdupn-?0aS_~H_tSGRMbf`LIVlTwN>Ip}EqDGolF{2KKZyjN z<5ch}x+Y#p%-@a=NT*Wp(6%r5zxZ)?jPViCV8vY9$MM~3m@81gPppRNcvopSU#pq% zg^1gdc@|lpvj8cAamjPp;LUMxSN+cW|u@mcxM z@m4OOIT3Iq(0$m_qJ7QR&Q{^-T_L~SB_tAwlu`WrYR=ulJ=IMupm zeCbbxsjEuUxZ@@xdui9q<7l^TQ9aGpV2PaoI_yyASH4&Z&2mrgM@y?tR?@am{CI|s ztIybnM8tGG5djZ^tKVaA#Y@n4n8 zk0I<{udaKC-P(L~b>ELNHjGcbJT9jC^hh(|{rms#g<~(t;Pw(qZhr0U-wOh!MP(kB zUh2su5xy~hzS>Tkj<|Osquk+vo#E!lN4xXC1(DFM=%nk84UYRUjeZk~r8b1Iw~y^~ z^0t89{lf#j;~M__EMoftAsl;5*g95=v#=)AP|oOgqSd9!;A=ZKkf&aQF)9%D5W$eG z_zjMm;ukghXU5LPC%t@^74B~omq_aAx|u+e55oivnfTP#jvEJ+Dh98P{Z)=nhC!nTcp%+v z5*@d3!s{nB-DDB2+l#lW6LBEwO8d*|sLj6aE}`uT+#bA$6A`2@8EGt8Kf)6b(CPSN z*b!RvheEfzxNRCZ%+Q~x0Jj4#f`*IqknUO}EAxvkcBlDu=dra#e}Z(j`~)s9oN2=ptA7{wsLDAthWMYJtWGzUj%&fV&$v8zb)p!zTCj0Ec<*oP;JRbEzK%DwJMud{aLoIjYsZtJEMBv!>Tn<-*PdVVDpz%9VrBDlRKnpv*7N3ZeG z<1V&L4e@o^J_=UVssAN4f(7w4+`5~Cw}o};jqIeyCnvL+*KV%lV;nSs($jYl&mQ&h zKbV`vdJIl>!QUNRH$CqoviSWu>sNcThg`mw@;E;~ZH|aaiI|4WPpASQfp2?qB<}!gQogn&U%u<3s z!i6Vt-B*sL-^}55L*Rta1W3n6Lz6p2C$rV?6DWg@`n%=n(;HFZ3UOVzgok;z{9{l- zv@y`C*ZM~#wqimm$KR_?T$N*ahdk)olt)TTR~0=wLq9qsaSK6x2)sr&ieP zPPTx4*sYC?O(UP~aVgNaY{01~L(c);4;}_(*K5(92* z!k_F+k!{WX&dx{p4n}c|>yzksYt)S!SlSzQHFcMRYG*9)CLHHOvBFJxqDDK)BUHD8$?F-xRJ?{X0TVrsU4 zyd72mx`ErL7fMb3Q{mXsbSfEM&wkz1f#DtTgJX^(|)o$eb(qLX;#ic%sv1l#l6X65e*W{7N!njYsG~CuqJM+#Na3Cbh^BDw`hM zP4+lqjVlt2>cgo*bkbh3Qduth3AmHr3WrNke5iwqxF=^v!*+1Y{9U=FzJSJg*U{q_ zSeZ88s8mCNYlc^S6JaIOHRR2EBDZ%^+@876M)QLs2>sJB8c%6~Ho59Fa81y~VK}&J zg;~0hvtUweI+;eVe?4?Jj>+?UScRxg$Gpl1Tmy8B;(~uFl4b?x{|{ex85TtI1`3}J zY3c5kP#P%(1O%kJ8>FSBLAtv`8tHBn0Vxsb5)hP<6s1AV%=714!HGwpv&x^g>Mzbiyx|*Bh-AMl7#Jqn6{;S5m7lfXMdg8P;ptJ^f zwz}1EdPS_yCW60KMAE8ye^GxkjM!|l(Ba)%JG~Kw1wZw5|J4qYYA@}emV6M|)2ho# z=|S?RUq@qxxiOMr$hm%BieO*92D;_>uqVtVRTu{^RqpSW&6ko#t;8Dm#M^TInOkNI z{rD5OD(Dhf)r;xTVn1_BJEUz)Z$0V*bF#crx~@^AjjNw#xWJBFC3NdM8Rm$_)xi@v z+fGm29!O`Ppixip39QG7km$T~6M&uSa_FY*@!@>Ey3}hN8%O;P%pMa=N*F z8@8o-egfajrO<5<4LUevUA$N-Ck{^M?;6*G`@8;a1<~HI!)Vo!Fsz}f|doV z>P<lY=KLIZqDh4GAg;F zc$eA`S}0cm>kGE4-#j)uM!YucPU&lmIl!er*Hg|x*n`}q8vAmphfom7iQ^u9X!-K{ z4+Q-KoqqTJ90HdFov>g-8C#CD#{Cm5T8i{36r9pCWafPj1de`z?>j=r|78!MV>#}n zGWP0-|3$sw7MwT}#r#Y0AC9ztwk37r@Bx|nF(@w%x-Tq5Nc8Q2c4)b@iK(qqk!c&I z14ge^7bonPsq@HXXZCC-b>Xv{0CeV zbYvFJp2fR37BqLY)Vk1~{S;o0{`LUF+dJ0IlgYiZagTcIvKHWc zq5CNI;awD}|G_dg+ZF8-b2E3&i~HdYJ;?5Hfv!ta8!)``f$q-=Sv`WmdUQJCN-d|{ zD+ZC~L3gHJ`8o|zVVVu!#9`pP;8l46HhK9g(-i$aFkPJB6(?5~*^i$i(=EHzH7aA` z96lhh_WeBRgZURrrDJI%y!Fcq!tBC590AtA)`_ ze>I-F0H*<+K>kX}&*A1zYNIl2+CM5a8TUOG_2vDg^W-KiUwgAJ8x*=@;8CfK!1kjYT{jK@xrb;7&^j^Y>C1;<*T?S6=@y zp+L{;P^PaVz$pXgZP>gVbKf*Iu34JtZ77jJw~KknQ-$ytY8}D1kJPMRy!As+1ph~~ zI`X;clyLkbjvXeJR@{?mff}z=;cZqWysUn0!io-acM7mI6J!hpjfs*U4j}R)6RH6!tl#f%EHHN_Ow|)s0Ip zAog16_Lxon&J!;^(*L6@GR(~ zpC;VBg{{NknY;L30?M|M)Y12;%q(F)n4K6dsA_S5dkmeazxQX4=UIf$FEZ=hLVey* z%v;d6UB7V7+^|a{97Em!P6WDT$%c8AR4Kms2m9eIOgH$&M;Ki|uGMuJmiv^BamlUO*oECAiMbnYHwoWUIqug92$ zhFeS99Qj;TK*H*N(rH8dNwp_%e9+-*IYzjQTHHq}ZyP=}qR+5X_ z-DMZ6$w*T0*E3Gg`l=d&zXd2(b}y0nkaW?#FtIh{_Zm-D?K*GQQ7?SE2}hFHVe9if z4I7QR7u|?6zV?wB@jZd<@|ppX+aj_V@6mhpQgeRbSYhq-dJ9=?V_!X9`u)A_;YV$3 zO+hHe)>Q3}aw zLf0L?*0k>|u`mvyVO^HF_}xp6D{=V@mY&mss7>p2gM@mmHWK+GZ28fdRga-|lQwFf zKf`!`#WyUxbj=n(GLR!NJOo{JEhKWpuHN!37Jc!fnSS9M=$5WaIBaF}=X^;pF({NzBe@q#NH zdk}@RFaqZKiQ$#|v9CE866@hO-W}&_Dq~0&K2Sl<_U`nQ@(nUV8j(U7aD>p2HQ{HP z2Km$yRcRA291=9}e(3dP@O^Zq+UFwFMpg^^KLpTy9Q{JI&`+Fa7J=d-Vy?HIsJnxc z{Mp;wrc#_&P49OaaCp$&?`~d7aAmcmefP_G5SdJsPx#NPWAHFym9kfEtY`M8WwcJ4CAM0p6lC+AmR@oB->Vu z$1U()pL5nTIZfYeN`zyCn9y-ZW`<4FlXFp#JqvVPRk9cHV|kwbuBok&q{uq7TvG@* zbm;6)rQ$RzwI=Sr@k0Msmcf}WS!>$%{eF7cb573AtYdEAP@yC0un)c|{=C7H!8fKB z`8E%Q{k{FSk6#PfQIlIJnN;2ahYXw_|IKHfnopbMQ=xdeN}hi-Pr8quYv4Z7X__Y7 zZdZ=}h`WvV{~j@Zy&J6me=j=zUu>L&V901M^OyaDHv!w`(xmijuF`}kmA@Uy#E+iP z-*Ln4>m4qf@S&8Q@UcjsWaMuiD#1dH`^N~vPT^P9@mJ!fxE^9=N&!u%9e^SQU4jioDBz&`t1)| zqvAz*tyj47x7Wgh$8fCh5<0P}a(}L;OxA6b1{>ET(SvhWOeTcHls}$5^=$Rgq=(n% z9J;@=gjGmr+SpGEx|{D6(qboQm=2q;KYfCVcPih?u;KvRDRgD7DynAvBqy;m-fr4Y zkmTs-nCPCr(!aRVav;yJWQ+yw4|JA#+|hSmXlcBaG{*!}A1U!R8Vjx3#}W8ucI&8+ zM?3-UH*`8aG?wq@`FNN`wO8(ozCsaGst|uoisGT)5sT8$pCAL=5p*-@KhIE+#=3Z7 zNqBae-rgJS?&DE>T>R=GV&Y6M#vPovasZv9mUh6<1B$fO099E=IkB(~BJX`3TG{<# z^OD^8<;or4_MlVyeYA{8?Cs(}CP*KmA;{PK`Ewl4=d`Poy6}Efv{^W@W*0iaOlzy= zC%so;h8YXR%P%qizFv5pcJuE-dmH=|)oJTKaNE$KPh}|99L%2f(es`lU^N=L-3n9hM+(kH&h_6D67MJz^g49aSdlCc*%{6UKMT&?PNOxJFAw z66;*P{nWr}auv0Tpg7^-WW7IUa9xGY4+qZ{f%7)O%wAwlc15cB*`vrM%~ZzWBz}i1 z#cAEPfBPDT%n{_@=D}1z5*B) zSvjq5Dov98DU>IXZBY&_zz8qIeI)CcX8RaEQa;a(b2Vs#3jYo}(wpHWI~( z34YBdpc`Q7{(}E!r}Nh;x|PUrU52`(n4Ccr_5h7zz6g%+>#x9#L-(rH9r2qVF|Sk} zVoHke3%P|?;-@@Irl!;luO>ax5G8>dgKjQ{ZLjes{$i_EQ}BZ>yX%4WWWRnE+a{UD znLDxmoF?E#pmWt=RUJOskL&AgqJK8UUg+dXI@V&gy}#Ou&hAfs1mDs_(6P8LNYCB> z+Ky1qq|Fm6LzFq(c=-Ja8?eNtF-Rn}=DW!UG-;kV3mI>VjLdqhoS{4nTPw(B(vOy7jUk zjRcdD&A6Ij8U5p1^r6RbpeahP_bG50fU#v8bf_P$Ev!dN9y?Aro#!c$WhOL#YfD|x zjJ++1K=;+z_< zfhD7Mn6+4}bS)>Vq+q*A9Mdjh8^}srq;c`NLc!v?<}oZ)hIE;@+eBV;pc z_6?JLGs<^{gC6DZ**wZCZ)hCS3AiMtSygiwJMeth_*|8aER48n_~R?RWlG>m;kk6^ zj=qXgz2_~(NfG}JQJ%bVTZMz?7CZPwx-qIqcR7q}i-Gfdye({JgK-40gCdrWA>5V-p)<65YeEWBuxl3IjuXdbMexjo;PcL7$c z-M<&E|2b?K_`0VWsk~Z4X$%?exPAGR4Y(X!Ob+*?o~O~n%SbNMxYVo}C2Km8pHRHT5E$`3q*7!*m}o*p%7gCmJQ__E!LrFY)vcOwP$ z;e}^+pFwF!;Hcik=o8d!8NTDmPdeYr)FAd`6KhLuS|qZz9$z!P^0fzl?@9n&-kIl8 zq#uM@bYG^^o~ex;>$ZnXZa4B)B~qlM6c=;DII115u zHH+x|j(mk$2QD`vy!vQczrUun+7LDkRx#kf*eDRTJ4+&ZYMOS$QTdvQe79(8I^B&i zkGgsbnUB=&8mi(sbHMq-`XyEPQcRof=hL^N+2oTE1ddRsp}ihJt<}P76Z|>#?KN<| z&<*b-XI8!?x^m*U+4zLw=eoxdhA^Cme(JCImi4#uDn6_y+eD7e_k@q2~y@q3F+9 z8M?q=I?N5;N}Quj$*itU(N$!*($u=u^<_Rf1tbl(3W*G5hcWpqMoVjQ$1OrVn%Jcx3Sd@oFhC} zjhEOXPID3@7yP%9GNu82RsD7vhNbIOK308C>j`jlfU}3Ly6p)8)2@Z7Wdi%(WaAz- z*(;&WqxV6(pALKUX~}6=fU|?{p+#B-&+C;0>BqPQy{V?oXyK6r6)eUXdLD&$Z`{;o zfU|+F%GnbgJw!8i#Ew@iyl$&L;cua5bA8)*oImo=9*sU6-LZmB_~p2w-Y?DlyTPb` zPD$1UJlnkpR$l`@lNuz^_*;d%1kM6DKP_&RK5qHVm0olrxv2ZN;$Tx-tz75BrRAo@ zYGpc4WAM&HF~bEjwU+7A$IZn<{vlZT+bv1deOr3+q&y~N4lMFP3;LLr4d*tSfY{gk z1=S6obj0oNCiF7*tB+JAOS81@q-)c^*;&Jne)rzt8d^Ia9YsOIgy7H^X}|?`jaNc+pnOu&d2L-RYt*1 zYqc7}rryHU;{;Cr9c2r3#p% zlZCF(vH>GkLRVCuyf1dd@EPW(l?(kxxpaKaeJla&Bx4i6NdxD1>5+_ban9i-i;o-DGvcX?9OUf$rmO~+_Vsh=Lg;e|BN4t^}+U=A- zT8b8#0wxYy*L>5w_cGM&{EKidY2kFQi0H3tsvO8WvZj~mvX-_igl03Dvx zrDQ{XDRq~mUeHRWv)>0cHD{_GE)-{Tjz*hij||}WpyNb*O*xJpcC)|B(^fG;q4JYL zr|`h`!AIqP`_FR_H(+M>A#`+{-ygR>Dtd82B*?(^$f5pPZjkkTHOG6aBEz(FJzLl{ z;DL_hF8Y0zCzZ*#)td9lY+8!ZzTD z9?u&%cIbjFOQqbqV|Rl~ZBAVn^`binw+)h;X?fSKaG$h&kqZZo6}q3K-kax}WJo^$ zVpQ?l+-w~J%_fc(!QiEr`rgx4S~PnS*o1QACHc2&GB$8 zRvTL@&ujw62%Mj8AoJjE%&|1~!*_1s6LUmCocMkU>%Vd%T?lWG^;iF!RSnl2ubFI; zPPfV5Jy7?h(>5^3c!~GRk&;MV-IC;qZ)%Pe%&^kJ@AQPQJ^xdmOr&=QG=B?q1-);S z$e*00)$iK1i04Lq=u!ZV8rCnHIb5fVmPx9t1M650{lt)P{%hgKqT? zD51-j{>>2@8HD{)x9*+9g9e(2#x+sOlV&R$)ze?27g{&Kkpt%)H|;GFd%{iJkafhD zAuH7HFY5HO{_GLDd&8%jeUE;ySdJ7#$N{P$MwqGj?CEcp7C$+hhrWzN6~EXrvAPnl zbd_XDh7k%ed^&6}32#}et7sw?JohcaULD;lYuuBUaa8&HAeeo`nuH2CLRh;ZXOEHi z&LMlTBNygV1L-m|gm-`L1ft6tCA@Q+>rP#*n7>pRXkeh7&Xa!t4hOpD zlDd+?y*UT97DD-V5BT$z76c+COe-+WO$|Op?AF8H3l?44h%$4K4^x%Dr;_W%EFMnp#5TF^*vv72V>1*7DNo%CFYip^A>xT@B|!>&UO8 zO0#=?tIrCoe@gq~anSRiTmzO^jFTjrjLP6pKhGE!{7)bu(n^Km_y|1qczh@?2?$~O z^b$HOQ;VOUtCA@qjqOrY@AuMGO_=+d0>$IMe-{?-EP4ti?WSh;E?43tewSQ*7=>6JFel+iY&RXz#L`r|>wbG9J{#Sq`d9nMl_4F*= zXcs0MH=)y=ekVTW+1Q{L}x`*fqP1wOx8|4Rm~BaTZC+eEAY(j1}PHC-;AsI2i)Ek zQajmbL8$o6+b~J-@ck<_F7(y>X7saMP`)AyS(OCVJ?u!Tp4BV0Fl_4y}lsm=Tvc}J$ zd%(>@=cQ(m;vAj(YfnzX{uoIy9GT0&pkcHb<*G}x>ky>*ny0PWYe<`}koyvAqm4`pq9#3lbk z`eM6^1-3U}fYK&ms}g5;U~u}t_SEDdJ5zG8>B4T59#&qSe@E*`pyUYqC^K*quy)Kr z9=moY6ycv1V=jIEq+%9#NnBS?xoe7i@gkx+UV;PHhlv|mdfMcAIwK4>v z@)7WCEN37Ycr6M1)aguy!rsXNTw?da|+#()8=mLUvL83z8qbb!|6& zkwlh#)pQD6KX87e%bxW|I_E`r;uO0zb(!zAx)Yg>=;EH0E5_;feVf((FEt3ZOJ{Jf zK3$08EVjaXOyBeaQ$mn<ml<9?6jwj$0G<-ou!zP zWQmyD&hhA@XdffLn(ev)*8}T!of4gj^DPUZ`kDD6DFs?Xh{bYDUSXX}qtp!ka1M(* za9z-Kculw7b;hzZn6mWsT}HP^^ERHNhoinH{K6EwBiaVj3mwocvc@;)8qoy~JgHzn z&N%j3BttGfxM(j|_O19aH^L56bZyYNm##b;L^^EewY};4ik};=#Q(veRfu{?D*R-e`UbXXlFtm)COkcQYhz0KX0zpF=&gi=<+0GM>d}Mp)daPK<2rQv`DCulDp9LkcKtlDws*+=A66p z7`SqHwx@pWd4uMg(TN3-V{uL~T#S)H&8fZaKDPy`qUxM%UEHC;Ojec=rU9oN`rn~3_QudvgZ zC3n7NEaRIauK$-31b=bj7&PtE&?OWNjA|xiL_2hHG19N0V$lz1FfW~aJK_qv>IJav z`O_;$eJ^lU$_WpCT9Bc#G03E7S~H~+pdE2b^GWB}AGkbt7CcT~dY8evJt5ZnW}Wns zR2}y|iNz1E){(p>fxgIyVNK-Mi$zn^c{kMsL`*D>TfFH8)HM@@&-cJFt+@m52F zKib2LY8Jd_cz9dRBz3vC7ISZZFYun#^bUt~Kv#D*AM`w6vDtlRErM~k?~ zAhyp?mAy(tEOP{Tl#nxAMlH)ZR5E?=$Q%=a7pl} zi?Pu%`UFuW;#=69V^pX)7dl+(_0Be8#5b3T&-H%wF@c<5Kq79|!)JeH-lrJ;Xw1Uy z%5_X4y)?`dZFv*v>sJ1}LGl$SEe;-a$n=rq_Z!hLVKMJg`8RJ@ZNoZ`TuFE|HJ_DYHf}V>J?t%>V%2dU4IQ{B=pH1j7xb@y zpA|ybs+0BY6|Jll%1jC|DkL(T5) zynGz(BCy4PJWWK{M($hkW!aSh$1D!FZ{>WZ{)db-^8df1$5!!l|DXRG(8sDd1DR10cj{j!l)T4kaqP?;mHy6W4t$b2+WO z7V#SeI1lLVzRhqaY;AUOE4A8TjT>&c+;hh5I%grDsYX28M01t_&JDUR1(KL=u!^7G z&GP5P-FFbe$sncjqdOMlv^O&QAW{X#wq2oHH6j*?^fvd`evS%4YYkH;O?tOz^8Pyx z-znQ1e497GIYXDD=oUcvaY?c-N{*P=I~@H8-?l-zD`nCwcqmWdr~xjIa)j=uaU{}p zY}L&S%Ki(|e@an2ddBCZ+92iWLqjjaQvf4Hd+5OaIZ~Lc&Re3m`^$E+^`8X!-^<%$ zp8J2DmC|u)A1DLP4!XoAn5;vqQwhjA_;a`?eA@90@#4&Vq>dF)2%YrbjNm8620Gzq z7_A8tn9FnLPvR(m_a!x&;%Zs)BH~iVsXR4 zGwjcE@04N*7o;=t8HFsjzY1Lwe%G8j0L}K%Z@v#k(VfoV?xeUy4T3Nb;qADVWtP1yKZ1g zX^MFTdZ;OmfCj#C0*W=)V=ETgB?pD9Bso9XK=4nKsYL(hj)+HjwKPKtFUkZYkLM}& zYzkhjsO*i48Pepf%>Mv|X~CzXv99X48!`sa57f((HO@}9LL zu!ATGKhhf;$LRXrvkJdn*voey*DT0qJ}Ft^t<-alVW3IK7)S(89MFV{9 zuacHOnf?}z$A~}|HiB>TVEvL~`2j`_gAvLg(^brPICTQv0@992&)EXZR0u(rXM2&i zdHF2up(lOMNHj&dAjbf`n|!fd4K39pb7OP(4H1BjL)#OvRd-j=9{JvjLl549J|S}A z0L+A+%Tlvv--hmW0>=lPsKjo{aS8tlig_DxwyLnv1h$5jVU;D3K(rw3QwK#J;2uJU z@|{e_!pOPg-D;(ocE-pi^H!s?FA78zL;RFwG-eJd$JRj0^D@8wIh1J{L zy~!;~vN1$)&Mn(x65C|z1T!$Wz%t^YsgMWUS;R5aCTK26q9a#NN28vF&56#B%RiNt z!HTa3rE!9%=vXB;*t*Y{&&WIp(e;ug7E=qQ{ucr*lQhZ``-&V1VjeL7+5h)->l>lD z$Ea03O5xpG{ea1m=KDe3)niufdyFM*DMhhnkAP&wL0WfDjEV}+>c9#JW;Lg2#PmuE z%8R+pJFl*L%Ahp3*{@a$!(L|i1fL*b?7H?wH|CKFlh$;{f20WE)H;xizIN*@R z`{|!zu>~75CAWb7`s9C$j(s`mZ&ffb8nC%@qk434tXlUrS>xGE)N%08cFN{|gn`m1 z;aRM?>{ieq&pqdOo2-_=DV`r|SMr+v#z$IfJJ35#DH~?q$l?7haJ+w#YGIZT%Rp<(ibpQnkNkBuQ7mPC;7Fm{>VNGLx0{NM)oV5OF8nh`d83$8oLKCS7QMtA z(pVcfwnPkFASdIpxwsHD4Ha+ZLyIrd!LB4_0-USXhec6-j`m|Pg+mBkmQ3@ikshlx zNte2K08ZOgHI3)1k4k5B9`njx1)K8lwh=&gMK*bCzpDG8V+HeGm}c9bZ@;mcn?AAI zJqeAaAa8oE0URE5%? zC4^;PUwQe3cTgM2>g+7f)yGxhGe!n|EOtZ$dA^BeBXn@E9R}&NE4ja4x-Sm^~ zH{E*hsk=IL9@u(Kp7lyo9AFKiah6i%;)Vvo58N#_c+gK19YXM@pM8rk73}_!``nB; zU;fm!+#u_{eL_u_N*-7n57r$YtBi9P|5BpPz}CfY|2%M5W|mX%T}04C3~hMr+x(lF zG$c^mCH8;aQ(h0*F}gQH%CmHRJ5A2nW{?&8ROeuX%#EK&q9SZQ98Gi6TFha}nE;(}lW=pQg=;`c(^Q|?38BBPuw_2J@RQ{tdnMDlFfP^aWp5gN?Q zeo)$PP+Fo1_o7az7Oxpux(z)ekxjMQ#Ve00M5*``-?yhICcG8E9f9kTI5@^AQlA%G zW~5hy$9*nYU_Xg;qs3F}W1w`y{qp3aHgE^<`eFEKzn^foVkGnXvGu{uOX{_u>sHL) zxo&k1{~RG<%yoZ+Jy1IZPt^deLxLwbI4LZS3m>jYQi>R|*1f*m5J=tImY!}wf zmRYO5^YR=)NlE?nG3MqmU&>%>p~JgE->08$^*$-x2W}hIjuu0v@NMtkl6ee9TVijP zSMS=52B&!T+Beap6thORp98lEoxg~Lq_q|W)1+atF&ib(xclgN9(gU@-Ox+ton0Dq zR^WaB=Z8S}I>m$8=2H^}qQM&~?1}OpDEyAbj@JCY1a|6@DVyNSZyijrW_X9usydcb z5Q$r%wCEH8HZ*(2P+0$19d*sJW;u-d?IPTdF!6|bGgRj|T!ndqfn7vxF)N@RWhC%+$3CtQ^DvNzb0lFNCsE1ccng%$B*obFa7ZhL%zMSfx|~<6t^>8XopLp9I>B z=I3JRU`uTY9UX*8ZDzyEcUW>V*n(d!Ynk8}#w0xKaX3<_D@P@UHr5-CDP8G^0E!)w zb^e_B$(mj@-x&&AT3oR7I3Q84UqisSE4o3BKH$M?s+v( z+&DO_ck6abe)~|f0dqh3yKHH+JMpNAw^bI5kpa==yCiNxtICge z9^iPr6FihrGMif(zI|N#sIglh;@}n$lr{oSLZSx4A#-XoKFz6_x;FH9wN47>q^95GroJ}JRTsQe)KL)-uF(+?z^~pBlyMLc(7>8x#FhY@&i`xZxbJ^& zpvMNe`acI4b-xe38*{`!eP5C_5K&FnK8Nr0@!FOsqzfGUJ!qv`?S{UTYnv^?%R3x8 zxwX|^ayN?l=cISB=MNgk^&i7eQ4hQ}Grezm#-z<3&s_vji+~wk`0;ftW~;J$+QZdZ zNqfu=z;(fM#J79UK)EVQHMj*}LK)52gC9S>(cJK&n2^XB8l z5|aD+gFK(#jMp@*%O@o4pCJ90e@X`)Ej2Hg&wy)yPN7N`%~8sOZ)OuuXQT|LLy&4( z@_L5`-E(3nd56>=4n@~NwSb!ao}p8 z)7*S2Hb^=oT>JZ;iZth-ddQnXii$vDuYwPKe};JYVdkm|I-BnFyvJQgoUeDPBbuTL zoA)jh!-GkyH=`El&sTEl7J;jT?r0X*dH8C)AQ??hq}-Y%!qR2+3x>|AL`D+xWSPv- zZ{W(IE7~-8Q^QuDWmBB-`LF2Lm8_DbUq|2OTB+Mx1zBovD1j@5PMz&+rMi}{VL-@6~$^Bn3=j7cvr|I{zmZ0pH|8i2K4hjQd3R|T-XsEC9yso?iVPy-izf4e_N%EBbxmiT zfbW+BYayNz&7ms-U@lT3Du6lvYx(O0iu??wk_#ycG-OqXC0GZM{<7iMMJlJ5{8bsb zo##MiVI!HTB^K1KkD`%%w)IglS!Huw`}5sCT1gkF4DZ`rzA3tO7VN}kz_yPQf>;!V zp@=_1%>B>WNRTvbifTr1F-3ut=6q)HTYqc&Z0<;{u5!pv9| zb^PrEef(-TkMMYPvpsYCgbj6IZX*IZ1rfcl#moD)5lM&p(PE-(&%c~UJ3ON&%#R=x z%rES&0xk?XRm$JEms_=#9i1WPnAqJ}qWY#hpG7dr?T@GLAtx`u+;b>!e#sPbOHTJg zXUkTu&54Rawlgc!9l;hqjt|W0yn0WmO<)@g2Gd)+!(Md$;UB>ZLp5}?M=Zbol5frZ z(#n+gY$7vm&-VuQBLYDi^gd_r#aGL> zKlqB2p0}BLJz#c}ZSSl*t#~-*9p747;<$9h_XU&9AU_56nS5buxwa@|sm>ObYnGvn5}{H~CiIip8V;0jUV{GHxmMBuK@n@7^+T z+fBiw3hWJeLFb=^$mo$-CEf5M@Hg8``(!6$Obf$z`HDduoCn?&VVuBuKHD7T5G*|Y95Jh$Pc=AbGYXtDbo*MF zEw+o4iKb#DDcgnwej7@~6;6CyZ{DPIhbrZj3j*f|-Dc-Wl+WDP1_g}6EuxdRvQL)_ z@7nr&n0gxV9D<1R6M(aaj?xx`*`yH_bNs0yLj64o^Fij$c$KY!Yhi(74O)CG_+_wz z4n-n^;Q6b?zx~wpQP$^nm?9Jn4nJE>k4oN5vqv5(P6B5GT?WVvu;UyrN#1wgXAXIvkK+lO6FElx6^1 z-{|#g{yjChh1#JT?2IQW1z7ywB+4E;KH`fOx*S-NfzuZC;Ms;!P*gRP>&mr$*#0d4 z&iZY@`F zuQF5urv;tK^IPXO)$Oz{{E4Gg(LHq!sU?YLXezIZkGPmixFv0Y(||5P=JUfaour?p z16~W?Xe=sBxHG57OxjX#uw0Sr5ToURQv=T1n-2Zq=qdT_$XlbQR9znNIiGCARfOt> z4Avu?ucS-X%Mn!AS-e&Mnam--G!V07o)C_hNfMl8R1wV44LZbN&5x1AtOO%2@UO=T zS&keDS;s$hI%L;mXQNakR`jYXBGSpqyDP-M+MJq!V=7{!26(G#dq`&GPVgmUmp(^l zt_-JSq2*CyEB{C_J>K!0lO4>gPypNFm}a83d-f{mFZh`R9POFSe_~I+)8HE$OMZ+r zQ{XyCuZkcCj(L7UeNXX>uP}k(jnl5)8wor47n>8-*bPOkIXiO=$S^dP1;Jpub7?TS4V@|wxm3{yegWr*AEzZm4*_1cJPvPx0={o&q; z4Jc0%wmOjjiW)JNV+TpW3L*0Eox_wVr4Qdt*O`ZszMQ_|(EvZE6$hYb&>(^F9cLgAc7+`y}=mEzA9m2(TysaM83Vmh^c7g}S zN~fru3TMh)&m5kj03GwMsb~0{z46M-*ZI9s}KOzwcD}v_U zz^IKAIB%a7$ER<2P*wl3;l}?|DreNp^YL7;NlE@-_iy>UZ27Wd`0u3l z_v>#P>r+LArN@g0AH?FzCSTu%3;2ngYJt*N;oT6*$|AfsTd}4f6ckZR#X*-7DB3vx ziI%SxiOF#-_s|~v@hri1$hM&pfJ}8sK!!r zM3|YvP-$nOW;PR)JZ%^KNCc+!XU1M(0VQ z4=4K^-0s;n+=P~lDzdqZ##*Wr$?hsegSJc#vJYYwmya~r9PxKOOyg$S4|EqK3nceY zqllJF*f9Hy{%(WPNWsCtzeu(2=4{Kh=2vXy+&72mM@Qn zhubVgY18Q@7nMGS?*4(fa%T>31n^vWY~mB@iY6`@izU)(Mpma|f2>ga2@zYi`b)MnT-+lm5 z|EHJkf5P?a*t;zEvD}lqAMz_o;S9xsvxPL0OCIC?8$?L3myV2sglCWA{&BX^_|xB@ zQR6Y=_Xp=4yHrip_I@Q}+(l|kLW74&x`+(_|E1OT#Y^JrlWXS}Zio9>yh<6QVeD+uhwebs&cJFe;qIzrF1Z;yC9d-Pk9<8xBe zmw7RcpEaK)j+2|t{+Q+|Vg&Inpxbka3l=2VD9m;e>sJv{Z0D(7;mxbhy4C90IcxWe z7y<4KI^8qYBImm~Iw}lr9ZYv#`j=nX<`mA&-B+!j=Ta|~cK~++9c>ThFI`e>l-1Ym z;mBRDg2mzjEM1vKe($SuyxMW3g*}5K=)$Bfo*b#Z+r!<=8S~eweEX=rhUBKrgZrm< ze(!b%BOIL^K*uagF+>M;5s#$fjuvw*Cq~TuR1(wq?K_)jFvo!wXA9gObY#1Uj@d<1 zZpEabBT*9H+Fxo>Kf>6mQGSUKj)ZdbQx>=#=-T`?KT7jCdqzm$);;~wz}(ICDOj!p z*=fU@d&`MV1SY4qpbI6FFF6pD6BR7G6X0T<^fk_H z*BbUG$MQc5$2gRUUzN<}w8!Y~2y}C*2>8kLjRLm@oU`D&3ZCXa-GBO2TrJ9?_MHEH z#<9c8y(QbGojjd%Vg$z{t;j04k z%l>w<`2_7z4&B(cVVxQIHCwNnzjI6;{zGQq=3y{&HPoAvuMFwJPmL3G z{uuVyw)oX|N}>5C;AWwF=gG&F5(N3{L%zm&i`lVg9bXEzjQ2t#Xk9 zHwxVaYF@oa>?qN&hCRy-2coXwakZGSlSlcup^J5rd|owh!_c*xnx3vk1UKmXVXl-p zF8$ozq(md2o&Ma+ML^5kY7&l42BCZBv53rYcgrTh>X?#@o#(ukndx*d(>&!hbAD@6 zY^fD+{m^ml`Aepa8fIdC5eqf;D{n&QdDs`QS@Ui9NINhlz85~vd!dukbs;L(VnX*? zk2#s@G8qt7SsjkKV%z`iV}O`HY?1-oZ|FY%)P3ncIT?u8lln2$zjrw>Lr+J2s&!qx(7V`?Rc z*NhF`)p-vGoWGRa{*+rLYcW@NUd!k@U^tEb!Jh3zXnIB{9{$T4VfjAx+62xUts;9fDwWS4IxU^CnO+-&T{Zk@PYHx-8!{VAkUYleBR|DP4czX<= zg`IIc3Qqp1v!q6*?*>Y8fw79nC(421QEw!G`vG0+GyUH?<&QN+7EEdU9#H7KJx!;d zYR$^5F5H~wq;7^iz)I-SSarH_r)voK+)H-ak|oha*osVsTh|q@6%N)V>Bikl(jBSu7tl{vrkoi7epTeBcps-y2v78BIlR(SLJ0l{Zkj+jB<10qMGDn0ht8$W3$0k-BW6l zhok(^`xuJ^&U7UgWiD-~g1ANN3mR3?{0-NiVu@!77fIdx$! z04@#I_Vs22;SYwof^yEN1s^wTOUZIiDn^B=Sgs8-y=04baQ`e^W=M^F@mkixE99=P zzB)m$H1h|sl?h%V@^v1Oz#5Cfn>Y|I309XE?}9N&eo6m)4GdWnhKGk+87?63X%3Pg(mS9P9D8J*(PV!+lT3Y>lAl@j6+ z+DJqwzVu|(_YdvHbO2Z?83j6?Z+`{McT(q6J2n~i2>;1@%KPB>#rS27M?kOiceTL0 zEf6gN)}tmmT@J-dp+guGh%)LCKl*FED4Nui82Os>mI+>Z!sZR1o~_%wjw= zG9@>yHuri2a(PiXBvOgOI{E6*$@6)%5uYG~?brced8=3UUlk_rEH{IBI?g$nzL$*1 zZ-|3WHYx8*@D+L>zAXaL{6KBp{VTG|2h@oRGS2uel+wQXp7(lAvT~BqD%?M$Gnjky z8#X*2u)I~}-}Y{mYOpD7$r+XsTLde$J?Rr6F6y7wnNuoM)STuZo)>6%&UlUH5?m~y zIWCHAW?8z6-x~+YRF#q)J-R#GGnsqn!6(OHO0cN|=l2_nEh~@YX|ZuQGMEl|G}wZswITeSUBxp@hk4RkrDNRf7E3{0hR?};Z)es)gYE|xaUsBlY? zm_En8U!eh<6?FW9_omg)ceRHC4nL-MXpHfeyH6O`qHR26E*!D5r$GVE61tV=m#!G} zlI;)I%?rcEi_}?h!>L}lo=B1^vnR+V+@JyX9ysS`51Pmyay$3@K`8VJ&1Z70b{2c3 zbYX1UH+JKz@!1?C(#%*~BNquM{_)x-D6fu4mXP211-xOP!z1w`pZ~q&wr6}w5C)=| z!h1&0Rq^AZtoxP88`nr`r*8$v}{h%cMs!!Z!e7<|Twb|2;2GS}QnQAGD| zllfnXf_|@}r?dJbwCPnsj`>#q+wpD$x_iST#FY#C+>Q2WA3I0XaPzs9sn@-If0J^t zF%YwPZHa=b8p7`0zZ%7AE>zF-PFj_x@5FzwcI*+Eq+@;9R51=w(X-Eh>oWD>Z}R3h zs~i@(_FGJ)Ey8(bhCSBCCKorHJNM$PG812dwm>S zvU-bSMxXFtLOo!EJ|he4kkbLfMSd&kfSqj*YCr7@9R##@0r4+*<80ATuV2~3|NJG5 z=nSI0f-SEs;Y1Uh$)|-FT`tj%^sJKqdnw=5nrOy)`ta|xgsNcRG-2sX!L;gG$5CLkBc_fnMb`Z|elAGznEy_zT>l3r#nhpjALBzU&Czh(mgrs`jtx^Y{;;jDLHIhN z=zG(4E`K_Frl>-P?l|rH{4>sMih$LvMZUP_?3KA{8ogTJed?`&(ojX1N>zr=f=A_# zn2bBEff!Ajk-`1%%Tqb-M0!XGOXv5}2ODGifK!Anl#}M)?TTY3zg@cW}`+2kC1B-KSmMx?$`YRm2A~I&h~2-rJ3C**iItL zqT<}4UL!H4C2KhXgYw_tVgdJXtU>fC<52_Gr#0DouZlOYIZW zgt+On_AVOs*GRgnhN92i=a9z0HKnjY67rc-UKz%!Os*q}3c|L7mU3g6ZPRzL&H=K4 ziMC=~V?6NjHVM%14in}(rQC>pHyGZVcE;J**eu5(rJ?*nvnxy=;h0VsHkgMuH|LsCiR&}}X2ZLp@TVmDPbfQAx6v` zHF5vDYBwepnu&>U(1UlIoyLv%C-fI^oX`mgj*q(XOgx>#SNZ#a+#QFznH}{spNh&N zNppnyu*4HMcIa|5`w5I%M+*z{M5*{YSfG1cKI2lWO7y_FznR(=VCC-Dj((*tzhU1( zkjfm*aQv$3{0r{-{cWOHF$9!dNi?JwX=CE5$7eC6WaN&f z4Ua%P8rUyvmuDfHEn*{jw9}-hROa|KBP#uiH@O9!^=*;1IX)#Fa8$5-_LLuc#2>gk zqTqEueE;}a;51f{i*wr~DNAs1^c)Y89&i-Ukv~0OJam zjYUcFfkk}H3*a6=7wF(r6)g!7Nu15>t`P-oOB(R^UIQZN;D6u zZ9IU(hA#3g%BsbEy0$O(^O;Df*M^J_d>RDlzQ=`AdC_1dBg0N4CUmAth!2Ai>Z;4- z#q4!jB#AVW=`dx92QCm-#G1;ac_)BFhfeXc;r4{}%W0G^sNK0~*ngaVpk5z8(iT5B z+_1oN`tPt2ROq$^-mheCd+3&{J@L~d5vNq(ds$w|iK;Mzl7X*fAP%!0$iM|p1ut?V zW_=NoqL5^p(|R^|Q%{Y6ys6T&(<*KuctV+!nk3Z#x+eS8p`{;NE)R=DVTq_!vZZ(*s7-gFM?#v?nB1%RNjS`$%I@F2cO1&rbfs1 zTbA=M1nw^uDBtE>=Jytp4TO5`$&x|G8f#L*M|+<4Rp~ZrVb{v z?ET9JN@3J4ACJdK#w|8)GmjM1MQRbEHv@sYf==vPpVdRxy(ib~*XenqS0%R&w&ium z_nk;QZB7DE=1+mU0M6OVOQWH!LIc(K@%V3=hXpex0vCwI6>;qwxxdZN(Bj0tp`5{R zI`6Fx+%*&gpR<|v)U!vcAm&vY7IGH9{U?BmF{JJu1j3!baEb96SYk%e%3j}ol5T+w z1rL{opMIwh?!@$|Ez*)|1|L*90zFuxT`V<*vu~t}hB;LNgfEK(m58oq#EED*JcDC- zarEH2`2#HQTA1rs;$VMKdJ;v%8c64+NwgvXmRc=zZCmYzcsG|7!nGWGuym<7UC1t9 z1Gtb11W;GxfA2>+=&W-|y{m@Apl?oMlwJZNLpyU9hYC8-Dn4+EM_x4d4zP zaXaMA*J*>8tFH0yZT_gTMn`HE*T$aNw?K$O@+94b?RgFBzZd2%l_m2ECTfz?^; za9I9LUKIzE3>|BuHTm=#{}uQ|Sot4`j+slLo_eumsKal8;rdbm5s}7?SfaNtxl5Ce z75NPX0>RY{_}sBh2gWXi`ME~U^0zvV7`y~29;O1ei|6*OdNhXr5Q6wTu_-c=7Ev+2&=VFI4cshrB;hm92;I%{cyA_HpF}t){3uJ{(b$exTJwywD=H3v zBg<*%4DtHoXcDa@1ANYX3a}JY?zJg|pHfs-?`z*pD~_weRm79f9sD>+?(cbap)>F* z0_DZi7L$Q}Er;A0qref@*>_rq&A^RAcjfFLz_XUA+biG6;WR{Q-ys09((z5=;z1`{ zT^4^ufE$Ib>y#^hAcHIOC9{-gWcPH{Y_3R=_WR!ySf(M}DZC`Kzzstukmi>1Va+f% z_H*|We`40cuTI~c(_Qxrqd#VJhfl#&iq^iK2AKM}e9tJ#Hyhg?T<&bE zWTC%NBXm(-0j?i9gTph{h!0ZM=7!3Hb)U3MJSI(kcjY|Sl!?Yke8*nW3S2LAwVhY) zhuN*(crKB43TXYZH}0=Y9o-*uZq2SB#IO8R1nxI<9!kaoJ(0Ufnbla#j^@wu*Rk9Q z-=|?UivK!3{As0L2wWF*ZxE-ti#{`cTVoCxyV@SrO;W*##?_| z(Dc6+!!#x0EV87W_$nMRp~3-H7{b(G46TY&%Cd!T$g_J5o-eVKl8B$hd460Gebuj% z3J(460r8r_BhdLd?^Vqoc1|T1boZ?r#^gdL)Il3~LW zba{_iT91y&CR~J(HQ|2-t`=4|;~Kx%GkWY|_TA&IT~iF~RjioK$J^B2r+Me~#$n}f z7+M2e*UR*2!bhi{{-)1-tO@nNNSVmmigwUfLcLiPcCCt!1?~rM&gJ>;%(8caPl*R~ z@M;iB=6P0_m<3L*Fl@&;`j}q$`FsZ-Eg6Xn4}5@N7Fn4lohOS*yKMf$>##S!dy1d; zaZdyS^Vcjmdsq%@QRa5=@bl${M4WOkbjKYQ%z;YaJmzT$XNE|4XaI-{_AJHe-nYrho!5UnX4^u4C)#6 zuFEt+EE`A)VIw3B?G$&tl9sG@ZuJ8$7nV*d3rk1k)fJ!eK#W|trk7|}xR2Ce+WRKl z^QIoZ;0hx*@U7zl_d(aT*2ZrH#|<2akvo+3Qt`Q%!Kvo@rI;V}PjM|18UH6M$Q>CS zp8o^aGV*a}j<|QFZR*(fl>#RLeF2>@4I$?U#ousfo&g_xD+~S(K10PkXK`iT&B}VZ zW?XM0PZVcJHoP(=L`qRGfJ=k5;A>YZx+28@n4P-$QRs+(LdthCof(v0_(rvd4#rHvizz9kH6n( zUOHoySc(s|@^}Yy87@6uWgq>ObH@UrCBWZ!N837b?~70DP_UdLu^^7L`TEuQG{$4e zv39*siyguY;Nsv_twY2nxjxecT?}q^s}RveoE%HJ`tQ6!J-nMt(>5dkYv$p3gmcOd zp1lxaSmq~7lSk3-mI$P%dV(>6+lx>!6qs~|WDTN4{dZ?E9=mU^?id*})|ttm@X=um z9bJjE-6=k^5yZ@o^mq?k1pG}*4jX1Hd+~A&a#sp_@OSwi*znr@&X=zYZ9x_5-&9xt zE(|(eI{Ht03QINO{OA^L)s-2e@jEp6#w}H%O3Lg@s{gGf`wU&f^6dkP&yA$Em7`8` zWS1oKNA`!?;n%EO&ZY;2E(=m1UI=s=3IZhKdA@C}=KZHMqIU%HnqPS)xq>592wwQI z?I*$^d=PZ@Z0KL|I{BVg6_J=N3)mvR#Ty{w>axDyh7iJ+s#^?4C;`yrkFW^4ja3J9 z#493q67CYrCT#fX&0Mvv_T&{|a~CrM=Lej7PphSURN(c*1iw?SQOeYxql0SKoy}6t zSE#eS3--5dcr^dV!CZBny8{1fob2;IFLTL6%@*{I!wx2k^EFJ3bB8p6IZTDs%9{qf z_nn~$icaA2USOPTR)VbV$>c3{)o58)qJ*YUADdzlLuw#nWrfeQE_4oibsq5Uk%k!~ zBn9>$A96FlzUPeI(2l0x=BaV&bLcgcN%E`;zB=4st%;%n)UFI}m@y>+r2I*HJ3AZ8BR-ZFC9Brj5Ol#NNVDX%w z^NXjnUF+CCFH0F~em(gmsj9Oj!sG!p8GC&#%Acx9JK!9l%ec{x*Q~o-cHfo`pcZld!3vvhgV*hH-11DpeNaxXnaPOgeQpqArFT?1J z(%$@SP3J~>k~}Tg`x^IW;zH2I%W)hA;LM;aWi;tw`4RPuEv=1Nu@)(oNj^F6<^WaI z>*7wGPj(58LrtLz;x$#<-|@V|*{BmMV-Mf2K3y_jPh~tW;|n-y^W1L%&KNjv)F#sO z8U2;}1X*;b)W0eG2?H@X*f|dFynkA;+HJncf}eIW0^{VKz0Hsi-O_C1M!WL9P+`l} zxauF8UnCovJ!=vzv`CdeJVQ82X$gz8OKdAxVt2v~Zf19SE?LDih0TAG`6>w`M2L`( z6*zrZzLkAXdY;4&Jg5^t{@G~|wBWvbj+x$Mns@sUH>HDF2R^fOp|d9JHTPy~TjjfzBwp*ZGNXr-dDgaw&b+M3|C@TxjCkM+Q=f zZzplEm4tzN1zkAKMoqfCfL20K_x02_LTZtw0V91h#}%&J=G?VROgOI9gzn={%y3^q zo>&`|LQHn@(HioRu!BOB0lQQMH|reugTJ=lps$A;cE<+LYKp0oVCY^j#4}=C5WaB z|COmPOfv{rKB9g+%d6K3kJEV~q9UH$aV2;>PFa5sdpOdtwkzXlkxx&F zuCYbv^{{;=FWi{b$FvbBu#?pUD6odmXk8Jcz!ZvYEurmaJnt^P-0p#OjvX_9A8IHLt_+?N=>+ce(A} ziJ=(``&{4zp|jMq-8&Uqw9hPgwQ4`xD|#H#89(YRBebTp*k`;oVFnyObPX*{tzwT1 zf8+~X)(J0a1Qd2nT@Ek)O}Q#ND7QHAdjs5a=n5`gY)vVURSlRwkC+;qDf+z8bg$Xs zt6F&Rephi*Bup0bLdVWU6jmW z4&BpNJ!7ilVdp=-T|RszB^`1$E2+vPMa@r~{-~YeR1o$M*r4P8tFYl38-U^3ZW2n@ z@bUrHwcGm3{$f7N%(RZ!d^ecdWr4011;6c)KnzmBQ>_DpBkzz_-PLccO>zZ}w_h4( zwH#p&feAXqr?*CG4tid3=32&4MKTxRF^Gb1sRj4D9sIC13+Q34=@E1jx}Nv)U4#p9 z3aqQqHt{EWZYT;_@#zVXIYVsJB-qD+qX*9YSlFEXIDpWRQ+#e!sH-(M#i}mQ8bRlp zKbD~y^9j8pY=5+1cp~uU{Tpf8iA9W9q+<)!cjzbk^+lyu8oKN8spw;8FHt}|8rc3A zHc?-rBydS z`J8yeQ)%)F@Rhm+vzoZzGm-+jupB?edm@wX)@|}aUK6oOSW}xg<7+9u=vW~C*I0b_ z8@LD1HI{|7jDB97qB#DFH_Oq69b+ap>g+bSd5ll&Qg)UIbK|7YHEa3TZq;2%+BvMW z$j^tJBREX8{Y0$AX;`t zt-X0&2DVV&2PboFr_xUz?;w=&g$8veMjz7=00))$@T!06td*qckGSZrqmN8ZK2*I{ z7#Io3Rh8v-5ly09dqX=3)){(6dd*t2D~pECD=TC^pyYg5%y<4)kkrZ1=HJ@aiX1(L zIuH#TT-AA`q$zyb}*3Iu|HU@BB zXuBd0Ga>CLyns1kR4lNv`hrf@mX}o%NkZcLzBQJHOld@`uz}5QrdI`JeMp4^Nx&h4 zntG?!A$NaJb1(cD8;78>{P%a_$O8|&iZiWmewWmLB3nuj{@x%Uf;9`DO49S3uul<_ zG3P>^aDM*WrTP)U$A-1EQ#i+hdk?fPkQu}T?JnK^FBfmo&sAfI%Ru*?M450bMu+h5 zlDP1l86-Oqlmp=YVuD{-_@Qj)3mdElowr7w+C#G(EZW&+_W9P{pX5^%(Njh7ZZT1A zfQ#fJ59qfn%FozxGB<0n%b-{gEwpk=~N&0c;5?gTnQdUZ}E-00Ag zKSQTnBUrw{QlRK^{`v^}SayL8HDucNZXii1wGX7tC*>J0dR+k@_E<{LIP zJ%28X=wI@%nLX(p-gCKPfytFHyogB^p!<3aBvL$1H9+OD>8bCtPu~FDTdQ2@MLfhz=*&((;sn+G2~ws z%R1=;`px1O@13$}={XfoLpLJ7csB2Y^*1Y+tnPzTqjovAD8YQ3mS=x>(b7qb4rZLf zf5{(v_iv7Vq9cIMJh)nLjBcJp(Znx>Zplcj{@u+2iH4Y+$ad4y!|pzz-C5@|P`E#s z;6qGO+IgozJF(U|@dXF@Cq#QnvU1l7!K?)$V_(-#8s=zG5#~Wg=1q@%rC-pl$$WY* z^E=d8VXv z7_*Im|Io-EeCt>v5=GFg)6A{z-KG_48yj=qWK{5?zjhlft!=M~psz4lD2O%*qeaLn zv!HsDb2^OGcg+ru=R86+BpM%b@LDz_ zo1ydKgQu>F<12}mJVBQkRv_Fc2p2hOIyKYE)l662tE!ddeP33AnLyy~>|WD!c7@!?2kw9}l%kF5w8us$P$m;=CJuL;P(u>SyC&<}F!wKH8})aD&hd=DLrI{8(2c z<2uL6Qq2q&!xqafT8<^-{^9CCMwqB?5M0c1 zSByY8ctZMwmJw_@9&x6i{8%PWJb2%A$^4T@1XcvCpWglpFV25;G(M*?kKHA}sQq`E~?MRfENYi<9q%lkvou&dIA2_9v0B>MiNQDfeZzvA(- zzFiYIV0>{?)T6$JW4~swsD}x=Tph3urBy_aUF*BApB8S+`Q{8aN<~x5471xy2=n_; zNH(~*1NRHKU4e9lcx9VGrB+$eV#hO4dC6$yCyzex?6_8Syqee+rTjm?b{r$+=kvb? z#jTkC<-%?C|0v}uWqsQHP>AfyyVJla{E*H}uEc+5q|zo8Q319DxaC+a$S@_dQ;Mu) z2`Rs^iCem)u~YxO2Tx_5$_PeC+6pmXjqncByBg*+93v}Zb440%Z{_lP=P7El%ieLM zbzJ<8b6`FJt{&F9k4CZZmN*Z$kMdE~@ijf;Cn{FQdG5ZiH3Q3qJ-nGPBb ze#5V4+Jx1#s$u4mj==qZPR1O6j@!-`TgoU?F7a%ILX3R-NA+G=>g$YUCn9S^I7wOw zodj{t8=HROK$GT2>6vd-KB&C-ghKv0iR)-h$Uu4)Hy*fh=n%Ix#g(rL3v&70(XLem zI7Oc}pK@9JnWi0oQJWTyNeWykbh45L_o$kbJrp!D!Cs3tty+fqp8Fi1t_FhAFj9z5 zQh_Um?%hm7Z2hxGaxRsZ{)1F?Ws5B6hE)&j7@odfvm^G*gi90)p(_Y^_tu=c8P{6> zvDLGX=M(rW&puMKTzM2)y$;=$!iTBIZ_xSvKx-A!n60iwr+B>hs{l<%paHKCp{u&w z<#K;J!lxLxeCY6Ti-kCG-TdS9J8Cj|DV5&t^Amp%l8Vy3oov|sFEE>aaXfstg6QtD;Aq$==pRTS&Z-Ybw*H#TY^9#f)|$AdpP(NREp-gieQDr1_KYmxl3;DeqKS_VKZ%V67QC<2`JIe#UGQ~3a^mzB_LSr&?5qq%qbd>SI&U2F5Z|~G?o>ieUs@OZiL1z?n zIqQu4yrbMq{o*`UdSldVB36oY8P%2(=Terf?K?3r@fHEy8m&*)DJBc1cx}V4JKLU9 z7j7oyWYzB)lY*&PzdFs~++7%SZXfGJlSL3TXaW>8mOU6b7`B>uJ{=q`g&c&3(jODT z?!#y3>=nHYr{4J(lO1u>;j|K@u;GDY}#BvWrg$5n0 z&*RToXuikRl?fl#sx7x#ygkBC-vf#8An+AODQDrI`dW(7*2giuMsuP|ueH0|N2JPo zy%Y#NraEU~3ONAYHPH?F;jEi_n!oh1XZZ&6jv6>p^F%Y-sd9_%oYadouyg1KuIj!K z>MwS`vFfWD16G{zs}I@(Zm=63XbvQ@iK%2H&hlg#^Ca>b6DmO?(OK-{Gso>PI zkkA3H>VXLo+;S3wjEXp>=o~3YUKORqr>VFNNe5ESIlr_-g5H=}!%1E@_}j@6K4wC+ zC3Udhuu1jBjG_%+N!uNHoiLE6zJL=ol-v!R3v}<+aWRFWS!C+MuhD*(7Dv4!E1)^ zJB3h5I#nMs5w_|d^zA$U0}#y)-ivNKt~+mQgWdHnE8ISR&(tZBBs5$l=TvKs=9Sh= zRYQQY`LA>%YTdB|k-x4!CtG?7MqVa*r50;zAZHy1%@1o`4Z}CI6)fHIFNNS@{Om$a zztGIC;`iRnM@y34c7ieEN~8zc2hCuErX@({d(%uhXv{o*dZZ?zl>g|7DVd@wF_rYj zEeEl_6Pk98Jc#xlmM*uDfj93jwq*2J<51TSS7QX}{7<37))`gID+29heK@;j2200^ zQ*1=i|F4ynRu)CfOXl}eJlQ#(dc4tTlJlC+XFZz0nL?+v|MNi>BST7Cl``&zJZ$EF+nw^=64^jObu7729u3_;723Y(%TbGiw8 zEG)-CiM^@b?GPu?;NQu0#+ox_c=Zhq`}ASU>pVZy{o&2VK>FyC_-_vRb%0xB_Fvhn z^>A)-xA_q}XW(>UEoQo%_$0Dc(nbLJ<$24QT>GaQzxLYHtBYGPH))_N#3 z(WJaAw}2u?)n#+cd&es7_3p}oAsjem=uDq;gf36>7@Dr{X>B7IOZ|>Z-q+T1(&2n= zPey~O(hQs;boDnKe_yzT*jd_G^p$)HZOV*mw&yrhje2prvibe>6K~+;q4W7_p#7&K z;%g!cNpOqpKdx_yip%*ft7ZQDf4qhqC?`TMpe7b|O-$ z#vtAcI3#9fVGGaVpg$OO4<|=h%u;pkmfN+`kP*c)@0(r}uZJrYgkkw!KHnlWJlk;T zSb9qZHjPf4)Dhyj4Tuy85*GX+{72FSoFH_+Ny+XdYu+2^DxEbh!&dcC)_97(van%L zf<0&HJYI+a96xZ*$riZ?hY3H0?E=m%7am>sq~X(s1iyK;j2ne3GFd(hjtN6}4m#_2 zqISARM?3#&YTq_71})Qf=>8 zjhP!kLwDPd2Ic9ACz`NELJPPkH|(tQ7{7X4=Bn)0=Hq9gGY~ueny1e6C9)+_2L|Q= z+G{?TKYIcz;UV%#hsr5AvqUy4MIMFbr{EuYq;{3I+e0ud77Rk2@c(jQ1N8fdxFh zhwlf49}LL)>qZa|3uVMMkj@}?;3DzmEe_mI9U5|41L2t9f6_{RZ_nXT$_85F$3lG# zgrmqMS})%2XAxQzBMHRLjJXSEGO&eS%Fsq<<+UK883- zBiK%Q-%6 zwRJu!oPWAGyt=*3F!J?HEV23b4~1B32W;|qqVBp{0~+vfWbmnD=Wwm?sup_!x5P_k zOIl)r$3v76E$*KL;;wVI_GqQdz&r#gE^DyT3#D{Z52Fxixxdk3z3a)Ry{<{_+-P~` zB2mLx$RpsI#Gu{13MO7ej?bZ?%Q-VcS$gnX?I%%|O7rH7y&;e8_WOh;!0uzB7DN*G z2rXQZ_{p>On>t!_Dy`|b5oq7NcF%c6X;vp#{sj#$ zE)PV*g|{Cg>Ld3^ahb=TGV2V@_`;-hOU?)coS9~gtRS`fVSI3(8#cWCqKnwv8AY+p zR34bM&4@YpPiTU#5|;s3qK81ugou`mJ?r!cy9XRK3bLM%HDItoMY zlUwWWlseS`IF7b9x}cPI7;uv@BOB6{6cjV`mTBRY-z?Xr~zY>7E!2myxrJ(p9iMMZ6 zGaG|YWbnSb#=UH+_8fSn?)+Y=vsN_vvJSnUWpqg%PsPv7zRv)FB36x)!MaGpCo=Z~=c)G}v+n(=@gCKnH& z<5rX>aL$cbH3wbV-d?A@@cEg*O4Oonmb@i;m3ta{!0kcTr1(9}%#FwAlUd?WN0q=a zg{?|MXLei5bm)-doOQJ#a68ahZ|0Tm>dfxxz0&`6m-_v+V=dn0ziRPsXd8cCsxNqQ z0k;L+x~=OkIbu~+U6#zRbYFcE8wnhWwIrRH?h{@I0FAXQd=3)7kFtZLr<%ow1IL4`OI_PEBgg>ehoy1({Hq=Rz#Jafv zHw#^}pG&3-ir-U>dW7}i%Baa)HUg%q$C7^$$ZXbK8MF0)n}+WGpT!vzPo@*Iv0$Ai zZzEhdhSb`BS1l-t`qCxGG04Kv?j&?33r#XQzJ<7fR`dKGhRObEX>D0v;(^p(y`{|5 z!(PB1#5i>HB^Y!nn4~q745n5|ePL7G<}y(Xx*AV?FMf^?Z;87CHwxWw4U^KyhXXdg z#0W<@Z;dbF5gZ7sC2D4w<=yeYdHWu~4MTULbbTU!RAO65>HIwBbZNB(sWlzT1hMsB zx)o+(1}#i74?;JT&VXq=`c}TW8;8nlX(l>pezR7D+A`Qmbohp$V37p4e(30`YPRTW zEP}dui+*r4T|SNrdTM5;yO{5&O^gt*`g9+-Ug$V4>8i_U3(E0DPUK1UZ;*d%Wj)0H zqQdTK$x&f`wFXD`zoA2r;#%EAGWpK68#bz`P5GFf1y>?vEbQtuTD*0whzItVx}YoU z^~WVd5->j&*EL~!T!H#XL&oQFQQ_vnSVoWG+(QoFI-t`v=dG`PvS{3SN6};M*BLyV zSm8l{NS5c4GqSh)6_XpdU%d1fm0l{;A!e? z^hv4i@8E|Y$}d*l1ml>pT4oGp3vDRBPB9Y4xJTdxKCw{)UgmGEo~h#^(~<*dLu ze*QFFude|4n=2`itc1C^c05o&z-wAnnFqaDA;B`@v=djx+Ev(>V0B~c?^B0cjDkKL z7V=tf%}NZ=Jwz4{jAMB5iS@TDiK$5cN{G4mmxJxjM*)|&eD7Ei>vMoBhj+q5YWAoa z^;z~kty2G)1Wf1t-GGTRl#Tg<$>$M!_2r|$l|mOr72ta`fg;H)T~eEVb7${4)nunH zxAIO_AxSav^feoB#n5$LKNKv$_#pGEltz5Vp9#HE=H&D)FH8U2Qdj1A_hd)}Cd*2fNq1R7XL=5)K zi_fgs6y(`_LSZMO-L6{1M*yPb!(W(F`(JFgkccHwq(XnP4YpHA`?LGqXm1U;qwsO{ z`3J$?s9ezdBG`-)S!&D1ty&Z^6jmd2APsF$n3oniK^Rg@Ub6am1fpewXztI34{9Sq z?LyfL(_OEkJW6Rid|J@6(H^noNpj$u@@K(T_Z2Kr_@Lv=#{PR`e2180nrOmk@#$t# z;SSpQ+ZMC0eL3m70w7)nXm!q%4T5dIUz|O>Wz~Fos~S^#I#d{wsdX`Aq#k-yP`JHx z^Is9yG>6mSVaEWv?M#rn@j=+bb0XqlU(*e25G@7Pbx%xb_}B_Jxa?V1 zc)?E0#Pp?zIfX``OYl;YVtG_E*bSTn>dLTy`JUYRe&Ej_!Q#iBHRMV*2Ymx(TuHau z6f*dhWvBO$tQH8wU933@two&(3Gf{aqy29SL>#sst_f@_c;@EJ2q-rzT}ZDn7zHZO=A^aWWWW%rcS-y z_?{+NTn?dH-q_9ji~qzsg4w}n>9|asR~Q83rEnS~0J>=A0kEB`r`gMpa;@74O(x@+ z#XLz|9}{}`WCmwF7c7Fbl}nw1b-vqyKq` zE-Kc02Hj23;KGDdGIC0R(zk7%%)1O+)&m3NVtgKyBDWG>k`CAp`?MhVb7`a7w~QAM zC-h(Q?Mu&3+5+bWt3fka81fNqQZ-+QthQuX3s)_zu8HnT?g?_hYfS3!A2`6dKu6Vu zGL|?Mgd{!A8GoN{X6ZXZD__IvOoI-c5#zi>4$SR1K{rd|vqBZZsnChDu-y_CLz$N& z%G-t*+@kV6>6YT#VlZ%y(8Y!fgrRK7dH=jqi;@yt4poc4zChA=o>g+?>0d@TuM^A_2w z=QZby{P&&S|D}^&`({d`0Y~*V&_(;&4HTM3H;x9gD?U3{x|MpC+A>HijhcNqNMy+u z9RQpabYk6ym7|{oF+| zPop1^+dlMQfAM8xeD1%zs^GWUd$ZOODW7__7Iv~cf3j!qw3MaI&BeWC2hmL7Un49r zSnri-Yv2j*H@^imj9ANfgsC?51U#kp7!?Z@Sa_eX|Jz_phZoFr{3g+p791bv+jW9< zUz~M%>bJv}DaOwGPl_#z;3E%iFrE(QSE{j(mSV-?mONJ`ocTA26wmL+jFm>R5g*U{ z1*WJBVWYYnFYHOxK$7r!X8E>#;x}T-*gr}Xyw=$B8kA$37BU^+^x=>4{}{W=s4luN zQ1o<3ceiv%cPi42bhmVOcMC|DgfxPLbR!{3iKHN1(jgsZ&wK8@>#nozI_G}i+iyMd z%>Hlo%zpNs89L2xg^#H?y$diK)Ml7GvB*7E7CcSi|czBkaOaF?$R8!yKwFam4Z76Vhked`|D~=AU(!>Zg&Lh~}-_LtBFZ1kW zylBGKn8e(g90_nbkgM_E-xc!WaFp9?e_Q0r#y7v1_xv8$J^SgmLs-raWoX9q26CUf zRnV>4X&V2zBiEh(x_G=cNM(_-i@f{6s5@3LE4um8@5 zhx@7VWf+p}dERoPFd?*$1=L9@VUs{9o3IrBMEx6|+y|m`wgF?xy&(8G!ZT2J_RXppv)+vC#)rlG_w%9y4%w z2{2Cn%;PRq$^O_G$)-v*g{Htj_CB-i7t5UOv_ViT!FV1PU}8`!QXZUkiJQFYmm0OA zxc`Dpe=~*g{H5}tM}Bz1pI6O%VYP_O|ECJ7nP_vEa|XBA1U#(M$kjh4 zwy-@dc1_@fAm?BC6f*WPW;}nUKWXu`TCEDhNNs*S_r1@o=ikHR5$NJ306AS@(rz`q zrJoN8D1CSCJz>T*__o8cjR{+f7Fq+g6`jEGL9W@%w6DQExqtRSAx*&2q#e)YDCjF) zZuBaL&*_6JODk|ZkZWZm82I^)=>2q@FfQ?QXQe>dNk#lB`qga}g9^NML>F*ekRu6Y z?pOVHw@1z7Q_%jM#rW3&AJO=Ob|&Zi+Bp#e7jy^72{}ef8^qnpA2*Y+i02Liy_vZR z`6$^74#-%DO@!p0ZdSmtLyl_(Zyf>7x%~1J_pyJt`y^~%nJXtJ@$U2BzeO*BQflB> zAt#@^cJ1(-Z9wpiJGpq}GnMzzdP*;Nijvm1MI&?^UrGSS47r1fd7n=iq?AwB3vByn z`iJT>)AHAkEJQse9}Om&XT^YHgq$8+VFD&T@xAi!jpp<$jDjGGF8evPoOEi=>3UT5 zHVtskA-6%ARiYrvOqH#-ka9-(Qe)a7EZPKHI=QS2jnN_|{R41xzy)Af+@QdYv;Ck8 z(}+RVG|N8PaAS<9e9+w<3g8;o`~CzCmC!@R@>6?sCq=qdU(Irme1FjIoCz-Z;O=;< z8|D8VE5ZKm1>#XbbCQh$3@-0aOv|d`OQH1t#<@G>q*r_?qcQ55u=nh1xx9g+fbuJh z#T`t2)cp-F70!VCalktSWj<2CopzM!m%6|G-UR`0WRRnV7f!S7#Vva-fIGh+Rx18% zIa=46u3!G`=g7d;)usyINFaBv5w!NE*Hq#f-))}`{e8dL%EWlKoeN$?U`Y8h)wjkTW?`k|>a?K7V~{{>wW~YW@^XAQLB32$|5j_) z>{qUR?68tV4u=7J! zWh)(UIFQS-p-Ytsrk%Z)KJ1f!U;O>jWBy7aQhT~sJMdF%p1}*?upoEaz&arqi!|3E zc*z$yw0#Qyj)$Q6qXLW{*GcCnV;)rVz<`{3qouS2WsZ&p=D{M8m8gxFF|JBhEQ+Ac zg=}*G%Q&=?=NaS_BUJtt`{CoY*q1DbaiN|MjIKN$8Geev7FL22uL#}*4i$2tj(g^R zw+^g$dEZex{LM`hl{B7rA6xqH4Ieu>h@BECc@fjrtp+=<+I7GW$&{{M{MlM(9auQVpyy?6sPuyiPvhizUSb4j#A| zL_ykpWa8K3b8iivv$bO+kPI9L4r~hW9+6A8J*=@{+$R@=9Jjq;@XWCv7_^Ta!6gl9y9@W2b>ReYoa4; zoU0Ve$C}|HjX^>6zY7;l%~G|t`CnJblV+qIU~a%vL0Ihxr;`5{gEzvaE-87zrf-#Z zlpSBw0xYXA0hK_pK8SXO42E5lHoL{(IyLyq-f0@wA@ubjs~7?Ka0_A?tgIC{u250n z{y|3#6kv|rP+oaLx`X5Q_xJ6w-05jYR&rc-+84&Fh9Mxx$%4p+#Q^dZxuk}S=?B?Ws9Byv%AA<|H6VeC1TUrFuY51kTFZK_>1??;0bi0~(d4EoR3&5bY2;hpLr| zArFKE$6b5nUow}1uCVCo7Bkh@%{Hc{2hkP|wZQE|Eu5dYxQ-|M@%`#+nvR)oPPfP_ zxM(wvlAb{Xj`ZcIh`qq=LFd|)`6H=oHIngaj)UY6FHX46utT@@Ar&J-ZOJTlfCRWj z+yTp-DkJiAaGMB-HJ0oV%!Jt-*k`X#Q2*+y6MC0_vb73O)zvIo%XZW}quJ7U6fIsmr;jv8=~MU8JY?&8l#BIUN9Sn$Y5d$Hi5gZ2qG z&JX#QmQ^V<@U4Lzth{JFKjJ=Q|0dE*$WPlO)DUOYR*U9%Bwb)$l%bb}wFB{1pnliP z(9&;lha4;^?I0`K^XfgU{MFIQ%E-B{)DJhyClNH@mZ4Um=|G=HeC6)38;!-fvRmBa z!gp{(_qcq|tv@6E;I+RC+;7OGi&7@)w5mFq-|ZV^2vt4)J18IcRH1e@5m=W%OFEGR z+ydm>O}oKUpk@eC&-tSHrUFTlO3rzcXhfpPzY_}zu3gOlHwU@VD%Ehw7j~`lgLr%h)?2ho z@lD$(n`LyRRhM6>7g8t&05=S!_aT8Vda9LBgzs0wbw!%H_1h%jn1bfdb+&0MI`z$_ z&=SiazoQjvPEh&DgA~d4hcy*0@4EM88Z&Vs@-&0pG#79Kzy)+sIl$YoS6yn! zW{yzhrEK4fh=iSIJ^kdw9>hJqvde!^c-;pRYo`Elu2L~DWjz1EZ63MeqE-J5Qe1nDb(PhuW{ji&M@%fmD zfNKHH$5h8WVD*qI6`?yp$EolW3n7|g-QEwSi#p21jh9b_U_<^FP$4tBCU5%wYHa^i znU$LT`>fE!c@_LCBX){Hjnj25zJm)8tr7aw7Q-i7@pFyS)LYV`PV)_C^^x9-fGuFQ zt2(|-Iu2aW-DW+M9p1I$$B&F9_HA=p_s0{}jB2D=3^VIO6kR`DOmArwp_P?7C_B!C z_@a~2FBI30zWLpoB=<{}oP%#fRMSS2Q<2mC;-xBKK7k?VPPtdjle;%aGozuZI8?{S zG1fm?B-Ry<(2{pAR(CrBM5_kbdGrT-be_gUx%GO`Kiti!D6iz98=Bnin&WCnz~Vf| z^+N;IK&|9}Ak?SUmwaU1$G=;fed~0SsJLR5X=VO~hpHmfIE>GOXywqkp2gQYQ-m>c zSo|8#y~!9nduB6bEb5ixVyCh)#)cHc2V5z1uEl-C>qtwwH0`#xhxUVF+?Op`ySBQI zfmQ`<1m1%BiNKWr7jlERBK6z*$Y;4Or`i9FByUIT?w>ZCgqSqSi<&dUwfsvg->p3^iyk%gKFL8_yK=v~tzF);WN^(F=^Ew6LzB-BP|x#mU80atN7xO0HN%xF znY6nmJ58pgD0Pln)SrW}{sXET=R^5<|MS{9w4g-Gm={sSe{q+OcG?}zjU8k8L_aA+ z^EVD!mCA*F3!`W1$>~1B^QCN#6lI}Ciq_rgE#wM1dc6|o%;Mx4V2l5MPZs|hknR{f zdljm{=9kU$B0)MFO<9&9hiJ z$nIX!>V8QB&=%q6Bh2nPTY5iU{D5oV?=3s2}BpZj|0b zj+%5#P2(@i!dKRBei%~))CokW_x}?AZ8}Qz3R#C3K!ubP=rkIOJ|z#dk{;%dDPcW1 zt~g?Lkt*_+3Cg^>Lz#(O?*(rse+QnBZ@EPrUV}@YnNwJ>5r1X1_*2b^7jZ!8jrV+B zf$2a~IEa=Aoy7|_p4B-u{8`=iYCMX4BH7D4@tdS4e!ej~bRHVd^|gSDhq4Q73CD{y za_DPZxIx;3l_%P|%~S9+OYEdZVMaQ9LzD?zER@~fEls%~X(<-2&-4QwN}DJVS~s+{ zGq@f?S(ouxL9w8S8;x4w1Cz{zQNBF$tDy}(1g42Y)T6$l>)_ten$2;3!MIpKiWa-A@bgzn zoY~r;PlL&Yi?k0&MCU_NThYJ3;h_SeT3`dNvCLLmXaY=%&<`2Ho-UOjA(rc;bO|56 z!iUW}zyhI`4(~YH7DeArOqVk>t5@}3Pd73pF{LpP72Vr0t%Hk(uH*htOH1bF!sGU% z#4VdGMjgd7*X5?QK0N>1iH|CTMMsV8Y6P4w z$`Uh?k>FUkC%>}}=;la#BIK0kPt;iWeyx5+0h~MJULCrI-^7PFWy=@;6NVdrL15l_ zVQJd#9k7_A+fB0wZ833$T!eXx!7mMzJkQ&w#Wcit*9AR^@Ny~tc$*}E_%&Yga9*I9ehe*2|w@n_N;7Ajx#&z8TQ=fF8aZp}XeEnKVNla7pN{sq`2 zwQ5tC9u*@cMkYB;Y0+cf37kFTqEte0yWC3oZMl(37pu+Bc8P7xr%qPO@$pCs_&B1V z|F^f0lPs4OIU_r@e0PM_x4=ti|BBWqb4cNzRRTV*Wq+P8C2%&7b2RH+cdJ7!6`d`w z($~ShBVqJ!s2kbAGOSk7j~B*<>fu(9+dnPBy1EUF=?xtCzCcymBU0h{X{p+VLSSd5 z&>w|s6*vpv0(2T|Vt##5_Fe#`?gxH#n!lGkKR#i*d(M<8rD8^_g?|lh|IbE_>edFXIaO#j7YLY6_O{=6DA6g_h&TO`;qT{7jj9&TN z?@gc>DJ1g9>fO`&&fXa~j>v_b) zQ_^j*s9w=tOEJ|hh*XD9$+Ju8;W?(=Nc9TZ6ru<@lqvGmQpLXGB}=b0w)hSULQZW)O@9Yxw|O38~vc4MMFQ&v;7h=#~ZXYH8mz0fRhEz zhndqCS)}V|X#TeK^9^d<073?C_Zj1hvz5>e1tsC6zPQvXqlX0i67j7H|J>2jX#(C{qzV{^^NKAx^35KjX1z7thn zI1=#np&>6bZOe+)h%>s+acGX^3QoDVzcDvxQ$BnJQ0#w>r=LV=5oxE1eblEkZqElJ z(gQytHp>ahQL)=Vje-;-`&6oKrKz&HAY;n znwHtzm>m^2p{W8lSQr@_A9HYis<8e2&nY=@e2|+&$64%DKzQuFC_1Q;(<2RpBegeL zJUr_y|8>>(HSrm6JkT#PPbSs* zC|T!j`F_8Y!ZWpba(Rkev7Zg4|4s0yHml?%slD|3LJAg!6BT?xLh?2GvT&-DVrqb2 zrihb3b|gF;#gfeqC)>xE%v&R~8yI$Qjrk&su!D-^%kzPUb)3Uk>?NkbyBUpL{|P_z zia1lU)k=^VD>B%1Huu&qAew1nxRp3w@Bv38E2B&2xoVl*97VWE-~78X=(dy@I@9Zu zQSJIC3$ErL7$G|Ge?tc4eXJ2-FVS7iUd;3x%D4l^2)WOu%Z56iJIYBtBMA)mWt`vE zNOQ}3?zz_D_vlC@l0dhJ&!HAcy+DnqgG2v)=+NPNIR@wCS8IA(Ik!W$)nxMV{fnx0ft(ThzXdgiJCn4;N7Mes>D*s5biPA zDlTv>x9(aD9J_xWnyC#0l zCF4{Nn>{T`gVYzmQ9x(G$E4sKQNAk6ElMLvyzUZmFf^R>w2h>qCeuoMZsh=#@W>#? z+~K>N@o_gWS79ezR@Z2S&oCJNr`Ri=0urqvl6*_3^hyG`<`3RkKZoz_Ux)CE$&de% ze&VuCAG7LpDZ3g*-|G7Sbz~yQh^iPNHgme{@Yi#Gs&<0G3uBlx4_{+?h~iLi}$-?1&J$B z-7=ZiI9;Zk5^lnb)h6!!+f5Z-qrl-nZlm|(^0wPwBB$WW?@h$H6>o`C8=PGJt%)=r zwYlRossV=uoDcW8qsb*@l7(u`Iywm5K0r2n~2KdfRHy64V zDudzp@vt_mIC`!FdzdT*1LffG7U=x@3#A`SM+d*_m|AabGbEBG?S_g;|q1TghCU zgcW7_d-%YOHuHWvOZ}@akxMC`-+z$D^h5>w30XpjtAtGgVl`L1(1UlXR~@34PiD%6 z@p)8#$FyDSHqE^IpIT`%u>ztt`J4YJg8m63_?YCKmxyni(~NH`Z-$K z9;3cf6|H*H*EXiV@dN(2lU6xb11v-;yIccn6G`|?oIhv{-7Coh7JnuUxfcX7qYTX zBZ6@R?i6xn(K9KGBYyBs&;Ca zmhL17G=M@I|p5u=$vuLSYq23=%iZsAHxz-umDp_$z@^ozk> z!-`t)Pvnguzq4a2dr=>f^Kgd0*`_hxz~M>M^9X*iDNsIX_OrAwrf0N%hdr)uVBkSP zMQTj#L;K=cE5;S+7SUHS5N!hb#S)T>5K!dQ1UJJ~_KmU0oZ9G>)CHNYG-+@1n5?;t zI)EF4vZKQ>91@++`TlY8uV;C18~&2#a9TVg>yH6nY9ZU7PPo8*huq~oljG%Kn=&qV zuU+&+YKGo+=Q)FB zNNK9Z9#kP6hMXxPZx=2}?aK+3jzISDcP`JI1=m~4&`Y{kd3s6Ue|P{l2%L}V-8+)s z_}i_c!DnXq$HL=YX)hcUP)7}vtrKQ>sl_p6(O?Fc84eIv;LBBSRsx8s9r{#yiz=mI6Wc0oT1;$k_@U%oQa+I3o&q5e-Aic}jl)_Ly=`EvZ;+g4wH1Fi#VoMiR4 zLm^B4S6GOpx1`@FQ{&>R6a>4&eaJWA z$wpu0(z*;EAocwnW&+~1K<=H|FMCm1u}s10*H`x1I!r^t7cwu>_Y&>(YP(v3DWD6{ z7s%CD4D`Rf$yIzoh-~oO~$)CfLe#y@uCs9M##Y?A8T^Lt>>kS8kngI-F{j$e>Z>4?pi6K&t-qA|1n=UJ*iXK zeTf*jI>>#LHqdtBB4n=;Dx3fIw+|r;)5Ban#9w1nh>`~R{Vr5+`2;zQPYdWhm!mh; z)a;U(d4qp;uw=Z&mC5{(I)_Wz>c*kLv>I}}l_Y{S_fhq#&YzC^V(=VG3$BbkK4Q%= zsAR#A%r^Q1R|z>Y!h+nJy4Z0yp*@2Of9e!VDZH0DbfP^)eH>4n&BxF(M>%jleMMq0 zY4omHIQs?@FZA5W?2`?7yyAq0X?-#qd5zR%Zg~hK;(JR(Xxt0j zQ>=_qU{O1rwIktZn80#V33&0sccc^spL6z+tP}fJF>2zMr>2Nq|=1|S2*0$ zTeW>8N`fJ=w6yApB zcVN7S+z4YN{e7c0&nI!L;;jvxGM>7ruP;4YV+F}ZQ}}gVpcz;S^yqwYZXbA4Hu+^y2}_+3tt{4T?yPf$a$io4NvGq4TriQ#k^fme^}|^oDLK2TgS$Z zjOgphfNok6AxGj-Te&7t7Hf2CBXTqM9x+a8CaXO=sed@SK!qeg@(yk;Cv$W4+UP_eJLOF&ZwfERDDEsEGbl} z-mNmovWrs;NdbE&qrsa&e67h_2Vol+X#%U&_SQHe3oE#EPh%<+YNdWZCI}oIf@qOY zD_@f>O?4=kj_>Tan=MJgQTM=Nw&_({CqCw>of5>I8ew35AG1R1p(atoRV+vq- zYYKzmIHr{{n4i&e+Cc!EFXZIag<4FSCdlC=`B_qG1XKOrY#5@LUD63f?p3P$u7m>T z4Y}_f?*#I{f8*lff6hX8I<|!>dhr-gcEmvCb$ZpLsCEgQC*;CBbXW14!{O7sIpOSa zmO@Xn`rY^M)3)d_d~C>@cP6tm4W7M+`drXGmlEvTc4qeTc}@Kx%E{g` zU=`jhMUN;*ecQyw-S~bw2)^ghPK1dEEGRpIYm1{~zr0$Yhn$pMvQ(T2?EY1`rt|vH z=_XCz^OJ$G|4MxJNMLujc#ghNjpTde6^56-2BGj&_||TmoVPSbO|A+kN;h!Ojp1A9 z92keBEABaO6OPwY6uZSx{3-7WY<`EUTV0{1kcls?O9E#Dox?#zi1fggxAGLr+`DZ( zTat19@}tTFwGoFzv%JiTcF;qu!0pKCzh{a=Ia4?fM8>p@(-@)dbIkt~WffmPEcv)6 zA^%sXv;aLcz^<{dzhMu7YdvZ&{PEK|nW0cJ?4wDYD4lBDacgLh0o3!%Kq+Rhk~VBS zk5^~vjf+Br%vx(qu{e*w;EE3^llO-=Hn?&iI}@nqwdx^E&g5;06$ch|>Mf_R%p>yb z>mgM2q#4mv`5pbh0L}zdkY%^C^>4s&O9&i#^VV-=}?hbZtYl2s79T(**n9PW= z6Mc;7p+U1YLXD~$RH@Vf(j1Gv>O5mjb5>Wq0BvWzY1{P|kRQAMGq8AwRG;fP|A!Y}_t7Ju ztb%C&htDgIg5HM^1-g(=lce=$c42OBnQq_JuklSHS813N+QGwe zU@^zhlC6$?@7u*4&&ALqMbk^VvMdn6*J*srss(>*+?g;UXMu)6m;&cJI6#jUnzX?k z=J;FC>g$MQhFe;vcMH++@KGnFf8D1iG$iUFSXj;ESL-t<)BQbz<59X7ya7tOGVgSp z1h)131?AWlVbP*+K)kQrh?)U}F07;S>kGGbxqI2QIsBc`o#;L`A>TMYSpD3t-W?q+ zQio{=CyZm{S65sWN`^b9T}49~cI#qkW4HHPD`O#{vbp}^oJ0x+rXFPHn9=;+dn%V9M!HGG_zfF1LEjk`Vy7^q1}fw@{EqGkk7I? zUNxG}e~MfP{wQKZcqjp^OZ$%I$@D$7jpNSr7v9 zz)>G5)+ALnuFNMFP@Lw+6U?4WVVH&O45kjGbm4S)X&Jy#@6v#C*)0sAz0&@Iz*JLd z6PZ#{Ez2FSb>iow-#i>5V3Y3+oL?evqaNHw2#y(Q-HKY)VS-J;Tf-#$^IK62VS(2_ zH#Re%MT_f5klv@0Oavy3F5^reNmg8VfwVeGrK=t zWxi(o2=GxKxh1;vGR;a6cF6&Yk+ENAd~ZD})0xIlz&EbKAIzhy_2uq}T<10()-t>A zABqhDtl3SnB>1o@dozs7>(Jes_nd-S+|P#JQ#+4QrqC~%KQR9ybpS(c9<7-g18}} zjE}QU6y2BJyl4+i+&3O!1G8ZEBXvH61Y~^F+Z2Rn$F#S5e->Cq<>dS(O8xuIOT&Q$ z0L`ypU|9p?m(G6VjX0i&PMvUM({j8br8YXubNiC8J0gV>P|M!?|M3-LB@7rCBrvMO zvLCun6j2NQzo*8gyD+e@$v&P{84b0ZNaBV;^i+wjNKuRqyG(4Q2l6&6G-LG;kipSc zR$-a5V5lx?8ZDZi=Ql}uHwch&SU&gnu%n%nAl@jZ^7luRhPDnEFMu?Y-=AE6dz!qa zE|XELCmmbRFZVf0W{9_0)oTXtczD=92XJ``is)!>Vd%R+JKo*RV@+G!hEeFWpN56i z(nb%T%|uDK1C`7TN1=${m}Xa-B3m%I z{DgZXYvw6z4<7x5k(l_?Abis7T}^k8Wb~9bd*^H*4d6l}6j3vt*-?n|ud8#2iR`k? z7mK}*sdTV2<%S$+kAiVN=+KQ~Rs|H1(vSyMt@x@`2aQ)yr}IjgJ3R1@s8;6HYjsYN z6Ctq~0E-Hsh>T2uCbWDq7&n{Mk`KD%QK8lG1#c-?n786#TrkRKzW|t#4Mp6+A&@@6j3Y(N0;7)Qc6|PW9~Sc%#^kNbhIE z%|X6Tz>Dr_Xy&9d`((mDji-oXq&&GYnhS;`2YGLoYT!Nq>dsp zZnIbD!-Z(vyh|~wrUC~q(-DA)GaUfjr~+_vEoQcd7GYQhRZpN11c~+h2Q2kNpK&8J6V*PKLf#Mu_X%7m@qMDdaz% zsRXg5O4A&5amM4^D#}I@Prwba0hcdiNxEin{wK-&I798VAlpDSYV$ID=RZ5MFV{^5 z`p^Vi<~eXuf;@@%Bhp?=4#RZsMJQ-9Xbe5SzXK&)a+7w1L|mwzJwO56&r_tJjF~{$ zf{N@{5g(-_akmW+K@T@Q!eeNf`Dp;Hz)KSXm(YmZUSWBuEutMgmqDG~^CY?m+ur%i zwfUuOsCE#cK5%`QpjjN#Z>gDi3Qq6V$I0e?O&0CHcp=8V-=1LlO)gQQv;ejO0TX<- zJvl)KowLsJfPvtgzQK$(r@2I}UbM4Mq`^4>t_-oAA031PORp?Gi;qqt@mC{Pco!k| zPTjN9<)6e{;$>GR+pe~FJm7l3pzQ#M$nx1j>Orh7twnB_?NHx<0qz~W$G;PdFd2l+ zTY+*Nn>B9)OlmnRGfOKs*l~O~SnlMqH@P?x^IPx&n}N@lr%?%1#+(mz9YSyU>_3SzwX6U4|fS4orh$hKzoE=@<(JOC` z)0QGbMfy6&smP7m-1b~U2dtZvUgqZkH-rzG=v9fy6a6n84kk2wRWezRvQJ%a<2OZ1 z;>YE2WMMlWhk*MExzO}BPs%iRj@iJ!lqZ`+ax#?fZ1%>b!ehBd6rYDgXaLs_Ir8XT zd$tRE>lIGnb-dq%Yp_ClE2QTdFcEYg&I4d1MuF>vTyw4+;=XjvQ2kfeyNT^YQHQi?VtT)&oI8kbEO&}kpR~T zxregV%lv(6hA9c^;sMZzpHW`aSN8s9l^I>~h+!w>guSm|G_DuZn zPTYYN`v@Z|St@n@kCbq{D=4G2g3`!f%dJt^=pq@~8?P{ebzj1CJ?D25boK3T3`_)N z-~CAg(VFqWlqhKOrg%Lj$d-Y;wiZ8AhEiYMIc_(#Eh~(J<+i3N8yC1HD7*F(Ls9vk zJrDoZD1(DvV$sh<&G!l($E>I?y^L+)DT@KF0do2z;;aS)V+eini-@ex)?p{-vAkok zSY@`Z1YVJab20$;8FB=f%Mp^S4W%z&`|`>kK{lJRVRbobN{$th1J7f4F^-j%$3YP*B!FIyOqDgI+GSqhG;--t*L2XZGLv$+Ht9K zSGNM`3m*Yoau$a9t6<7PWUY0Im>nDn^dS z22%TlFMJEc(6czPrahSFHJLBne4Qnx`f)CjfGdDp6=m?R5Xt>J_bL=G{~e0O1|0i) zaZ%jeA)JpNZkytHfy)EV=gZ6WeR%;gnq^uiu35@(!rl%~)SfURJEL!m?=ByHngzn- zfb}rX_o|wOqCw1WQt`IdQ`!P3s_^Vm9XE0V9dl)EJ*$R6v@EDseP_toar50Z?oZh; z%dS+t;Z3yR2!){?`4@@%v1~Y-61WT~JMtz;S>7{_DHtq461Gj_)_xr1+WWYw)Ixsk z?}(Obhrp#l?i=%SF>PJnReY=UXQ-*{!B1)I8UuTqn`;gi*UwZ=_JK=<9KDzuX&Tqi zjHZ}vMY0nM9Ys`ejZqz}M{$#j$kV?+JisMG4)I@d>kp2@XG?D<#IaMxLqQ&x#22Y^e0Tz-gZC{55;H6B?y6ICC%sWQ*kH6KK*E6TrP&l{$?TJCXFOJzDx$)1Bn|EL3ZYxuz6~vtJkkFxIA#z& z_*|;CpSbIX+49IgY`Rv14mm7UL%7pOEz?Bs?+NB}mHniuVFJJ&0QyFl6}!2%bJ^LI ziHXLxKeJ7Uq*NHY9JrTo0@KLp(jb~2)T63=R|w2D5*qBn96R2alH^Ppnto0mJxg={ zEHA!JavcPm57Z*fFK+K~97&E5$&|~lI%Z3&so(U$Ywc@aoU;!&H^D>WiWlTAF;|4Z zo=JN}^@n*0!m+W<2E$F|Ta@Dq%lv`^w?r}EJRp~SEv#V0;kF`M98<^Od+f2d>g6p; z_js=&r@++rNFN8B8|0F6g7Y@{D$jF&H4_b`N!3gzVCI-l?*-x3)TrYxtWp5y0=dG& zH+sZ@HLa`;PWG9aWt4OYceTJdL5`>yQ6a0uav@>UrEhb@J1XlM(Dv zjWS~%;k3UcxXUZhS~#<%G+b$~MGFCE4dr)`yK*GGSR}9bmelRtg9Q;0Tg2ndSC7>* zWXv~QJ5rIrSwfEIN>Wxy@yItSFzm>UB*iP$+Bczb`@BaUjtir2uUs8CbKrcAkqh6f zXHJ^w_8T}nD!rk!`{6B^RwH^FxMK8kqh1e`Q%%86W}_3>YO`+?;>HwCYE_1*m6zHc ze}cH2KlvQT{j8D5N(Rx4q2AKmGwn6v;x_b`#>O&O*F(|o-`DYOvX9~P9Mq+L-6H}#S_YyfUAd; zxPM?$Ig56I@IMpP!jq+yxkZRK1@GX5Zh_I!tk!`gDTz^EAGJGuaHT2OX2oMOpJ z5}Ef1ayREOC)G*tL;VpGL7|J2UxS#~cZauu(|}wCBJxgBm#lY4?rv?5989-qW?Vo} zoNvl*;Q~r^mT4VuYLN5W?=>;x5*ib|szog>%%&yCyufrJ5-uuRCN$-%toaU{3gqA^ z7WVeNJYJQRd&}NKdlF47yy5H1vHqOBMZ{ma|AtiO>L?G(IXz zjCg;d^eZm$)5oYJ{#f6K7s);XI%wi@(#~RpS|+j+fJuVh@alfmMg5y8T&iPghu&hw z7uRC>y!Y3hrazwWEVgyH5C9X0vMaS^{3nTR6&6D3E*g71RcX(ufUdM@?C-^whVdu!3>& zfUW!Mf!J*a?kE+yuYUoYk4AAQFZ<*3BlqZ~rQ-O#(-wqHhsBLur*#$H<58s3@0X7InvBhup>NG&s3|`Fo>LQu#s*qBM3J{c<`v41+uL*J z=06^Jf{R&EIC`*A-0L>ije}kSu`t|Vpkx8lllm|COp+v~)+FEZB!!oK>;e-B0uG2j z$8Cz-{NlTj`U?UwK?5b@WOSmGSfl>KfzzyDG$tD#Y)|}$jlpF>4%*$B9}gj*^AM+>>?5)H=iKVRDF3LbP*IMG(f5yYFg`=7m;=t*oM6^epc362(epf-aR>Y92tW@tjkL{gC z>>E_AT+ib%U-+7yefB-Z28WcJtJGy2I6}yAH1XUB9`H2Zw=dRKm&x(LlAy~yU}I|8 z{Ql0MHy;o78&cy#ZU8A-{V~F!(Oj(?mcQ!Z2)uwnUcE2uC^F#Y&7S~f8sKmtNB#%5 z^3V*4`Rz-lJ_F9Imo&X1Brguj#yY-n4*%iQg)Sl3kn_zRAy2V>N#M{Gfdi-OrOeEo z?&ncTe#(OXnjO^<z#2LD6rejUoQUVSg zxPZ;rSi1OkHk{{IoVCI2Ni)6N+`~J(|A@4x+TjIIp1wjCYBc%kWG=*%hpmd4xR>oK zTSqT*rwN^Nl?q#%rT+RWd_4Q@`xV4Pf%>0O0#jik#=H9|RAvwH0kd;DN7ED(RfSwd zBU&dscxzVRkic<$Ok7_WM2RO0P4!n#gDIe4*%O)e=Mv|K?MN2lpLtX?$S??Cn_$>d zJx(Zz();yZftTha^1I?2n5ceq57sgX7GgRE2hTw?IB2kP8m3h|FZk8t8`w0IM9h=mK9?!Z8;!ggT8o$H*3em_}fQ}h-E^S3L><;D$vX`u+5{p7r_ z18|Rc!0i_0E(ax0a?eeje;s?R_F<;oT^9)_LD19QF9ZgADFe8B$kpt^WXSL%TL>%T z56X|w7JtW}z#{ChOe{T4*7#R@RtDTHSSTSO8|e$_$_rjX^@*5%Uy_Xl#nG}zd!pTT2!tJ%DH&6L+n=wwB=^+AFj!+xMB{A;Z- za7)1XC|>cY#stn^(Y^kBIj9<5cdKuUh)&m^=0W(XM=RU9=oic)m>s`Wkw4Y-k$CP= z;2d>)pYmzpa@mV-Hm$c}@386CxFZ2Xo5utHM6fb-gL)|KldZ-h+D9#69%^OVYvJcU zPLru4TIv{~I>60B*%3Is82C1OJfDM1qduJN$f~ZLn$l{66_I$b@bRt4T_te8AeWmP z^xn(59!;C&Gd`}|;)rmt0f}9JCqh_l{B&-#B_?n`A?K1i9V)iBR7esd@UFLd_!_BG z`r3TCMTK!SfJ}wm>jAh)$eAcA34Eb4Pvq<_Y{6lk;W~DgU2UNAD9|2140dImgXRF^ zkdxMbe(dVoo8YWVkQlv-~y({OMX+UiE`n#Rbajn z)2xz0Bw~%z4Ymxp!7vd;PO64_-zbUIW6GBf4bVUN5IC+6zO5RM zM-Np?h(oU*da0_gZoG(tiQ2umR$W|6^`&PK9L!fR^jQ_8=oni?#;ouAC|bQ0bnFO* zRhLDABUIqU=ye+pln2rJpx#jqE)xmz&Z(+DDwaQ$nj>o6jHobe}MPoCia9 zt3BY4S_%(;t6c&+D+s3pWK7+j0CZ#>yEh zzLyr~nn}PlLwCb~pO1hlal`sOlPxr#D)}kJ%=oi2c3v9wb4ShD+GgMyf%8zcY^4wv zDcB=f>$YBuyw~=dUhm4NBP8Xwzkb(x7E<60LOmGsf!`zN7-+{B1|6m@Uw3f+BJ>)K zXJP0-QGBjy-H@n?07|QcSMUF|F%MidY+WN4?fzI}%atj9e+mxv^9WMyB%LsfhL%$z zg#{&f)*9d{q5JJ=`=d9GSODwkcb1uCBnuarf&8}*TSNtdqrX2zyv72q95^3jOabzF zjubSFHY*DTO%#Qe8(JH?X^L&+-j9Z_ci4Z!u~!OazMvt`-_(dm$tpeCS{$~Eqkj~+ zPuMdm+aHbdZClkK!pu=I7<(R1Y#8m*77isID&MRk&@5%sTUIqu**yLE%Z0c0dil?5KwXcEvZclnc>#eSw^>lt$4MHwZF51dw*4N_#D2l2Tq7Rh(`VM4Ly4NUD z=58PLp^D$f~|0NH>(h=3m*JJ$OIwN z4IXY)M)-yF?VPfA{_AZ~n+u<%#(|ZNJgQlBYo~88y_i9SdgFoV8E{;Z8%L+=*UoXj zS*ff4T*s#UQZVVeysY&qOFLc_4njKUXKJB9mUT@|>h5GC5hv1={-E{ddYG+aTEo^@ zB64*Zh}u&@r9Rjn(KFq8+q?6`v;oyp}LxeqE$CIUya7$;c? zj)^?ga6ey!jJCdLZ=y`M-qoe$j?wdOc3oM4Ii5s#?@<#l8p(#)hIbynn4v-5;JI+i zZ$rwfAY5sYAVPN{LImyubiAIYWJ~^3W+uw(gi|Izqb-H2R_DR%C26dz_hKK&asd|) z9YdY~cT?5r#J}6PZ@Z6zcFDJi-J8(Gs55YcPMy&na|0I(-TTwJN1@xHvz20VPZ}8o zI15IS*yLVH>$8{if6Y6cYy&PDxc%)<+FU6M?vJC?5J%L~Yr?p2;$;$5EsAt|Knn}H*b^vS6m!P^j}=8%h&2{X2oC$ipT*U|zo*a-*M+qTajaFfZ`X$w^>f<}#)M>{$?|Db7Kf~3;WGA86Z zT%?7<-=qhQ-+n3o_vGylf=^al&uQIA{7(EMj4W}*-bZ?JqVm+i@7eSE^OLqPdL9i~<4ni5n#>hAALy<|465~ZY$1*|m% zqE3HiCEZiu?41G53p&F1Ck1$JSV9M9b*6L(>GdDon*>`NY7gbtcEb3`>imK8fG!eE z-!}3nEygn<+rpSO;-(;y&T+5F{d>fna;1nFCtPK?LAP!E1rPhu?>4J4B2YEfRe%xa z*05e<`=t5#wkwMYq9Aat(7m!Ov#gvFYUk*h_J{~yHZkJb`gPoHE?KB_iD*S3jR~AH zbPE;^CCM|olCNkz&wsUbjrbTJtGU4r#w4OmMrw&qo1o@|Kca7`;$F$xNI{K z0DpJ3!1;7B(zC{m$5u~qL?U|Ba&=B7dEZ>83r1kT_c;~s*3})P8 zxse|@wQDnX+e3G@cEoW`|oJjY-v|u=IBTWyJq@hy2qsO zT1&6Ji$C)dZPG~K%whYSNUyz@t*8gO22ghv{4zY12%c}0N{07pzmk;PSN#4HI8*4H z_ukq)?URaHx!J=zeLDI*#aYowL$jcmE?e&0w(E}k1wT6 zV8(3lq7FXam&z#m++G<3oDp=d)6v$tp4}2;Hicg?sC1p$Ak{GQ|D=)iu+a#|>q`y* z?lp7<7i3)812%zCjGqj02etGj(nMwEwX3=27LU=nBCp{3OCP$4?&Y0Onn2T?tkjhU zC!3AuMBb;XBhC4gHTOiaBG}}B(}j+_vVP${CX&p%3Kt2%A&sKzLxWVWZypo=OzlF4 zTc(b{X+tM^@T42@DH&Dil@{^DW$w#-g-wxjMOUowXz*pXg?3Niw4mGTFQB1m%I-nU z4Ra+Dmd@W&yZ?>7CenBJ&i00PpRRtcX=?2Z{qaY&AJ`#!Nr4o=sRHNGGKku_ zOUVCAaLk*jFZ~G}elVAh+}z8Yx`bj&vwNmsuSglZg}nVsO3P@c=SkLj-;G1cx5SM^ z0!G&roa=DckH<(YHKL$2MKBBbyegj)zIa2<(>VI(ulrMYT3<;=P<}TtBY{;N)O$=~Txe5K2@6g5Uo<-Kt)f;|XSV_&O+E zEU@lO@aB0k4{$Qj;b(CPdaCXolFQU@vnkR9irDT`zxdj^>1g`;6uE|E4mc_3gw{h) zf+7fBg*8fYj%7ZJF)=73M^}8N+sY-?Y$JAh1e^rCdggyAT_U?)aA2V0^x`Ov5fqp! zVR9Y|)fcPqK9E9sF3ExL6nvy6!PU+iNi;WJUAm;W@sc83`mFJZ!N6Pc-09HawqD^V zP?{K=!+&YrNO1=Q-ta~JrpDo}yPsd~ImwL9Q_u09;*SVV=`3&}uyt#1uyi;YMPEFp z*L2=?6Z#Ss9TDGesM(Dzhh$QiM5O|pFmyp3Dy05V4doA$ZZ(e6yHG89SsKKI`4TZs zk=DZ_AH(#GAav^l;G~dn6dW)(k38l;Z&uXg9(+?t+Q8j_%g$|=*S9dx%Qu*aW#VRfAF=U-g_I7@X zC^>>|>D|;{;Wxl>L$?|H*eTD=$Ct#(gS#%-GVlAd2-#Nw#|P^9>AZd>2QaJ337sMj zO9sglRqp_0;ezU2+wJf==NY3tuXDS;qBD{3Cd@{%1LtF$_Jy9YFFV+J;EhATd0j#7 zmoBDfv7%E8@v?N%ltwjh^s%y3#S7oOk48@}KvVAtj%%hw&7k|K*80fni}M8EwHU4j zLkK938IHaeEFs+LU(lH7f8kEWIK*ydY23YGqHEd`4M%1r?=oP$JX1vV7{X?e9Of0*BQ?%I%q$He29x* zZYmu$cS@JC>M}r}2f5}CJtf~K`ERGY=e3zw8s>ZtkA}L8`v0UQRl4viqqM=_1|1wN zOpL=HBVV6CHJXQ^QLt%Tjtw1GxLJb$XI_u>xOwS{-Sh7@TU2 zs!k&fDT%#dnH>B^Gvh7aUA|vJu^FZi#V28)XIrh?4UdhIP^4Y175IoZ`wBp7-h9Zu=1m&^t%V> z_XNov(0w=CdOQLg8tksC+&$5`Jj5!aH(OMj=nI!=JS;{HEBI>ZvQDHc)KV*4|78TX zbk_$+RT$L`y+wbtbCAgxBAxoF(!jOJtB12~^%L`FHRE;HCWrS=?|c(0 z^8|pqB?PT2XVnf>4gJl*r`(XldXIbkR?^Ux?0sbMo7CDWZr(9GR&10T;NtO`ea5kl zQI|2LAGE87FUgi#$gcE~5io5qIE|8UwBHBiUBU7iPoA?=hrhSkYp4j!x6k}4s=ZS_ z7WPXwL_gdA-q)u&>oW?N?Qp$MN=bleRfIEY&o3c_=rX3$Ic-WMB zThWaq#xfA0wzu7SUENmlwY1)77`Wfi4Jk42ZJqCJ^Z!C&udH5p=rHBug`rgCg)SE9 zgVA0JH+7DoV-}ox(I3S>U{Lf!>q=iG0_UY^nS$Tg^vT2Bx^{}JZQu@JZ`BaaUsP1F z4P!-K)lC1)TrEyg)b_A=V{1n9prOFp1CI#@VITadP9EzpMKOUJ7`wq6MQ^29Oiz(nSrz=GNIThDf%OvC1m|vF&?>dSk_!D{Xm%0A!I(b}R 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�>_$FVbz$f*nw|OX>9~@TuKNoVMro5+S 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®$=UfGYd=L=h<_scGKwJY}i z8w~{WCT(=TGjDrBZwbQPrpQ{gzsZ)3X;|H0>UMh2v8t;z!HGf~*z;Moy*zca%h$AO z#koL9R*~bd>{SWfTg=N;+8D_U`EUQ?d$4@IL91g-{{Ix}bcln7YplxCShpVT7)trq zztZobDfkUDMa=)|@qlbtdxmi2ByH!c(7N|$nQZagm0TEe8D1z?U`JUGaOlvXZ+`oZ z(D|Bj9`B`nm*v;p-5qqCgj=@&`)lsK00oy#;83CCMp24b&CZKwIBoM_7Yi^l_zK5TilGd8UY)|N}m_rYq2eS)@iX+?E9}dz_1r0 zSj39tb`T%x`O6b)fah<^^HS-$SHkZVaVq0Ic~mm7Jp~j%w0{Pm<(X_vBB?N)vJzZf zQ+_!+80(l2z^eD_ z%J$7L@_AK(yMeC6!TDkEof)oIz+J>nCFN|!v+|4xfxII62uqU{<{S9jxB|{?CWn^Z zyOefr%rE*x0-XT&X;#`}-CB=LEA<9AjdW2XV?ObN6w7YA_;5Bfk z&;=i#2J)12^)b$_cMQu@6#SYpGCjo@By?5Tk$ZO6jSJk77HE8*M0C}02nHwDyz^R| zgbFe1%ba;T?IQ=dr1lTe#yp}x<3l;n0==HYCC9of52Dwndx?dC_6Fr@rnWpDSXkua zcAG!ASsEEYz&#K!lEZ=d;2ze=Rt9PjHhmh`Vz;a}|M?NI?_YkMy6QkVm;>%YH=#cE zvs!jnnSQvofq4Ue=OTN(|5xFgP&b`-E)K*6YQSv+=k~NSa`V&!bK6@svny)1>>0DW zyA@ADsBX2nfL&i%71$8y7f4R1xGTtGzY}3aAK`zT{QPdJ8DEcBd1CDkW@3ReaX_&+ zh_;~xT0yo!edJ)0`)2=_A)%J9xT;OY(k9#0hcr~&D~sY|osqz;!P0dnES)3VWRboj z;wPRLPN^Kxq$ftX^=yofRbW*)j$Q+91(r_i=Buyom>!qRh2ieNX?LVKBk2;K)mTrw zQY;>Atqek61NMMQH^@T4&3aWEvNL zDSssKLFeqaBiro55I!VK1$y<>)(>OkK4VR^@?6uG|fChbk`tl zrfmBPz8j|ZC|FJMeR_*?bQotV^j&ldk-=~qeMEZv#N-J(RYp>3E$sJ(z^cF+a~1ur z+fNB(9PB2Ass^84;haoA`~ADk$%x*lQfv*5w+(24A!g-Uju~HVUEM0>ZOO|Qow9i? zXd}$bPYAK=);N1Pk==pogQausV!t=B)Snr+ogRkwqhpuR>nMcT2PsExIq{r?<)Lu} z_-xoS^0@#l<#F^Ik^l_yxd1YQTp#yfjtkq@nZdCKsf<)4a73#cUb8NKDkEe~z2^qn zIG&aCj(VR*=a=b-$REZFikC@S$j1QJ3C~@;OK4>no9-7C)pR?D2g60jls=@ldGGdf zhaQPqpxmVb*A7cZ?V_uAX&8Oke;46(8r5HIg!y*Or2yyGzn`^&Dum0pV3Xul@JM^7 zs?j9x>292l40c1$Ha9JT-_z4yIR~?Y=ma;OhcV0`onz4lCDL0hkLM2 zGTq&~en!r2-(WCHBb75j36u6lE$~dc@1rn-F717!*5zZrLL9Rp7C-jD_xZ7M0%l`d zLdY##YtaBp_ja+POgA&WCQRj_Wo8B+3bJ$GX#@ocMO#^o#D}+^aDA~5>cGj%dO